1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 * otherwise expressly agreed to in writing between Synopsys and you.
11 * The Software IS NOT an item of Licensed Software or Licensed Product under
12 * any End User Software License Agreement or Agreement for Licensed Product
13 * with Synopsys or any supplement thereto. You are permitted to use and
14 * redistribute this Software in source and binary forms, with or without
15 * modification, provided that redistributions of source code must retain this
16 * notice. You may not view, use, disclose, copy or distribute this file or
17 * any information contained herein except pursuant to this license grant from
18 * Synopsys. If you do not agree with this notice, including the disclaimer
19 * below, then you are not authorized to use the Software.
21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 * ========================================================================== */
36 * The Core Interface Layer provides basic services for accessing and
37 * managing the DWC_otg hardware. These services are used by both the
38 * Host Controller Driver and the Peripheral Controller Driver.
40 * The CIL manages the memory map for the core so that the HCD and PCD
41 * don't have to do this separately. It also handles basic tasks like
42 * reading/writing the registers and data FIFOs in the controller.
43 * Some of the data access functions provide encapsulation of several
44 * operations required to perform a task, such as writing multiple
45 * registers to start a transfer. Finally, the CIL performs basic
46 * services that are not specific to either the host or device modes
47 * of operation. These services include management of the OTG Host
48 * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
49 * Diagnostic API is also provided to allow testing of the controller
52 * The Core Interface Layer has the following requirements:
53 * - Provides basic controller operations.
54 * - Minimal use of OS services.
55 * - The OS services used will be abstracted by using inline functions
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
64 extern bool cil_force_host;
66 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
69 * This function is called to initialize the DWC_otg CSR data
70 * structures. The register addresses in the device and host
71 * structures are initialized from the base address supplied by the
72 * caller. The calling function must make the OS calls to get the
73 * base address of the DWC_otg controller registers. The core_params
74 * argument holds the parameters that specify how the core should be
77 * @param reg_base_addr Base address of DWC_otg core registers
80 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
82 dwc_otg_core_if_t *core_if = 0;
83 dwc_otg_dev_if_t *dev_if = 0;
84 dwc_otg_host_if_t *host_if = 0;
85 uint8_t *reg_base = (uint8_t *) reg_base_addr;
88 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
90 core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
92 if (core_if == NULL) {
94 "Allocation of dwc_otg_core_if_t failed\n");
97 core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
100 * Allocate the Device Mode structures.
102 dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
104 if (dev_if == NULL) {
105 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
110 dev_if->dev_global_regs =
111 (dwc_otg_device_global_regs_t *) (reg_base +
112 DWC_DEV_GLOBAL_REG_OFFSET);
114 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
115 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
116 (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
117 (i * DWC_EP_REG_OFFSET));
119 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
120 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
121 (i * DWC_EP_REG_OFFSET));
122 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
123 i, &dev_if->in_ep_regs[i]->diepctl);
124 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
125 i, &dev_if->out_ep_regs[i]->doepctl);
128 dev_if->speed = 0; // unknown
130 core_if->dev_if = dev_if;
133 * Allocate the Host Mode structures.
135 host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
137 if (host_if == NULL) {
139 "Allocation of dwc_otg_host_if_t failed\n");
145 host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
146 (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
149 (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
151 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
152 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
153 (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
154 (i * DWC_OTG_CHAN_REGS_OFFSET));
155 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
156 i, &host_if->hc_regs[i]->hcchar);
159 host_if->num_host_channels = MAX_EPS_CHANNELS;
160 core_if->host_if = host_if;
162 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
163 core_if->data_fifo[i] =
164 (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
165 (i * DWC_OTG_DATA_FIFO_SIZE));
166 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n",
167 i, (unsigned long)core_if->data_fifo[i]);
170 core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
172 /* Initiate lx_state to L3 disconnected state */
173 core_if->lx_state = DWC_OTG_L3;
175 * Store the contents of the hardware configuration registers here for
178 core_if->hwcfg1.d32 =
179 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
180 core_if->hwcfg2.d32 =
181 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
182 core_if->hwcfg3.d32 =
183 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
184 core_if->hwcfg4.d32 =
185 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
187 /* Force host mode to get HPTXFSIZ exact power on value */
189 gusbcfg_data_t gusbcfg = {.d32 = 0 };
190 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
191 gusbcfg.b.force_host_mode = 1;
192 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
194 core_if->hptxfsiz.d32 =
195 DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
196 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
198 gusbcfg.b.force_host_mode = 1;
200 gusbcfg.b.force_host_mode = 0;
201 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
205 DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
206 DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
207 DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
208 DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
211 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
213 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
215 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
216 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
218 DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
219 DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
220 DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
221 DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
222 core_if->hwcfg2.b.num_host_chan);
223 DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
224 core_if->hwcfg2.b.nonperio_tx_q_depth);
225 DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
226 core_if->hwcfg2.b.host_perio_tx_q_depth);
227 DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
228 core_if->hwcfg2.b.dev_token_q_depth);
230 DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
231 core_if->hwcfg3.b.dfifo_depth);
232 DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
233 core_if->hwcfg3.b.xfer_size_cntr_width);
236 * Set the SRP sucess bit for FS-I2c
238 core_if->srp_success = 0;
239 core_if->srp_timer_started = 0;
242 * Create new workqueue and init works
244 core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
245 if (core_if->wq_otg == 0) {
246 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
253 core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
255 DWC_PRINTF("Core Release: %x.%x%x%x\n",
256 (core_if->snpsid >> 12 & 0xF),
257 (core_if->snpsid >> 8 & 0xF),
258 (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
260 core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
261 w_wakeup_detected, core_if);
262 if (core_if->wkp_timer == 0) {
263 DWC_WARN("DWC_TIMER_ALLOC failed\n");
266 DWC_WORKQ_FREE(core_if->wq_otg);
271 if (dwc_otg_setup_params(core_if)) {
272 DWC_WARN("Error while setting core params\n");
275 core_if->hibernation_suspend = 0;
277 /** ADP initialization */
278 dwc_otg_adp_init(core_if);
284 * This function frees the structures allocated by dwc_otg_cil_init().
286 * @param core_if The core interface pointer returned from
287 * dwc_otg_cil_init().
290 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
292 dctl_data_t dctl = {.d32 = 0 };
293 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
295 /* Disable all interrupts */
296 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
297 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
299 dctl.b.sftdiscon = 1;
300 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
301 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0,
305 if (core_if->wq_otg) {
306 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
307 DWC_WORKQ_FREE(core_if->wq_otg);
309 if (core_if->dev_if) {
310 DWC_FREE(core_if->dev_if);
312 if (core_if->host_if) {
313 DWC_FREE(core_if->host_if);
316 /** Remove ADP Stuff */
317 dwc_otg_adp_remove(core_if);
318 if (core_if->core_params) {
319 DWC_FREE(core_if->core_params);
321 if (core_if->wkp_timer) {
322 DWC_TIMER_FREE(core_if->wkp_timer);
324 if (core_if->srp_timer) {
325 DWC_TIMER_FREE(core_if->srp_timer);
331 * This function enables the controller's Global Interrupt in the AHB Config
334 * @param core_if Programming view of DWC_otg controller.
336 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
338 gahbcfg_data_t ahbcfg = {.d32 = 0 };
339 ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
340 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
344 * This function disables the controller's Global Interrupt in the AHB Config
347 * @param core_if Programming view of DWC_otg controller.
349 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
351 gahbcfg_data_t ahbcfg = {.d32 = 0 };
352 ahbcfg.b.glblintrmsk = 1; /* Disable interrupts */
353 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
357 * This function initializes the commmon interrupts, used in both
358 * device and host modes.
360 * @param core_if Programming view of the DWC_otg controller
363 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
365 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
366 gintmsk_data_t intr_mask = {.d32 = 0 };
368 /* Clear any pending OTG Interrupts */
369 DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
371 /* Clear any pending interrupts */
372 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
375 * Enable the interrupts in the GINTMSK.
377 intr_mask.b.modemismatch = 1;
378 intr_mask.b.otgintr = 1;
380 if (!core_if->dma_enable) {
381 intr_mask.b.rxstsqlvl = 1;
384 intr_mask.b.conidstschng = 1;
385 intr_mask.b.wkupintr = 1;
386 intr_mask.b.disconnect = 0;
387 intr_mask.b.usbsuspend = 1;
388 intr_mask.b.sessreqintr = 1;
389 #ifdef CONFIG_USB_DWC_OTG_LPM
390 if (core_if->core_params->lpm_enable) {
391 intr_mask.b.lpmtranrcvd = 1;
394 DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
398 * The restore operation is modified to support Synopsys Emulated Powerdown and
399 * Hibernation. This function is for exiting from Device mode hibernation by
400 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
401 * @param core_if Programming view of DWC_otg controller.
402 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
403 * @param reset - indicates whether resume is initiated by Reset.
405 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
406 int rem_wakeup, int reset)
408 gpwrdn_data_t gpwrdn = {.d32 = 0 };
409 pcgcctl_data_t pcgcctl = {.d32 = 0 };
410 dctl_data_t dctl = {.d32 = 0 };
414 if (!core_if->hibernation_suspend) {
415 DWC_PRINTF("Already exited from Hibernation\n");
419 DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
420 /* Switch-on voltage to the core */
421 gpwrdn.b.pwrdnswtch = 1;
422 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
427 gpwrdn.b.pwrdnrstn = 1;
428 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
431 /* Assert Restore signal */
433 gpwrdn.b.restore = 1;
434 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
437 /* Disable power clamps */
439 gpwrdn.b.pwrdnclmp = 1;
440 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
446 /* Deassert Reset core */
448 gpwrdn.b.pwrdnrstn = 1;
449 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
452 /* Disable PMU interrupt */
454 gpwrdn.b.pmuintsel = 1;
455 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
457 /* Mask interrupts from gpwrdn */
459 gpwrdn.b.connect_det_msk = 1;
460 gpwrdn.b.srp_det_msk = 1;
461 gpwrdn.b.disconn_det_msk = 1;
462 gpwrdn.b.rst_det_msk = 1;
463 gpwrdn.b.lnstchng_msk = 1;
464 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
466 /* Indicates that we are going out from hibernation */
467 core_if->hibernation_suspend = 0;
470 * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
471 * indicates restore from remote_wakeup
473 restore_essential_regs(core_if, rem_wakeup, 0);
476 * Wait a little for seeing new value of variable hibernation_suspend if
477 * Restore done interrupt received before polling
481 if (core_if->hibernation_suspend == 0) {
483 * Wait For Restore_done Interrupt. This mechanism of polling the
484 * interrupt is introduced to avoid any possible race conditions
487 gintsts_data_t gintsts;
489 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
490 if (gintsts.b.restoredone) {
492 gintsts.b.restoredone = 1;
493 DWC_WRITE_REG32(&core_if->core_global_regs->
494 gintsts, gintsts.d32);
495 DWC_PRINTF("Restore Done Interrupt seen\n");
501 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
504 /* Clear all pending interupts */
505 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
507 /* De-assert Restore */
509 gpwrdn.b.restore = 1;
510 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
515 pcgcctl.b.rstpdwnmodule = 1;
516 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
519 /* Restore GUSBCFG and DCFG */
520 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
521 core_if->gr_backup->gusbcfg_local);
522 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
523 core_if->dr_backup->dcfg);
525 /* De-assert Wakeup Logic */
527 gpwrdn.b.pmuactv = 1;
528 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
532 /* Set Device programming done bit */
533 dctl.b.pwronprgdone = 1;
534 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
536 /* Start Remote Wakeup Signaling */
537 dctl.d32 = core_if->dr_backup->dctl;
538 dctl.b.rmtwkupsig = 1;
539 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
543 /* Clear all pending interupts */
544 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
546 /* Restore global registers */
547 dwc_otg_restore_global_regs(core_if);
548 /* Restore device global registers */
549 dwc_otg_restore_dev_regs(core_if, rem_wakeup);
554 dctl.b.rmtwkupsig = 1;
555 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
558 core_if->hibernation_suspend = 0;
559 /* The core will be in ON STATE */
560 core_if->lx_state = DWC_OTG_L0;
561 DWC_PRINTF("Hibernation recovery completes here\n");
567 * The restore operation is modified to support Synopsys Emulated Powerdown and
568 * Hibernation. This function is for exiting from Host mode hibernation by
569 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
570 * @param core_if Programming view of DWC_otg controller.
571 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
572 * @param reset - indicates whether resume is initiated by Reset.
574 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
575 int rem_wakeup, int reset)
577 gpwrdn_data_t gpwrdn = {.d32 = 0 };
578 hprt0_data_t hprt0 = {.d32 = 0 };
582 DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
583 /* Switch-on voltage to the core */
584 gpwrdn.b.pwrdnswtch = 1;
585 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
590 gpwrdn.b.pwrdnrstn = 1;
591 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
594 /* Assert Restore signal */
596 gpwrdn.b.restore = 1;
597 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
600 /* Disable power clamps */
602 gpwrdn.b.pwrdnclmp = 1;
603 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
609 /* Deassert Reset core */
611 gpwrdn.b.pwrdnrstn = 1;
612 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
615 /* Disable PMU interrupt */
617 gpwrdn.b.pmuintsel = 1;
618 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
621 gpwrdn.b.connect_det_msk = 1;
622 gpwrdn.b.srp_det_msk = 1;
623 gpwrdn.b.disconn_det_msk = 1;
624 gpwrdn.b.rst_det_msk = 1;
625 gpwrdn.b.lnstchng_msk = 1;
626 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
628 /* Indicates that we are going out from hibernation */
629 core_if->hibernation_suspend = 0;
631 /* Set Restore Essential Regs bit in PCGCCTL register */
632 restore_essential_regs(core_if, rem_wakeup, 1);
634 /* Wait a little for seeing new value of variable hibernation_suspend if
635 * Restore done interrupt received before polling */
638 if (core_if->hibernation_suspend == 0) {
639 /* Wait For Restore_done Interrupt. This mechanism of polling the
640 * interrupt is introduced to avoid any possible race conditions
643 gintsts_data_t gintsts;
644 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
645 if (gintsts.b.restoredone) {
647 gintsts.b.restoredone = 1;
648 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
649 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");
655 DWC_WARN("Restore Done interrupt wasn't generated\n");
659 /* Set the flag's value to 0 again after receiving restore done interrupt */
660 core_if->hibernation_suspend = 0;
662 /* This step is not described in functional spec but if not wait for this
663 * delay, mismatch interrupts occurred because just after restore core is
664 * in Device mode(gintsts.curmode == 0) */
667 /* Clear all pending interrupts */
668 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
670 /* De-assert Restore */
672 gpwrdn.b.restore = 1;
673 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
676 /* Restore GUSBCFG and HCFG */
677 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
678 core_if->gr_backup->gusbcfg_local);
679 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
680 core_if->hr_backup->hcfg_local);
682 /* De-assert Wakeup Logic */
684 gpwrdn.b.pmuactv = 1;
685 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
688 /* Start the Resume operation by programming HPRT0 */
689 hprt0.d32 = core_if->hr_backup->hprt0_local;
693 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
695 DWC_PRINTF("Resume Starts Now\n");
696 if (!reset) { // Indicates it is Resume Operation
697 hprt0.d32 = core_if->hr_backup->hprt0_local;
702 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
706 /* Wait for Resume time and then program HPRT again */
708 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
710 } else { // Indicates it is Reset Operation
711 hprt0.d32 = core_if->hr_backup->hprt0_local;
716 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
717 /* Wait for Reset time and then program HPRT again */
720 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
722 /* Clear all interrupt status */
723 hprt0.d32 = dwc_otg_read_hprt0(core_if);
724 hprt0.b.prtconndet = 1;
725 hprt0.b.prtenchng = 1;
726 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
728 /* Clear all pending interupts */
729 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
731 /* Restore global registers */
732 dwc_otg_restore_global_regs(core_if);
733 /* Restore host global registers */
734 dwc_otg_restore_host_regs(core_if, reset);
736 /* The core will be in ON STATE */
737 core_if->lx_state = DWC_OTG_L0;
738 DWC_PRINTF("Hibernation recovery is complete here\n");
742 /** Saves some register values into system memory. */
743 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
745 struct dwc_otg_global_regs_backup *gr;
748 gr = core_if->gr_backup;
750 gr = DWC_ALLOC(sizeof(*gr));
752 return -DWC_E_NO_MEMORY;
754 core_if->gr_backup = gr;
757 gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
758 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
759 gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
760 gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
761 gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
762 gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
763 gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
764 #ifdef CONFIG_USB_DWC_OTG_LPM
765 gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
767 gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
768 gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
769 gr->gdfifocfg_local =
770 DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
771 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
772 gr->dtxfsiz_local[i] =
773 DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
776 DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
777 DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl = %08x\n", gr->gotgctl_local);
778 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
779 DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg = %08x\n", gr->gahbcfg_local);
780 DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg = %08x\n", gr->gusbcfg_local);
781 DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz = %08x\n", gr->grxfsiz_local);
782 DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
783 gr->gnptxfsiz_local);
784 DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz = %08x\n",
786 #ifdef CONFIG_USB_DWC_OTG_LPM
787 DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local);
789 DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl = %08x\n", gr->gi2cctl_local);
790 DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl = %08x\n", gr->pcgcctl_local);
791 DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg = %08x\n",gr->gdfifocfg_local);
796 /** Saves GINTMSK register before setting the msk bits. */
797 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
799 struct dwc_otg_global_regs_backup *gr;
801 gr = core_if->gr_backup;
803 gr = DWC_ALLOC(sizeof(*gr));
805 return -DWC_E_NO_MEMORY;
807 core_if->gr_backup = gr;
810 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
812 DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
813 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
818 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
820 struct dwc_otg_dev_regs_backup *dr;
823 dr = core_if->dr_backup;
825 dr = DWC_ALLOC(sizeof(*dr));
827 return -DWC_E_NO_MEMORY;
829 core_if->dr_backup = dr;
832 dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
833 dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
835 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
837 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
839 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
841 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
843 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
845 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
847 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
851 "=============Backing Host registers==============\n");
852 DWC_DEBUGPL(DBG_ANY, "Backed up dcfg = %08x\n", dr->dcfg);
853 DWC_DEBUGPL(DBG_ANY, "Backed up dctl = %08x\n", dr->dctl);
854 DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk = %08x\n",
856 DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk = %08x\n", dr->diepmsk);
857 DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk = %08x\n", dr->doepmsk);
858 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
859 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d] = %08x\n", i,
861 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n",
863 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i,
870 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
872 struct dwc_otg_host_regs_backup *hr;
875 hr = core_if->hr_backup;
877 hr = DWC_ALLOC(sizeof(*hr));
879 return -DWC_E_NO_MEMORY;
881 core_if->hr_backup = hr;
885 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
887 DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
888 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
889 hr->hcintmsk_local[i] =
890 DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
892 hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
894 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
897 "=============Backing Host registers===============\n");
898 DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n",
900 DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
901 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
902 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
903 hr->hcintmsk_local[i]);
905 DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n",
907 DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n",
913 int dwc_otg_restore_global_regs(dwc_otg_core_if_t *core_if)
915 struct dwc_otg_global_regs_backup *gr;
918 gr = core_if->gr_backup;
920 return -DWC_E_INVALID;
923 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
924 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
925 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
926 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
927 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
928 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
929 gr->gnptxfsiz_local);
930 DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
932 DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
933 gr->gdfifocfg_local);
934 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
935 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
936 gr->dtxfsiz_local[i]);
939 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
940 DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
941 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
942 (gr->gahbcfg_local));
946 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
948 struct dwc_otg_dev_regs_backup *dr;
951 dr = core_if->dr_backup;
954 return -DWC_E_INVALID;
958 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
962 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
963 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
964 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
966 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
967 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
968 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
969 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
975 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
977 struct dwc_otg_host_regs_backup *hr;
979 hr = core_if->hr_backup;
982 return -DWC_E_INVALID;
985 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
988 // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
991 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
993 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
994 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
995 hr->hcintmsk_local[i]);
1001 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
1003 struct dwc_otg_global_regs_backup *gr;
1005 gr = core_if->gr_backup;
1007 /* Restore values for LPM and I2C */
1008 #ifdef CONFIG_USB_DWC_OTG_LPM
1009 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
1011 DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
1016 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
1018 struct dwc_otg_global_regs_backup *gr;
1019 pcgcctl_data_t pcgcctl = {.d32 = 0 };
1020 gahbcfg_data_t gahbcfg = {.d32 = 0 };
1021 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1022 gintmsk_data_t gintmsk = {.d32 = 0 };
1024 /* Restore LPM and I2C registers */
1025 restore_lpm_i2c_regs(core_if);
1027 /* Set PCGCCTL to 0 */
1028 DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
1030 gr = core_if->gr_backup;
1031 /* Load restore values for [31:14] bits */
1032 DWC_WRITE_REG32(core_if->pcgcctl,
1033 ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
1035 /* Umnask global Interrupt in GAHBCFG and restore it */
1036 gahbcfg.d32 = gr->gahbcfg_local;
1037 gahbcfg.b.glblintrmsk = 1;
1038 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
1040 /* Clear all pending interupts */
1041 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
1043 /* Unmask restore done interrupt */
1044 gintmsk.b.restoredone = 1;
1045 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1047 /* Restore GUSBCFG and HCFG/DCFG */
1048 gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
1049 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
1052 hcfg_data_t hcfg = {.d32 = 0 };
1053 hcfg.d32 = core_if->hr_backup->hcfg_local;
1054 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
1057 /* Load restore values for [31:14] bits */
1058 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1059 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1062 pcgcctl.b.restoremode = 1;
1063 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1066 /* Load restore values for [31:14] bits and set EssRegRestored bit */
1067 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
1068 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1069 pcgcctl.b.ess_reg_restored = 1;
1071 pcgcctl.b.restoremode = 1;
1072 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1074 dcfg_data_t dcfg = {.d32 = 0 };
1075 dcfg.d32 = core_if->dr_backup->dcfg;
1076 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1078 /* Load restore values for [31:14] bits */
1079 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1080 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1082 pcgcctl.d32 |= 0x208;
1084 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1087 /* Load restore values for [31:14] bits */
1088 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1089 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1090 pcgcctl.b.ess_reg_restored = 1;
1092 pcgcctl.d32 |= 0x208;
1093 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1100 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1103 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
1108 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1109 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1110 (core_if->core_params->ulpi_fs_ls)) ||
1111 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1112 /* Full speed PHY */
1113 val = DWC_HCFG_48_MHZ;
1115 /* High speed PHY running at full speed or high speed */
1116 val = DWC_HCFG_30_60_MHZ;
1119 DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1120 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
1121 hcfg.b.fslspclksel = val;
1122 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1126 * Initializes the DevSpd field of the DCFG register depending on the PHY type
1127 * and the enumeration speed of the device.
1129 static void init_devspd(dwc_otg_core_if_t * core_if)
1134 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1135 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1136 (core_if->core_params->ulpi_fs_ls)) ||
1137 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1138 /* Full speed PHY */
1140 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1141 /* High speed PHY running at full speed */
1144 /* High speed PHY running at high speed */
1148 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1150 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
1151 dcfg.b.devspd = val;
1152 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1156 * This function calculates the number of IN EPS
1157 * using GHWCFG1 and GHWCFG2 registers values
1159 * @param core_if Programming view of the DWC_otg controller
1161 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
1163 uint32_t num_in_eps = 0;
1164 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1165 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
1166 uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
1169 for (i = 0; i < num_eps; ++i) {
1170 if (!(hwcfg1 & 0x1))
1176 if (core_if->hwcfg4.b.ded_fifo_en) {
1178 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1185 * This function calculates the number of OUT EPS
1186 * using GHWCFG1 and GHWCFG2 registers values
1188 * @param core_if Programming view of the DWC_otg controller
1190 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
1192 uint32_t num_out_eps = 0;
1193 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1194 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
1197 for (i = 0; i < num_eps; ++i) {
1198 if (!(hwcfg1 & 0x1))
1207 * This function initializes the DWC_otg controller registers and
1208 * prepares the core for device mode or host mode operation.
1210 * @param core_if Programming view of the DWC_otg controller
1213 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
1216 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1217 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1218 gahbcfg_data_t ahbcfg = {.d32 = 0 };
1219 gusbcfg_data_t usbcfg = {.d32 = 0 };
1220 gi2cctl_data_t i2cctl = {.d32 = 0 };
1222 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p) regs at %p\n",
1223 core_if, global_regs);
1225 /* Common Initialization */
1226 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1228 /* Program the ULPI External VBUS bit if needed */
1229 usbcfg.b.ulpi_ext_vbus_drv =
1230 (core_if->core_params->phy_ulpi_ext_vbus ==
1231 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1233 /* Set external TS Dline pulsing */
1234 usbcfg.b.term_sel_dl_pulse =
1235 (core_if->core_params->ts_dline == 1) ? 1 : 0;
1236 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1238 /* Reset the Controller */
1239 dwc_otg_core_reset(core_if);
1241 core_if->adp_enable = core_if->core_params->adp_supp_enable;
1242 core_if->power_down = core_if->core_params->power_down;
1243 core_if->otg_sts = 0;
1245 /* Initialize parameters from Hardware configuration registers. */
1246 dev_if->num_in_eps = calc_num_in_eps(core_if);
1247 dev_if->num_out_eps = calc_num_out_eps(core_if);
1249 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1250 core_if->hwcfg4.b.num_dev_perio_in_ep);
1252 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1253 dev_if->perio_tx_fifo_size[i] =
1254 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1255 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1256 i, dev_if->perio_tx_fifo_size[i]);
1259 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1260 dev_if->tx_fifo_size[i] =
1261 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1262 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1263 i, dev_if->tx_fifo_size[i]);
1266 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1267 core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
1268 core_if->nperio_tx_fifo_size =
1269 DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
1271 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1272 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1273 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
1274 core_if->nperio_tx_fifo_size);
1276 /* This programming sequence needs to happen in FS mode before any other
1277 * programming occurs */
1278 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1279 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1280 /* If FS mode with FS PHY */
1282 /* core_init() is now called on every switch so only call the
1283 * following for the first time through. */
1284 if (!core_if->phy_init_done) {
1285 core_if->phy_init_done = 1;
1286 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1287 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1288 usbcfg.b.physel = 1;
1289 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1291 /* Reset after a PHY select */
1292 dwc_otg_core_reset(core_if);
1295 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1296 * do this on HNP Dev/Host mode switches (done in dev_init and
1298 if (dwc_otg_is_host_mode(core_if)) {
1299 init_fslspclksel(core_if);
1301 init_devspd(core_if);
1304 if (core_if->core_params->i2c_enable) {
1305 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1306 /* Program GUSBCFG.OtgUtmifsSel to I2C */
1307 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1308 usbcfg.b.otgutmifssel = 1;
1309 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1311 /* Program GI2CCTL.I2CEn */
1312 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1313 i2cctl.b.i2cdevaddr = 1;
1315 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1317 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1320 } /* endif speed == DWC_SPEED_PARAM_FULL */
1322 /* High speed PHY. */
1323 if (!core_if->phy_init_done) {
1324 core_if->phy_init_done = 1;
1325 /* HS PHY parameters. These parameters are preserved
1326 * during soft reset so only program the first time. Do
1327 * a soft reset immediately after setting phyif. */
1329 if (core_if->core_params->phy_type == 2) {
1330 /* ULPI interface */
1331 usbcfg.b.ulpi_utmi_sel = 1;
1334 core_if->core_params->phy_ulpi_ddr;
1335 } else if (core_if->core_params->phy_type == 1) {
1336 /* UTMI+ interface */
1337 usbcfg.b.ulpi_utmi_sel = 0;
1338 if (core_if->core_params->phy_utmi_width == 16) {
1345 DWC_ERROR("FS PHY TYPE\n");
1347 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1348 /* Reset after setting the PHY parameters */
1349 dwc_otg_core_reset(core_if);
1353 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1354 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1355 (core_if->core_params->ulpi_fs_ls)) {
1356 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1357 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1358 usbcfg.b.ulpi_fsls = 1;
1359 usbcfg.b.ulpi_clk_sus_m = 1;
1360 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1362 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1363 usbcfg.b.ulpi_fsls = 0;
1364 usbcfg.b.ulpi_clk_sus_m = 0;
1365 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1368 /* Program the GAHBCFG Register. */
1369 switch (core_if->hwcfg2.b.architecture) {
1371 case DWC_SLAVE_ONLY_ARCH:
1372 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1373 ahbcfg.b.nptxfemplvl_txfemplvl =
1374 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1375 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1376 core_if->dma_enable = 0;
1377 core_if->dma_desc_enable = 0;
1380 case DWC_EXT_DMA_ARCH:
1381 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1383 uint8_t brst_sz = core_if->core_params->dma_burst_size;
1384 ahbcfg.b.hburstlen = 0;
1385 while (brst_sz > 1) {
1386 ahbcfg.b.hburstlen++;
1390 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1391 core_if->dma_desc_enable =
1392 (core_if->core_params->dma_desc_enable != 0);
1395 case DWC_INT_DMA_ARCH:
1396 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1397 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
1398 Host mode ISOC in issue fix - vahrama */
1399 /* Broadcom had altered to (1<<3)|(0<<0) - WRESP=1, max 4 beats */
1400 ahbcfg.b.hburstlen = (1<<3)|(0<<0);//DWC_GAHBCFG_INT_DMA_BURST_INCR4;
1401 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1402 core_if->dma_desc_enable =
1403 (core_if->core_params->dma_desc_enable != 0);
1407 if (core_if->dma_enable) {
1408 if (core_if->dma_desc_enable) {
1409 DWC_PRINTF("Using Descriptor DMA mode\n");
1411 DWC_PRINTF("Using Buffer DMA mode\n");
1415 DWC_PRINTF("Using Slave mode\n");
1416 core_if->dma_desc_enable = 0;
1419 if (core_if->core_params->ahb_single) {
1420 ahbcfg.b.ahbsingle = 1;
1423 ahbcfg.b.dmaenable = core_if->dma_enable;
1424 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1426 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1428 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1429 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1430 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1431 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
1432 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1433 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
1436 * Program the GUSBCFG register.
1438 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1440 switch (core_if->hwcfg2.b.op_mode) {
1441 case DWC_MODE_HNP_SRP_CAPABLE:
1442 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1443 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1444 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1445 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1448 case DWC_MODE_SRP_ONLY_CAPABLE:
1449 usbcfg.b.hnpcap = 0;
1450 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1451 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1454 case DWC_MODE_NO_HNP_SRP_CAPABLE:
1455 usbcfg.b.hnpcap = 0;
1456 usbcfg.b.srpcap = 0;
1459 case DWC_MODE_SRP_CAPABLE_DEVICE:
1460 usbcfg.b.hnpcap = 0;
1461 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1462 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1465 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1466 usbcfg.b.hnpcap = 0;
1467 usbcfg.b.srpcap = 0;
1470 case DWC_MODE_SRP_CAPABLE_HOST:
1471 usbcfg.b.hnpcap = 0;
1472 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1473 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1476 case DWC_MODE_NO_SRP_CAPABLE_HOST:
1477 usbcfg.b.hnpcap = 0;
1478 usbcfg.b.srpcap = 0;
1482 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1484 #ifdef CONFIG_USB_DWC_OTG_LPM
1485 if (core_if->core_params->lpm_enable) {
1486 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1488 /* To enable LPM support set lpm_cap_en bit */
1489 lpmcfg.b.lpm_cap_en = 1;
1491 /* Make AppL1Res ACK */
1492 lpmcfg.b.appl_resp = 1;
1495 lpmcfg.b.retry_count = 3;
1497 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1502 if (core_if->core_params->ic_usb_cap) {
1503 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1504 gusbcfg.b.ic_usb_cap = 1;
1505 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
1509 gotgctl_data_t gotgctl = {.d32 = 0 };
1510 gotgctl.b.otgver = core_if->core_params->otg_ver;
1511 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
1513 /* Set OTG version supported */
1514 core_if->otg_ver = core_if->core_params->otg_ver;
1515 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1516 core_if->core_params->otg_ver, core_if->otg_ver);
1520 /* Enable common interrupts */
1521 dwc_otg_enable_common_interrupts(core_if);
1523 /* Do device or host intialization based on mode during PCD
1524 * and HCD initialization */
1525 if (dwc_otg_is_host_mode(core_if)) {
1526 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
1527 core_if->op_state = A_HOST;
1529 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
1530 core_if->op_state = B_PERIPHERAL;
1531 #ifdef DWC_DEVICE_ONLY
1532 dwc_otg_core_dev_init(core_if);
1538 * This function enables the Device mode interrupts.
1540 * @param core_if Programming view of DWC_otg controller
1542 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
1544 gintmsk_data_t intr_mask = {.d32 = 0 };
1545 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1547 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1549 /* Disable all interrupts. */
1550 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
1552 /* Clear any pending interrupts */
1553 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
1555 /* Enable the common interrupts */
1556 dwc_otg_enable_common_interrupts(core_if);
1558 /* Enable interrupts */
1559 intr_mask.b.usbreset = 1;
1560 intr_mask.b.enumdone = 1;
1561 /* Disable Disconnect interrupt in Device mode */
1562 intr_mask.b.disconnect = 0;
1564 if (!core_if->multiproc_int_enable) {
1565 intr_mask.b.inepintr = 1;
1566 intr_mask.b.outepintr = 1;
1569 intr_mask.b.erlysuspend = 1;
1571 if (core_if->en_multiple_tx_fifo == 0) {
1572 intr_mask.b.epmismatch = 1;
1575 //intr_mask.b.incomplisoout = 1;
1576 intr_mask.b.incomplisoin = 1;
1578 /* Enable the ignore frame number for ISOC xfers - MAS */
1579 /* Disable to support high bandwith ISOC transfers - manukz */
1581 #ifdef DWC_UTE_PER_IO
1582 if (core_if->dma_enable) {
1583 if (core_if->dma_desc_enable) {
1584 dctl_data_t dctl1 = {.d32 = 0 };
1585 dctl1.b.ifrmnum = 1;
1586 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
1587 dctl, 0, dctl1.d32);
1588 DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
1589 DWC_READ_REG32(&core_if->dev_if->
1590 dev_global_regs->dctl));
1596 if (core_if->dma_enable) {
1597 if (core_if->dma_desc_enable == 0) {
1598 if (core_if->pti_enh_enable) {
1599 dctl_data_t dctl = {.d32 = 0 };
1601 DWC_MODIFY_REG32(&core_if->
1602 dev_if->dev_global_regs->dctl,
1605 intr_mask.b.incomplisoin = 1;
1606 intr_mask.b.incomplisoout = 1;
1610 intr_mask.b.incomplisoin = 1;
1611 intr_mask.b.incomplisoout = 1;
1613 #endif /* DWC_EN_ISOC */
1615 /** @todo NGS: Should this be a module parameter? */
1616 #ifdef USE_PERIODIC_EP
1617 intr_mask.b.isooutdrop = 1;
1618 intr_mask.b.eopframe = 1;
1619 intr_mask.b.incomplisoin = 1;
1620 intr_mask.b.incomplisoout = 1;
1623 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1625 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1626 DWC_READ_REG32(&global_regs->gintmsk));
1630 * This function initializes the DWC_otg controller registers for
1633 * @param core_if Programming view of DWC_otg controller
1636 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
1639 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1640 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1641 dwc_otg_core_params_t *params = core_if->core_params;
1642 dcfg_data_t dcfg = {.d32 = 0 };
1643 depctl_data_t diepctl = {.d32 = 0 };
1644 grstctl_t resetctl = {.d32 = 0 };
1645 uint32_t rx_fifo_size;
1646 fifosize_data_t nptxfifosize;
1647 fifosize_data_t txfifosize;
1648 dthrctl_data_t dthrctl;
1649 fifosize_data_t ptxfifosize;
1650 uint16_t rxfsiz, nptxfsiz;
1651 gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
1652 hwcfg3_data_t hwcfg3 = {.d32 = 0 };
1654 /* Restart the Phy Clock */
1655 DWC_WRITE_REG32(core_if->pcgcctl, 0);
1657 /* Device configuration register */
1658 init_devspd(core_if);
1659 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1660 dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
1661 dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1662 /* Enable Device OUT NAK in case of DDMA mode*/
1663 if (core_if->core_params->dev_out_nak) {
1664 dcfg.b.endevoutnak = 1;
1667 if (core_if->core_params->cont_on_bna) {
1668 dctl_data_t dctl = {.d32 = 0 };
1669 dctl.b.encontonbna = 1;
1670 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1674 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1676 /* Configure data FIFO sizes */
1677 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1678 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
1679 core_if->total_fifo_size);
1680 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
1681 params->dev_rx_fifo_size);
1682 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
1683 params->dev_nperio_tx_fifo_size);
1686 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1687 DWC_READ_REG32(&global_regs->grxfsiz));
1690 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
1691 core_if->init_rxfsiz = params->dev_rx_fifo_size;
1693 rx_fifo_size = params->dev_rx_fifo_size;
1694 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
1696 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1697 DWC_READ_REG32(&global_regs->grxfsiz));
1699 /** Set Periodic Tx FIFO Mask all bits 0 */
1700 core_if->p_tx_msk = 0;
1702 /** Set Tx FIFO Mask all bits 0 */
1703 core_if->tx_msk = 0;
1705 if (core_if->en_multiple_tx_fifo == 0) {
1706 /* Non-periodic Tx FIFO */
1707 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1708 DWC_READ_REG32(&global_regs->gnptxfsiz));
1710 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1711 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1713 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1716 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1717 DWC_READ_REG32(&global_regs->gnptxfsiz));
1719 /**@todo NGS: Fix Periodic FIFO Sizing! */
1721 * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1722 * Indexes of the FIFO size module parameters in the
1723 * dev_perio_tx_fifo_size array and the FIFO size registers in
1724 * the dptxfsiz array run from 0 to 14.
1726 /** @todo Finish debug of this */
1727 ptxfifosize.b.startaddr =
1728 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1729 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1730 ptxfifosize.b.depth =
1731 params->dev_perio_tx_fifo_size[i];
1732 DWC_DEBUGPL(DBG_CIL,
1733 "initial dtxfsiz[%d]=%08x\n", i,
1734 DWC_READ_REG32(&global_regs->dtxfsiz
1736 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1738 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
1740 DWC_READ_REG32(&global_regs->dtxfsiz
1742 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
1746 * Tx FIFOs These FIFOs are numbered from 1 to 15.
1747 * Indexes of the FIFO size module parameters in the
1748 * dev_tx_fifo_size array and the FIFO size registers in
1749 * the dtxfsiz array run from 0 to 14.
1752 /* Non-periodic Tx FIFO */
1753 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1754 DWC_READ_REG32(&global_regs->gnptxfsiz));
1757 core_if->pwron_gnptxfsiz =
1758 (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1759 core_if->init_gnptxfsiz =
1760 params->dev_nperio_tx_fifo_size;
1762 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1763 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1765 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1768 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1769 DWC_READ_REG32(&global_regs->gnptxfsiz));
1771 txfifosize.b.startaddr =
1772 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1774 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1776 txfifosize.b.depth =
1777 params->dev_tx_fifo_size[i];
1779 DWC_DEBUGPL(DBG_CIL,
1780 "initial dtxfsiz[%d]=%08x\n",
1782 DWC_READ_REG32(&global_regs->dtxfsiz
1786 core_if->pwron_txfsiz[i] =
1788 (&global_regs->dtxfsiz[i]) >> 16);
1789 core_if->init_txfsiz[i] =
1790 params->dev_tx_fifo_size[i];
1792 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1795 DWC_DEBUGPL(DBG_CIL,
1796 "new dtxfsiz[%d]=%08x\n",
1798 DWC_READ_REG32(&global_regs->dtxfsiz
1801 txfifosize.b.startaddr += txfifosize.b.depth;
1803 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
1804 /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO */
1805 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
1806 hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
1807 gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
1808 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1809 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
1810 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1811 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
1812 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1816 /* Flush the FIFOs */
1817 dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
1818 dwc_otg_flush_rx_fifo(core_if);
1820 /* Flush the Learning Queue. */
1821 resetctl.b.intknqflsh = 1;
1822 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
1824 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
1825 core_if->start_predict = 0;
1826 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
1827 core_if->nextep_seq[i] = 0xff; // 0xff - EP not active
1829 core_if->nextep_seq[0] = 0;
1830 core_if->first_in_nextep_seq = 0;
1831 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
1832 diepctl.b.nextep = 0;
1833 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
1835 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
1836 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1838 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1840 DWC_DEBUGPL(DBG_CILV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
1841 __func__, core_if->first_in_nextep_seq);
1842 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
1843 DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]);
1845 DWC_DEBUGPL(DBG_CILV,"\n");
1848 /* Clear all pending Device Interrupts */
1849 /** @todo - if the condition needed to be checked
1850 * or in any case all pending interrutps should be cleared?
1852 if (core_if->multiproc_int_enable) {
1853 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
1854 DWC_WRITE_REG32(&dev_if->
1855 dev_global_regs->diepeachintmsk[i], 0);
1859 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1860 DWC_WRITE_REG32(&dev_if->
1861 dev_global_regs->doepeachintmsk[i], 0);
1864 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1865 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
1867 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
1868 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
1869 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1870 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
1873 for (i = 0; i <= dev_if->num_in_eps; i++) {
1874 depctl_data_t depctl;
1875 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
1876 if (depctl.b.epena) {
1884 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1886 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1887 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
1888 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1891 for (i = 0; i <= dev_if->num_out_eps; i++) {
1892 depctl_data_t depctl;
1893 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
1894 if (depctl.b.epena) {
1895 dctl_data_t dctl = {.d32 = 0 };
1896 gintmsk_data_t gintsts = {.d32 = 0 };
1897 doepint_data_t doepint = {.d32 = 0 };
1898 dctl.b.sgoutnak = 1;
1899 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1902 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
1903 } while (!gintsts.b.goutnakeff);
1905 gintsts.b.goutnakeff = 1;
1906 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1911 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1914 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
1915 out_ep_regs[i]->doepint);
1916 } while (!doepint.b.epdisabled);
1918 doepint.b.epdisabled = 1;
1919 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32);
1922 dctl.b.cgoutnak = 1;
1923 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1928 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1930 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
1931 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
1932 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
1935 if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1936 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
1937 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
1938 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
1940 dev_if->rx_thr_length = params->rx_thr_length;
1941 dev_if->tx_thr_length = params->tx_thr_length;
1943 dev_if->setup_desc_index = 0;
1946 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1947 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1948 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1949 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1950 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1951 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
1953 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1956 DWC_DEBUGPL(DBG_CIL,
1957 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1958 dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1959 dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1960 dthrctl.b.rx_thr_len);
1964 dwc_otg_enable_device_interrupts(core_if);
1967 diepmsk_data_t msk = {.d32 = 0 };
1968 msk.b.txfifoundrn = 1;
1969 if (core_if->multiproc_int_enable) {
1970 DWC_MODIFY_REG32(&dev_if->dev_global_regs->
1971 diepeachintmsk[0], msk.d32, msk.d32);
1973 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
1978 if (core_if->multiproc_int_enable) {
1979 /* Set NAK on Babble */
1980 dctl_data_t dctl = {.d32 = 0 };
1981 dctl.b.nakonbble = 1;
1982 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1985 if (core_if->snpsid >= OTG_CORE_REV_2_94a) {
1986 dctl_data_t dctl = {.d32 = 0 };
1987 dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
1988 dctl.b.sftdiscon = 0;
1989 DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
1994 * This function enables the Host mode interrupts.
1996 * @param core_if Programming view of DWC_otg controller
1998 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
2000 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2001 gintmsk_data_t intr_mask = {.d32 = 0 };
2003 DWC_DEBUGPL(DBG_CIL, "%s(%p)\n", __func__, core_if);
2005 /* Disable all interrupts. */
2006 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
2008 /* Clear any pending interrupts. */
2009 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
2011 /* Enable the common interrupts */
2012 dwc_otg_enable_common_interrupts(core_if);
2015 * Enable host mode interrupts without disturbing common
2019 intr_mask.b.disconnect = 1;
2020 intr_mask.b.portintr = 1;
2021 intr_mask.b.hcintr = 1;
2023 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2027 * This function disables the Host Mode interrupts.
2029 * @param core_if Programming view of DWC_otg controller
2031 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
2033 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2034 gintmsk_data_t intr_mask = {.d32 = 0 };
2036 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2039 * Disable host mode interrupts without disturbing common
2042 intr_mask.b.sofintr = 1;
2043 intr_mask.b.portintr = 1;
2044 intr_mask.b.hcintr = 1;
2045 intr_mask.b.ptxfempty = 1;
2046 intr_mask.b.nptxfempty = 1;
2048 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
2052 * This function initializes the DWC_otg controller registers for
2055 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2056 * request queues. Host channels are reset to ensure that they are ready for
2057 * performing transfers.
2059 * @param core_if Programming view of DWC_otg controller
2062 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
2064 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2065 dwc_otg_host_if_t *host_if = core_if->host_if;
2066 dwc_otg_core_params_t *params = core_if->core_params;
2067 hprt0_data_t hprt0 = {.d32 = 0 };
2068 fifosize_data_t nptxfifosize;
2069 fifosize_data_t ptxfifosize;
2070 uint16_t rxfsiz, nptxfsiz, hptxfsiz;
2071 gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
2073 hcchar_data_t hcchar;
2076 dwc_otg_hc_regs_t *hc_regs;
2078 gotgctl_data_t gotgctl = {.d32 = 0 };
2080 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
2082 /* Restart the Phy Clock */
2083 DWC_WRITE_REG32(core_if->pcgcctl, 0);
2085 /* Initialize Host Configuration Register */
2086 init_fslspclksel(core_if);
2087 if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
2088 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2089 hcfg.b.fslssupp = 1;
2090 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2094 /* This bit allows dynamic reloading of the HFIR register
2095 * during runtime. This bit needs to be programmed during
2096 * initial configuration and its value must not be changed
2098 if (core_if->core_params->reload_ctl == 1) {
2099 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
2100 hfir.b.hfirrldctrl = 1;
2101 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
2104 if (core_if->core_params->dma_desc_enable) {
2105 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
2107 (core_if->hwcfg4.b.desc_dma
2108 && (core_if->snpsid >= OTG_CORE_REV_2_90a)
2109 && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
2110 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
2112 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
2113 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
2115 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
2117 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
2118 "Either core version is below 2.90a or "
2119 "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
2120 "To run the driver in Buffer DMA host mode set dma_desc_enable "
2121 "module parameter to 0.\n");
2124 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2126 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2129 /* Configure data FIFO sizes */
2130 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2131 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
2132 core_if->total_fifo_size);
2133 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
2134 params->host_rx_fifo_size);
2135 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
2136 params->host_nperio_tx_fifo_size);
2137 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
2138 params->host_perio_tx_fifo_size);
2141 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
2142 DWC_READ_REG32(&global_regs->grxfsiz));
2143 DWC_WRITE_REG32(&global_regs->grxfsiz,
2144 params->host_rx_fifo_size);
2145 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
2146 DWC_READ_REG32(&global_regs->grxfsiz));
2148 /* Non-periodic Tx FIFO */
2149 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2150 DWC_READ_REG32(&global_regs->gnptxfsiz));
2151 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
2152 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
2153 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2154 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2155 DWC_READ_REG32(&global_regs->gnptxfsiz));
2157 /* Periodic Tx FIFO */
2158 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
2159 DWC_READ_REG32(&global_regs->hptxfsiz));
2160 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
2161 ptxfifosize.b.startaddr =
2162 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2163 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
2164 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
2165 DWC_READ_REG32(&global_regs->hptxfsiz));
2167 if (core_if->en_multiple_tx_fifo
2168 && core_if->snpsid <= OTG_CORE_REV_2_94a) {
2169 /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
2170 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
2171 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
2172 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2173 hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
2174 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
2175 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2179 /* TODO - check this */
2180 /* Clear Host Set HNP Enable in the OTG Control Register */
2181 gotgctl.b.hstsethnpen = 1;
2182 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2183 /* Make sure the FIFOs are flushed. */
2184 dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ );
2185 dwc_otg_flush_rx_fifo(core_if);
2187 /* Clear Host Set HNP Enable in the OTG Control Register */
2188 gotgctl.b.hstsethnpen = 1;
2189 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2191 if (!core_if->core_params->dma_desc_enable) {
2192 /* Flush out any leftover queued requests. */
2193 num_channels = core_if->core_params->host_channels;
2195 for (i = 0; i < num_channels; i++) {
2196 hc_regs = core_if->host_if->hc_regs[i];
2197 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2201 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2204 /* Halt all channels to put them into a known state. */
2205 for (i = 0; i < num_channels; i++) {
2207 hc_regs = core_if->host_if->hc_regs[i];
2208 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2212 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2213 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d regs %p\n", __func__, i, hc_regs);
2215 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2216 if (++count > 1000) {
2218 ("%s: Unable to clear halt on channel %d (timeout HCCHAR 0x%X @%p)\n",
2219 __func__, i, hcchar.d32, &hc_regs->hcchar);
2223 } while (hcchar.b.chen);
2227 /* Turn on the vbus power. */
2228 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
2229 if (core_if->op_state == A_HOST) {
2230 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2231 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2232 if (hprt0.b.prtpwr == 0) {
2234 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2238 dwc_otg_enable_host_interrupts(core_if);
2242 * Prepares a host channel for transferring packets to/from a specific
2243 * endpoint. The HCCHARn register is set up with the characteristics specified
2244 * in _hc. Host channel interrupts that may need to be serviced while this
2245 * transfer is in progress are enabled.
2247 * @param core_if Programming view of DWC_otg controller
2248 * @param hc Information needed to initialize the host channel
2250 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2252 hcintmsk_data_t hc_intr_mask;
2253 hcchar_data_t hcchar;
2254 hcsplt_data_t hcsplt;
2256 uint8_t hc_num = hc->hc_num;
2257 dwc_otg_host_if_t *host_if = core_if->host_if;
2258 dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2260 /* Clear old interrupt conditions for this host channel. */
2261 hc_intr_mask.d32 = 0xFFFFFFFF;
2262 hc_intr_mask.b.reserved14_31 = 0;
2263 DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
2265 /* Enable channel interrupts required for this transfer. */
2266 hc_intr_mask.d32 = 0;
2267 hc_intr_mask.b.chhltd = 1;
2268 if (core_if->dma_enable) {
2269 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
2270 if (!core_if->dma_desc_enable)
2271 hc_intr_mask.b.ahberr = 1;
2273 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2274 hc_intr_mask.b.xfercompl = 1;
2277 if (hc->error_state && !hc->do_split &&
2278 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2279 hc_intr_mask.b.ack = 1;
2281 hc_intr_mask.b.datatglerr = 1;
2282 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2283 hc_intr_mask.b.nak = 1;
2288 switch (hc->ep_type) {
2289 case DWC_OTG_EP_TYPE_CONTROL:
2290 case DWC_OTG_EP_TYPE_BULK:
2291 hc_intr_mask.b.xfercompl = 1;
2292 hc_intr_mask.b.stall = 1;
2293 hc_intr_mask.b.xacterr = 1;
2294 hc_intr_mask.b.datatglerr = 1;
2296 hc_intr_mask.b.bblerr = 1;
2298 hc_intr_mask.b.nak = 1;
2299 hc_intr_mask.b.nyet = 1;
2301 hc_intr_mask.b.ack = 1;
2306 hc_intr_mask.b.nak = 1;
2307 if (hc->complete_split) {
2308 hc_intr_mask.b.nyet = 1;
2310 hc_intr_mask.b.ack = 1;
2314 if (hc->error_state) {
2315 hc_intr_mask.b.ack = 1;
2318 case DWC_OTG_EP_TYPE_INTR:
2319 hc_intr_mask.b.xfercompl = 1;
2320 hc_intr_mask.b.nak = 1;
2321 hc_intr_mask.b.stall = 1;
2322 hc_intr_mask.b.xacterr = 1;
2323 hc_intr_mask.b.datatglerr = 1;
2324 hc_intr_mask.b.frmovrun = 1;
2327 hc_intr_mask.b.bblerr = 1;
2329 if (hc->error_state) {
2330 hc_intr_mask.b.ack = 1;
2333 if (hc->complete_split) {
2334 hc_intr_mask.b.nyet = 1;
2336 hc_intr_mask.b.ack = 1;
2340 case DWC_OTG_EP_TYPE_ISOC:
2341 hc_intr_mask.b.xfercompl = 1;
2342 hc_intr_mask.b.frmovrun = 1;
2343 hc_intr_mask.b.ack = 1;
2346 hc_intr_mask.b.xacterr = 1;
2347 hc_intr_mask.b.bblerr = 1;
2352 DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2355 * Program the HCCHARn register with the endpoint characteristics for
2356 * the current transfer.
2359 hcchar.b.devaddr = hc->dev_addr;
2360 hcchar.b.epnum = hc->ep_num;
2361 hcchar.b.epdir = hc->ep_is_in;
2362 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2363 hcchar.b.eptype = hc->ep_type;
2364 hcchar.b.mps = hc->max_packet;
2366 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2368 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d, Dev Addr %d, EP #%d\n",
2369 __func__, hc->hc_num, hcchar.b.devaddr, hcchar.b.epnum);
2370 DWC_DEBUGPL(DBG_HCDV, " Is In %d, Is Low Speed %d, EP Type %d, "
2371 "Max Pkt %d, Multi Cnt %d\n",
2372 hcchar.b.epdir, hcchar.b.lspddev, hcchar.b.eptype,
2373 hcchar.b.mps, hcchar.b.multicnt);
2376 * Program the HCSPLIT register for SPLITs
2380 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
2382 hc->complete_split ? "CSPLIT" : "SSPLIT");
2383 hcsplt.b.compsplt = hc->complete_split;
2384 hcsplt.b.xactpos = hc->xact_pos;
2385 hcsplt.b.hubaddr = hc->hub_addr;
2386 hcsplt.b.prtaddr = hc->port_addr;
2387 DWC_DEBUGPL(DBG_HCDV, "\t comp split %d\n", hc->complete_split);
2388 DWC_DEBUGPL(DBG_HCDV, "\t xact pos %d\n", hc->xact_pos);
2389 DWC_DEBUGPL(DBG_HCDV, "\t hub addr %d\n", hc->hub_addr);
2390 DWC_DEBUGPL(DBG_HCDV, "\t port addr %d\n", hc->port_addr);
2391 DWC_DEBUGPL(DBG_HCDV, "\t is_in %d\n", hc->ep_is_in);
2392 DWC_DEBUGPL(DBG_HCDV, "\t Max Pkt: %d\n", hcchar.b.mps);
2393 DWC_DEBUGPL(DBG_HCDV, "\t xferlen: %d\n", hc->xfer_len);
2395 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2400 * Attempts to halt a host channel. This function should only be called in
2401 * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2402 * normal circumstances in DMA mode, the controller halts the channel when the
2403 * transfer is complete or a condition occurs that requires application
2406 * In slave mode, checks for a free request queue entry, then sets the Channel
2407 * Enable and Channel Disable bits of the Host Channel Characteristics
2408 * register of the specified channel to intiate the halt. If there is no free
2409 * request queue entry, sets only the Channel Disable bit of the HCCHARn
2410 * register to flush requests for this channel. In the latter case, sets a
2411 * flag to indicate that the host channel needs to be halted when a request
2412 * queue slot is open.
2414 * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2415 * HCCHARn register. The controller ensures there is space in the request
2416 * queue before submitting the halt request.
2418 * Some time may elapse before the core flushes any posted requests for this
2419 * host channel and halts. The Channel Halted interrupt handler completes the
2420 * deactivation of the host channel.
2422 * @param core_if Controller register interface.
2423 * @param hc Host channel to halt.
2424 * @param halt_status Reason for halting the channel.
2426 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
2427 dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
2429 gnptxsts_data_t nptxsts;
2430 hptxsts_data_t hptxsts;
2431 hcchar_data_t hcchar;
2432 dwc_otg_hc_regs_t *hc_regs;
2433 dwc_otg_core_global_regs_t *global_regs;
2434 dwc_otg_host_global_regs_t *host_global_regs;
2436 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2437 global_regs = core_if->core_global_regs;
2438 host_global_regs = core_if->host_if->host_global_regs;
2440 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
2441 "halt_status = %d\n", halt_status);
2443 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2444 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2446 * Disable all channel interrupts except Ch Halted. The QTD
2447 * and QH state associated with this transfer has been cleared
2448 * (in the case of URB_DEQUEUE), so the channel needs to be
2449 * shut down carefully to prevent crashes.
2451 hcintmsk_data_t hcintmsk;
2453 hcintmsk.b.chhltd = 1;
2454 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
2457 * Make sure no other interrupts besides halt are currently
2458 * pending. Handling another interrupt could cause a crash due
2459 * to the QTD and QH state.
2461 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
2464 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2465 * even if the channel was already halted for some other
2468 hc->halt_status = halt_status;
2470 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2471 if (hcchar.b.chen == 0) {
2473 * The channel is either already halted or it hasn't
2474 * started yet. In DMA mode, the transfer may halt if
2475 * it finishes normally or a condition occurs that
2476 * requires driver intervention. Don't want to halt
2477 * the channel again. In either Slave or DMA mode,
2478 * it's possible that the transfer has been assigned
2479 * to a channel, but not started yet when an URB is
2480 * dequeued. Don't want to halt a channel that hasn't
2486 if (hc->halt_pending) {
2488 * A halt has already been issued for this channel. This might
2489 * happen when a transfer is aborted by a higher level in
2494 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2495 __func__, hc->hc_num);
2501 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2503 /* No need to set the bit in DDMA for disabling the channel */
2504 //TODO check it everywhere channel is disabled
2505 if (!core_if->core_params->dma_desc_enable)
2509 if (!core_if->dma_enable) {
2510 /* Check for space in the request queue to issue the halt. */
2511 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2512 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2513 nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
2514 if (nptxsts.b.nptxqspcavail == 0) {
2519 DWC_READ_REG32(&host_global_regs->hptxsts);
2520 if ((hptxsts.b.ptxqspcavail == 0)
2521 || (core_if->queuing_high_bandwidth)) {
2526 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2528 hc->halt_status = halt_status;
2530 if (hcchar.b.chen) {
2531 hc->halt_pending = 1;
2532 hc->halt_on_queue = 0;
2534 hc->halt_on_queue = 1;
2537 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2538 DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
2539 DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
2540 DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
2541 DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
2547 * Clears the transfer state for a host channel. This function is normally
2548 * called after a transfer is done and the host channel is being released.
2550 * @param core_if Programming view of DWC_otg controller.
2551 * @param hc Identifies the host channel to clean up.
2553 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2555 dwc_otg_hc_regs_t *hc_regs;
2557 hc->xfer_started = 0;
2560 * Clear channel interrupt enables and any unhandled channel interrupt
2563 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2564 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
2565 DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
2567 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
2572 * Sets the channel property that indicates in which frame a periodic transfer
2573 * should occur. This is always set to the _next_ frame. This function has no
2574 * effect on non-periodic transfers.
2576 * @param core_if Programming view of DWC_otg controller.
2577 * @param hc Identifies the host channel to set up and its properties.
2578 * @param hcchar Current value of the HCCHAR register for the specified host
2581 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
2582 dwc_hc_t * hc, hcchar_data_t * hcchar)
2584 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2585 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2588 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
2590 /* 1 if _next_ frame is odd, 0 if it's even */
2591 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2593 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
2594 && !hc->complete_split) {
2595 switch (hfnum.b.frnum & 0x7) {
2597 core_if->hfnum_7_samples++;
2598 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2601 core_if->hfnum_0_samples++;
2602 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2605 core_if->hfnum_other_samples++;
2606 core_if->hfnum_other_frrem_accum +=
2616 void hc_xfer_timeout(void *ptr)
2618 hc_xfer_info_t *xfer_info = NULL;
2622 xfer_info = (hc_xfer_info_t *) ptr;
2624 if (!xfer_info->hc) {
2625 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
2629 hc_num = xfer_info->hc->hc_num;
2630 DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2631 DWC_WARN(" start_hcchar_val 0x%08x\n",
2632 xfer_info->core_if->start_hcchar_val[hc_num]);
2636 void ep_xfer_timeout(void *ptr)
2638 ep_xfer_info_t *xfer_info = NULL;
2640 dctl_data_t dctl = {.d32 = 0 };
2641 gintsts_data_t gintsts = {.d32 = 0 };
2642 gintmsk_data_t gintmsk = {.d32 = 0 };
2645 xfer_info = (ep_xfer_info_t *) ptr;
2647 if (!xfer_info->ep) {
2648 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
2652 ep_num = xfer_info->ep->num;
2653 DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
2654 /* Put the sate to 2 as it was time outed */
2655 xfer_info->state = 2;
2658 DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl);
2660 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts);
2662 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk);
2664 if (!gintmsk.b.goutnakeff) {
2666 gintmsk.b.goutnakeff = 1;
2667 DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk,
2672 if (!gintsts.b.goutnakeff) {
2673 dctl.b.sgoutnak = 1;
2675 DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl,
2680 void set_pid_isoc(dwc_hc_t * hc)
2682 /* Set up the initial PID for the transfer. */
2683 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2685 if (hc->multi_count == 1) {
2686 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2687 } else if (hc->multi_count == 2) {
2688 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2690 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2693 if (hc->multi_count == 1) {
2694 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2696 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2700 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2705 * This function does the setup for a data transfer for a host channel and
2706 * starts the transfer. May be called in either Slave mode or DMA mode. In
2707 * Slave mode, the caller must ensure that there is sufficient space in the
2708 * request queue and Tx Data FIFO.
2710 * For an OUT transfer in Slave mode, it loads a data packet into the
2711 * appropriate FIFO. If necessary, additional data packets will be loaded in
2714 * For an IN transfer in Slave mode, a data packet is requested. The data
2715 * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2716 * additional data packets are requested in the Host ISR.
2718 * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2719 * register along with a packet count of 1 and the channel is enabled. This
2720 * causes a single PING transaction to occur. Other fields in HCTSIZ are
2721 * simply set to 0 since no data transfer occurs in this case.
2723 * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2724 * all the information required to perform the subsequent data transfer. In
2725 * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2726 * controller performs the entire PING protocol, then starts the data
2729 * @param core_if Programming view of DWC_otg controller.
2730 * @param hc Information needed to initialize the host channel. The xfer_len
2731 * value may be reduced to accommodate the max widths of the XferSize and
2732 * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2733 * to reflect the final xfer_len value.
2735 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2737 hcchar_data_t hcchar;
2738 hctsiz_data_t hctsiz;
2739 uint16_t num_packets;
2740 uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
2741 uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
2742 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2747 if (!core_if->dma_enable) {
2748 dwc_otg_hc_do_ping(core_if, hc);
2749 hc->xfer_started = 1;
2759 if (hc->complete_split && !hc->ep_is_in) {
2760 /* For CSPLIT OUT Transfer, set the size to 0 so the
2761 * core doesn't expect any data written to the FIFO */
2763 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
2764 hc->xfer_len = hc->max_packet;
2765 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
2769 hctsiz.b.xfersize = hc->xfer_len;
2772 * Ensure that the transfer length and packet count will fit
2773 * in the widths allocated for them in the HCTSIZn register.
2775 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2776 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2778 * Make sure the transfer size is no larger than one
2779 * (micro)frame's worth of data. (A check was done
2780 * when the periodic transfer was accepted to ensure
2781 * that a (micro)frame's worth of data can be
2782 * programmed into a channel.)
2784 uint32_t max_periodic_len =
2785 hc->multi_count * hc->max_packet;
2786 if (hc->xfer_len > max_periodic_len) {
2787 hc->xfer_len = max_periodic_len;
2790 } else if (hc->xfer_len > max_hc_xfer_size) {
2791 /* Make sure that xfer_len is a multiple of max packet size. */
2792 hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
2795 if (hc->xfer_len > 0) {
2797 (hc->xfer_len + hc->max_packet -
2798 1) / hc->max_packet;
2799 if (num_packets > max_hc_pkt_count) {
2800 num_packets = max_hc_pkt_count;
2801 hc->xfer_len = num_packets * hc->max_packet;
2804 /* Need 1 packet for transfer length of 0. */
2809 /* Always program an integral # of max packets for IN transfers. */
2810 hc->xfer_len = num_packets * hc->max_packet;
2813 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2814 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2816 * Make sure that the multi_count field matches the
2817 * actual transfer length.
2819 hc->multi_count = num_packets;
2822 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2825 hctsiz.b.xfersize = hc->xfer_len;
2828 hc->start_pkt_count = num_packets;
2829 hctsiz.b.pktcnt = num_packets;
2830 hctsiz.b.pid = hc->data_pid_start;
2831 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2833 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2834 DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
2835 DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
2836 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2838 if (core_if->dma_enable) {
2840 if (hc->align_buff) {
2841 dma_addr = hc->align_buff;
2843 dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
2845 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
2848 /* Start the split */
2850 hcsplt_data_t hcsplt;
2851 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
2852 hcsplt.b.spltena = 1;
2853 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
2856 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2857 hcchar.b.multicnt = hc->multi_count;
2858 hc_set_even_odd_frame(core_if, hc, &hcchar);
2860 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2861 if (hcchar.b.chdis) {
2862 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2863 __func__, hc->hc_num, hcchar.d32);
2867 /* Set host channel enable after all other setup is complete. */
2870 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2872 hc->xfer_started = 1;
2875 if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
2876 /* Load OUT packet into the appropriate Tx FIFO. */
2877 dwc_otg_hc_write_packet(core_if, hc);
2880 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2881 DWC_DEBUGPL(DBG_HCDV, "transfer %d from core_if %p\n",
2882 hc->hc_num, core_if);//GRAYG
2883 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2884 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2886 /* Start a timer for this transfer. */
2887 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2893 * This function does the setup for a data transfer for a host channel
2894 * and starts the transfer in Descriptor DMA mode.
2896 * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set.
2897 * Sets PID and NTD values. For periodic transfers
2898 * initializes SCHED_INFO field with micro-frame bitmap.
2900 * Initializes HCDMA register with descriptor list address and CTD value
2901 * then starts the transfer via enabling the channel.
2903 * @param core_if Programming view of DWC_otg controller.
2904 * @param hc Information needed to initialize the host channel.
2906 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2908 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2909 hcchar_data_t hcchar;
2910 hctsiz_data_t hctsiz;
2916 hctsiz.b_ddma.dopng = 1;
2918 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2921 /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
2922 hctsiz.b_ddma.pid = hc->data_pid_start;
2923 hctsiz.b_ddma.ntd = hc->ntd - 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
2924 hctsiz.b_ddma.schinfo = hc->schinfo; /* Non-zero only for high-speed interrupt endpoints */
2926 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2927 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2928 DWC_DEBUGPL(DBG_HCDV, " NTD: %d\n", hctsiz.b_ddma.ntd);
2930 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2933 hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
2935 /* Always start from first descriptor. */
2937 DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
2939 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2940 hcchar.b.multicnt = hc->multi_count;
2943 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2944 if (hcchar.b.chdis) {
2945 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2946 __func__, hc->hc_num, hcchar.d32);
2950 /* Set host channel enable after all other setup is complete. */
2954 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2956 hc->xfer_started = 1;
2960 if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
2961 && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
2962 DWC_DEBUGPL(DBG_HCDV, "DMA transfer %d from core_if %p\n",
2963 hc->hc_num, core_if);//GRAYG
2964 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2965 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2966 /* Start a timer for this transfer. */
2967 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2974 * This function continues a data transfer that was started by previous call
2975 * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
2976 * sufficient space in the request queue and Tx Data FIFO. This function
2977 * should only be called in Slave mode. In DMA mode, the controller acts
2978 * autonomously to complete transfers programmed to a host channel.
2980 * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
2981 * if there is any data remaining to be queued. For an IN transfer, another
2982 * data packet is always requested. For the SETUP phase of a control transfer,
2983 * this function does nothing.
2985 * @return 1 if a new request is queued, 0 if no more requests are required
2986 * for this transfer.
2988 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2990 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2993 /* SPLITs always queue just once per channel */
2995 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2996 /* SETUPs are queued only once since they can't be NAKed. */
2998 } else if (hc->ep_is_in) {
3000 * Always queue another request for other IN transfers. If
3001 * back-to-back INs are issued and NAKs are received for both,
3002 * the driver may still be processing the first NAK when the
3003 * second NAK is received. When the interrupt handler clears
3004 * the NAK interrupt for the first NAK, the second NAK will
3005 * not be seen. So we can't depend on the NAK interrupt
3006 * handler to requeue a NAKed request. Instead, IN requests
3007 * are issued each time this function is called. When the
3008 * transfer completes, the extra requests for the channel will
3011 hcchar_data_t hcchar;
3012 dwc_otg_hc_regs_t *hc_regs =
3013 core_if->host_if->hc_regs[hc->hc_num];
3015 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3016 hc_set_even_odd_frame(core_if, hc, &hcchar);
3019 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
3021 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3025 /* OUT transfers. */
3026 if (hc->xfer_count < hc->xfer_len) {
3027 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3028 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3029 hcchar_data_t hcchar;
3030 dwc_otg_hc_regs_t *hc_regs;
3031 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3032 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3033 hc_set_even_odd_frame(core_if, hc, &hcchar);
3036 /* Load OUT packet into the appropriate Tx FIFO. */
3037 dwc_otg_hc_write_packet(core_if, hc);
3047 * Starts a PING transfer. This function should only be called in Slave mode.
3048 * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
3050 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3052 hcchar_data_t hcchar;
3053 hctsiz_data_t hctsiz;
3054 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3056 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3060 hctsiz.b.pktcnt = 1;
3061 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3063 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3066 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3070 * This function writes a packet into the Tx FIFO associated with the Host
3071 * Channel. For a channel associated with a non-periodic EP, the non-periodic
3072 * Tx FIFO is written. For a channel associated with a periodic EP, the
3073 * periodic Tx FIFO is written. This function should only be called in Slave
3076 * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
3077 * then number of bytes written to the Tx FIFO.
3079 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3082 uint32_t remaining_count;
3083 uint32_t byte_count;
3084 uint32_t dword_count;
3086 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
3087 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
3089 remaining_count = hc->xfer_len - hc->xfer_count;
3090 if (remaining_count > hc->max_packet) {
3091 byte_count = hc->max_packet;
3093 byte_count = remaining_count;
3096 dword_count = (byte_count + 3) / 4;
3098 if ((((unsigned long)data_buff) & 0x3) == 0) {
3099 /* xfer_buff is DWORD aligned. */
3100 for (i = 0; i < dword_count; i++, data_buff++) {
3101 DWC_WRITE_REG32(data_fifo, *data_buff);
3104 /* xfer_buff is not DWORD aligned. */
3105 for (i = 0; i < dword_count; i++, data_buff++) {
3108 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
3109 16 | data_buff[3] << 24);
3110 DWC_WRITE_REG32(data_fifo, data);
3114 hc->xfer_count += byte_count;
3115 hc->xfer_buff += byte_count;
3119 * Gets the current USB frame number. This is the frame number from the last
3122 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
3125 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
3127 /* read current frame/microframe number from DSTS register */
3128 return dsts.b.soffn;
3132 * Calculates and gets the frame Interval value of HFIR register according PHY
3133 * type and speed.The application can modify a value of HFIR register only after
3134 * the Port Enable bit of the Host Port Control and Status register
3135 * (HPRT.PrtEnaPort) has been set.
3138 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
3140 gusbcfg_data_t usbcfg;
3141 hwcfg2_data_t hwcfg2;
3143 int clock = 60; // default value
3144 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
3145 hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
3146 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
3147 if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3149 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
3151 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3152 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3154 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3155 !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3157 if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3158 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3160 if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
3162 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
3164 if (hprt0.b.prtspd == 0)
3165 /* High speed case */
3166 return 125 * clock - 1;
3169 return 1000 * clock - 1;
3173 * This function reads a setup packet from the Rx FIFO into the destination
3174 * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3175 * Interrupt routine when a SETUP packet has been received in Slave mode.
3177 * @param core_if Programming view of DWC_otg controller.
3178 * @param dest Destination buffer for packet data.
3180 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
3182 device_grxsts_data_t status;
3183 /* Get the 8 bytes of a setup transaction data */
3185 /* Pop 2 DWORDS off the receive data FIFO into memory */
3186 dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
3187 dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
3188 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
3190 DWC_READ_REG32(&core_if->core_global_regs->grxstsp);
3191 DWC_DEBUGPL(DBG_ANY,
3192 "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n",
3193 status.b.epnum, status.b.bcnt, status.b.pktsts,
3194 status.b.fn, status.b.fn);
3199 * This function enables EP0 OUT to receive SETUP packets and configures EP0
3200 * IN for transmitting packets. It is normally called when the
3201 * "Enumeration Done" interrupt occurs.
3203 * @param core_if Programming view of DWC_otg controller.
3204 * @param ep The EP0 data.
3206 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3208 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3210 depctl_data_t diepctl;
3211 depctl_data_t doepctl;
3212 dctl_data_t dctl = {.d32 = 0 };
3214 ep->stp_rollover = 0;
3215 /* Read the Device Status and Endpoint 0 Control registers */
3216 dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
3217 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
3218 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
3220 /* Set the MPS of the IN EP based on the enumeration speed */
3221 switch (dsts.b.enumspd) {
3222 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
3223 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
3224 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
3225 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
3227 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3228 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3232 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3234 /* Enable OUT EP for receive */
3235 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
3236 doepctl.b.epena = 1;
3237 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
3240 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
3241 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
3242 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
3243 DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
3245 dctl.b.cgnpinnak = 1;
3247 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3248 DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
3249 DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
3254 * This function activates an EP. The Device EP control register for
3255 * the EP is configured as defined in the ep structure. Note: This
3256 * function is not used for EP0.
3258 * @param core_if Programming view of DWC_otg controller.
3259 * @param ep The EP to activate.
3261 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3263 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3264 depctl_data_t depctl;
3265 volatile uint32_t *addr;
3266 daint_data_t daintmsk = {.d32 = 0 };
3270 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3271 (ep->is_in ? "IN" : "OUT"));
3273 #ifdef DWC_UTE_PER_IO
3274 ep->xiso_frame_num = 0xFFFFFFFF;
3275 ep->xiso_active_xfers = 0;
3276 ep->xiso_queued_xfers = 0;
3278 /* Read DEPCTLn register */
3279 if (ep->is_in == 1) {
3280 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
3281 daintmsk.ep.in = 1 << ep->num;
3283 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3284 daintmsk.ep.out = 1 << ep->num;
3287 /* If the EP is already active don't change the EP Control
3289 depctl.d32 = DWC_READ_REG32(addr);
3290 if (!depctl.b.usbactep) {
3291 depctl.b.mps = ep->maxpacket;
3292 depctl.b.eptype = ep->type;
3293 depctl.b.txfnum = ep->tx_fifo_num;
3295 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3296 depctl.b.setd0pid = 1; // ???
3298 depctl.b.setd0pid = 1;
3300 depctl.b.usbactep = 1;
3302 /* Update nextep_seq array and EPMSCNT in DCFG*/
3303 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) { // NP IN EP
3304 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3305 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
3308 core_if->nextep_seq[i] = ep->num;
3309 core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
3310 depctl.b.nextep = core_if->nextep_seq[ep->num];
3311 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
3313 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3315 DWC_DEBUGPL(DBG_PCDV,
3316 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3317 __func__, core_if->first_in_nextep_seq);
3318 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
3319 DWC_DEBUGPL(DBG_PCDV, "%2d\n",
3320 core_if->nextep_seq[i]);
3326 DWC_WRITE_REG32(addr, depctl.d32);
3327 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
3330 /* Enable the Interrupt for this EP */
3331 if (core_if->multiproc_int_enable) {
3332 if (ep->is_in == 1) {
3333 diepmsk_data_t diepmsk = {.d32 = 0 };
3334 diepmsk.b.xfercompl = 1;
3335 diepmsk.b.timeout = 1;
3336 diepmsk.b.epdisabled = 1;
3337 diepmsk.b.ahberr = 1;
3338 diepmsk.b.intknepmis = 1;
3339 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
3340 diepmsk.b.intknepmis = 0;
3341 diepmsk.b.txfifoundrn = 1; //?????
3342 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3349 if (core_if->dma_desc_enable) {
3354 if (core_if->dma_enable) {
3358 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3359 diepeachintmsk[ep->num], diepmsk.d32);
3362 doepmsk_data_t doepmsk = {.d32 = 0 };
3363 doepmsk.b.xfercompl = 1;
3364 doepmsk.b.ahberr = 1;
3365 doepmsk.b.epdisabled = 1;
3366 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3367 doepmsk.b.outtknepdis = 1;
3371 if (core_if->dma_desc_enable) {
3376 doepmsk.b.babble = 1;
3380 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3381 doepeachintmsk[ep->num], doepmsk.d32);
3383 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
3386 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3388 diepmsk_data_t diepmsk = {.d32 = 0 };
3390 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
3392 doepmsk_data_t doepmsk = {.d32 = 0 };
3393 doepmsk.b.outtknepdis = 1;
3394 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
3397 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
3401 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
3402 DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
3404 ep->stall_clear_flag = 0;
3410 * This function deactivates an EP. This is done by clearing the USB Active
3411 * EP bit in the Device EP control register. Note: This function is not used
3412 * for EP0. EP0 cannot be deactivated.
3414 * @param core_if Programming view of DWC_otg controller.
3415 * @param ep The EP to deactivate.
3417 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3419 depctl_data_t depctl = {.d32 = 0 };
3420 volatile uint32_t *addr;
3421 daint_data_t daintmsk = {.d32 = 0 };
3425 #ifdef DWC_UTE_PER_IO
3426 ep->xiso_frame_num = 0xFFFFFFFF;
3427 ep->xiso_active_xfers = 0;
3428 ep->xiso_queued_xfers = 0;
3431 /* Read DEPCTLn register */
3432 if (ep->is_in == 1) {
3433 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3434 daintmsk.ep.in = 1 << ep->num;
3436 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3437 daintmsk.ep.out = 1 << ep->num;
3440 depctl.d32 = DWC_READ_REG32(addr);
3442 depctl.b.usbactep = 0;
3444 /* Update nextep_seq array and EPMSCNT in DCFG*/
3445 if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN
3446 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3447 if (core_if->nextep_seq[i] == ep->num)
3450 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];
3451 if (core_if->first_in_nextep_seq == ep->num)
3452 core_if->first_in_nextep_seq = i;
3453 core_if->nextep_seq[ep->num] = 0xff;
3454 depctl.b.nextep = 0;
3456 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
3458 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
3461 DWC_DEBUGPL(DBG_PCDV,
3462 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3463 __func__, core_if->first_in_nextep_seq);
3464 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
3465 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
3470 depctl.b.txfnum = 0;
3472 if (core_if->dma_desc_enable)
3475 DWC_WRITE_REG32(addr, depctl.d32);
3476 depctl.d32 = DWC_READ_REG32(addr);
3477 if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC
3478 && depctl.b.epena) {
3479 depctl_data_t depctl = {.d32 = 0};
3481 diepint_data_t diepint = {.d32 = 0};
3484 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3485 diepctl, depctl.d32);
3489 DWC_READ_REG32(&core_if->
3490 dev_if->in_ep_regs[ep->num]->
3492 } while (!diepint.b.inepnakeff);
3493 diepint.b.inepnakeff = 1;
3494 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3495 diepint, diepint.d32);
3498 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3499 diepctl, depctl.d32);
3503 DWC_READ_REG32(&core_if->
3504 dev_if->in_ep_regs[ep->num]->
3506 } while (!diepint.b.epdisabled);
3507 diepint.b.epdisabled = 1;
3508 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3509 diepint, diepint.d32);
3511 dctl_data_t dctl = {.d32 = 0};
3512 gintmsk_data_t gintsts = {.d32 = 0};
3513 doepint_data_t doepint = {.d32 = 0};
3514 dctl.b.sgoutnak = 1;
3515 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3519 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
3520 } while (!gintsts.b.goutnakeff);
3522 gintsts.b.goutnakeff = 1;
3523 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
3528 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
3532 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
3533 out_ep_regs[ep->num]->doepint);
3534 } while (!doepint.b.epdisabled);
3536 doepint.b.epdisabled = 1;
3537 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
3540 dctl.b.cgoutnak = 1;
3541 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
3545 /* Disable the Interrupt for this EP */
3546 if (core_if->multiproc_int_enable) {
3547 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
3550 if (ep->is_in == 1) {
3551 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3552 diepeachintmsk[ep->num], 0);
3554 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3555 doepeachintmsk[ep->num], 0);
3558 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
3565 * This function initializes dma descriptor chain.
3567 * @param core_if Programming view of DWC_otg controller.
3568 * @param ep The EP to start the transfer on.
3570 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3572 dwc_otg_dev_dma_desc_t *dma_desc;
3576 unsigned maxxfer_local, total_len;
3578 if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR &&
3579 (ep->maxpacket%4)) {
3580 maxxfer_local = ep->maxpacket;
3581 total_len = ep->xfer_len;
3583 maxxfer_local = ep->maxxfer;
3584 total_len = ep->total_len;
3587 ep->desc_cnt = (total_len / maxxfer_local) +
3588 ((total_len % maxxfer_local) ? 1 : 0);
3593 if (ep->desc_cnt > MAX_DMA_DESC_CNT)
3594 ep->desc_cnt = MAX_DMA_DESC_CNT;
3596 dma_desc = ep->desc_addr;
3597 if (maxxfer_local == ep->maxpacket) {
3598 if ((total_len % maxxfer_local) &&
3599 (total_len/maxxfer_local < MAX_DMA_DESC_CNT)) {
3600 xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
3601 (total_len % maxxfer_local);
3603 xfer_est = ep->desc_cnt * maxxfer_local;
3605 xfer_est = total_len;
3607 for (i = 0; i < ep->desc_cnt; ++i) {
3608 /** DMA Descriptor Setup */
3609 if (xfer_est > maxxfer_local) {
3610 dma_desc->status.b.bs = BS_HOST_BUSY;
3611 dma_desc->status.b.l = 0;
3612 dma_desc->status.b.ioc = 0;
3613 dma_desc->status.b.sp = 0;
3614 dma_desc->status.b.bytes = maxxfer_local;
3615 dma_desc->buf = ep->dma_addr + offset;
3616 dma_desc->status.b.sts = 0;
3617 dma_desc->status.b.bs = BS_HOST_READY;
3619 xfer_est -= maxxfer_local;
3620 offset += maxxfer_local;
3622 dma_desc->status.b.bs = BS_HOST_BUSY;
3623 dma_desc->status.b.l = 1;
3624 dma_desc->status.b.ioc = 1;
3626 dma_desc->status.b.sp =
3628 ep->maxpacket) ? 1 : ((ep->
3630 dma_desc->status.b.bytes = xfer_est;
3632 if (maxxfer_local == ep->maxpacket)
3633 dma_desc->status.b.bytes = xfer_est;
3635 dma_desc->status.b.bytes =
3636 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
3639 dma_desc->buf = ep->dma_addr + offset;
3640 dma_desc->status.b.sts = 0;
3641 dma_desc->status.b.bs = BS_HOST_READY;
3647 * This function is called when to write ISOC data into appropriate dedicated
3650 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
3652 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3653 dwc_otg_dev_in_ep_regs_t *ep_regs;
3654 dtxfsts_data_t txstatus = {.d32 = 0 };
3656 int epnum = dwc_ep->num;
3659 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
3661 ep_regs = core_if->dev_if->in_ep_regs[epnum];
3663 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3665 if (len > dwc_ep->maxpacket) {
3666 len = dwc_ep->maxpacket;
3669 dwords = (len + 3) / 4;
3671 /* While there is space in the queue and space in the FIFO and
3672 * More data to tranfer, Write packets to the Tx FIFO */
3673 txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3674 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
3676 while (txstatus.b.txfspcavail > dwords &&
3677 dwc_ep->xfer_count < dwc_ep->xfer_len && dwc_ep->xfer_len != 0) {
3678 /* Write the FIFO */
3679 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
3681 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3682 if (len > dwc_ep->maxpacket) {
3683 len = dwc_ep->maxpacket;
3686 dwords = (len + 3) / 4;
3688 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3689 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
3693 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
3694 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
3699 * This function does the setup for a data transfer for an EP and
3700 * starts the transfer. For an IN transfer, the packets will be
3701 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3702 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3704 * @param core_if Programming view of DWC_otg controller.
3705 * @param ep The EP to start the transfer on.
3708 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3710 depctl_data_t depctl;
3711 deptsiz_data_t deptsiz;
3712 gintmsk_data_t intr_mask = {.d32 = 0 };
3714 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3715 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3716 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
3717 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
3718 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
3721 if (ep->is_in == 1) {
3722 dwc_otg_dev_in_ep_regs_t *in_regs =
3723 core_if->dev_if->in_ep_regs[ep->num];
3725 gnptxsts_data_t gtxstatus;
3728 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
3730 if (core_if->en_multiple_tx_fifo == 0
3731 && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) {
3733 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3738 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
3739 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
3741 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3742 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3743 ep->maxxfer : (ep->total_len - ep->xfer_len);
3745 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
3746 MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3749 /* Zero Length Packet? */
3750 if ((ep->xfer_len - ep->xfer_count) == 0) {
3751 deptsiz.b.xfersize = 0;
3752 deptsiz.b.pktcnt = 1;
3754 /* Program the transfer size and packet count
3755 * as follows: xfersize = N * maxpacket +
3756 * short_packet pktcnt = N + (short_packet
3759 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3761 (ep->xfer_len - ep->xfer_count - 1 +
3762 ep->maxpacket) / ep->maxpacket;
3763 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3764 deptsiz.b.pktcnt = MAX_PKT_CNT;
3765 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
3767 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3768 deptsiz.b.mc = deptsiz.b.pktcnt;
3771 /* Write the DMA register */
3772 if (core_if->dma_enable) {
3773 if (core_if->dma_desc_enable == 0) {
3774 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
3776 DWC_WRITE_REG32(&in_regs->dieptsiz,
3778 DWC_WRITE_REG32(&(in_regs->diepdma),
3779 (uint32_t) ep->dma_addr);
3782 /* The descriptor chain should be already initialized by now */
3783 if (ep->buff_mode != BM_STANDARD) {
3784 DWC_WRITE_REG32(&in_regs->diepdma,
3785 ep->descs_dma_addr);
3788 init_dma_desc_chain(core_if, ep);
3789 /** DIEPDMAn Register write */
3790 DWC_WRITE_REG32(&in_regs->diepdma,
3797 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
3798 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
3800 * Enable the Non-Periodic Tx FIFO empty interrupt,
3801 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3802 * the data will be written into the fifo by the ISR.
3804 if (core_if->en_multiple_tx_fifo == 0) {
3805 intr_mask.b.nptxfempty = 1;
3807 (&core_if->core_global_regs->gintmsk,
3808 intr_mask.d32, intr_mask.d32);
3810 /* Enable the Tx FIFO Empty Interrupt for this EP */
3811 if (ep->xfer_len > 0) {
3812 uint32_t fifoemptymsk = 0;
3813 fifoemptymsk = 1 << ep->num;
3815 (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3821 write_isoc_tx_fifo(core_if, ep);
3824 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
3825 depctl.b.nextep = core_if->nextep_seq[ep->num];
3827 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3828 dsts_data_t dsts = {.d32 = 0};
3829 if (ep->bInterval == 1) {
3831 DWC_READ_REG32(&core_if->dev_if->
3832 dev_global_regs->dsts);
3833 ep->frame_num = dsts.b.soffn + ep->bInterval;
3834 if (ep->frame_num > 0x3FFF) {
3835 ep->frm_overrun = 1;
3836 ep->frame_num &= 0x3FFF;
3838 ep->frm_overrun = 0;
3839 if (ep->frame_num & 0x1) {
3840 depctl.b.setd1pid = 1;
3842 depctl.b.setd0pid = 1;
3846 /* EP enable, IN data in FIFO */
3849 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
3853 dwc_otg_dev_out_ep_regs_t *out_regs =
3854 core_if->dev_if->out_ep_regs[ep->num];
3856 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
3857 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
3859 if (!core_if->dma_desc_enable) {
3860 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3861 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3862 ep->maxxfer : (ep->total_len - ep->xfer_len);
3864 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len
3865 - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3868 /* Program the transfer size and packet count as follows:
3871 * xfersize = N * maxpacket
3873 if ((ep->xfer_len - ep->xfer_count) == 0) {
3874 /* Zero Length Packet */
3875 deptsiz.b.xfersize = ep->maxpacket;
3876 deptsiz.b.pktcnt = 1;
3879 (ep->xfer_len - ep->xfer_count +
3880 (ep->maxpacket - 1)) / ep->maxpacket;
3881 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3882 deptsiz.b.pktcnt = MAX_PKT_CNT;
3884 if (!core_if->dma_desc_enable) {
3886 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
3888 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3891 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3892 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
3894 if (core_if->dma_enable) {
3895 if (!core_if->dma_desc_enable) {
3896 DWC_WRITE_REG32(&out_regs->doeptsiz,
3899 DWC_WRITE_REG32(&(out_regs->doepdma),
3900 (uint32_t) ep->dma_addr);
3903 /* The descriptor chain should be already initialized by now */
3904 if (ep->buff_mode != BM_STANDARD) {
3905 DWC_WRITE_REG32(&out_regs->doepdma,
3906 ep->descs_dma_addr);
3909 /** This is used for interrupt out transfers*/
3911 ep->xfer_len = ep->total_len;
3912 init_dma_desc_chain(core_if, ep);
3914 if (core_if->core_params->dev_out_nak) {
3915 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
3916 deptsiz.b.pktcnt = (ep->total_len +
3917 (ep->maxpacket - 1)) / ep->maxpacket;
3918 deptsiz.b.xfersize = ep->total_len;
3919 /* Remember initial value of doeptsiz */
3920 core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
3921 DWC_WRITE_REG32(&out_regs->doeptsiz,
3925 /** DOEPDMAn Register write */
3926 DWC_WRITE_REG32(&out_regs->doepdma,
3933 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
3936 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3937 dsts_data_t dsts = {.d32 = 0};
3938 if (ep->bInterval == 1) {
3940 DWC_READ_REG32(&core_if->dev_if->
3941 dev_global_regs->dsts);
3942 ep->frame_num = dsts.b.soffn + ep->bInterval;
3943 if (ep->frame_num > 0x3FFF) {
3944 ep->frm_overrun = 1;
3945 ep->frame_num &= 0x3FFF;
3947 ep->frm_overrun = 0;
3949 if (ep->frame_num & 0x1) {
3950 depctl.b.setd1pid = 1;
3952 depctl.b.setd0pid = 1;
3961 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
3963 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3964 DWC_READ_REG32(&out_regs->doepctl),
3965 DWC_READ_REG32(&out_regs->doeptsiz));
3966 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3967 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->
3969 DWC_READ_REG32(&core_if->core_global_regs->
3972 /* Timer is scheduling only for out bulk transfers for
3973 * "Device DDMA OUT NAK Enhancement" feature to inform user
3974 * about received data payload in case of timeout
3976 if (core_if->core_params->dev_out_nak) {
3977 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
3978 core_if->ep_xfer_info[ep->num].core_if = core_if;
3979 core_if->ep_xfer_info[ep->num].ep = ep;
3980 core_if->ep_xfer_info[ep->num].state = 1;
3982 /* Start a timer for this transfer. */
3983 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
3990 * This function setup a zero length transfer in Buffer DMA and
3991 * Slave modes for usb requests with zero field set
3993 * @param core_if Programming view of DWC_otg controller.
3994 * @param ep The EP to start the transfer on.
3997 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4000 depctl_data_t depctl;
4001 deptsiz_data_t deptsiz;
4002 gintmsk_data_t intr_mask = {.d32 = 0 };
4004 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4005 DWC_PRINTF("zero length transfer is called\n");
4008 if (ep->is_in == 1) {
4009 dwc_otg_dev_in_ep_regs_t *in_regs =
4010 core_if->dev_if->in_ep_regs[ep->num];
4012 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4013 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4015 deptsiz.b.xfersize = 0;
4016 deptsiz.b.pktcnt = 1;
4018 /* Write the DMA register */
4019 if (core_if->dma_enable) {
4020 if (core_if->dma_desc_enable == 0) {
4022 DWC_WRITE_REG32(&in_regs->dieptsiz,
4024 DWC_WRITE_REG32(&(in_regs->diepdma),
4025 (uint32_t) ep->dma_addr);
4028 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4030 * Enable the Non-Periodic Tx FIFO empty interrupt,
4031 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4032 * the data will be written into the fifo by the ISR.
4034 if (core_if->en_multiple_tx_fifo == 0) {
4035 intr_mask.b.nptxfempty = 1;
4036 DWC_MODIFY_REG32(&core_if->
4037 core_global_regs->gintmsk,
4038 intr_mask.d32, intr_mask.d32);
4040 /* Enable the Tx FIFO Empty Interrupt for this EP */
4041 if (ep->xfer_len > 0) {
4042 uint32_t fifoemptymsk = 0;
4043 fifoemptymsk = 1 << ep->num;
4044 DWC_MODIFY_REG32(&core_if->
4045 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4051 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4052 depctl.b.nextep = core_if->nextep_seq[ep->num];
4053 /* EP enable, IN data in FIFO */
4056 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4060 dwc_otg_dev_out_ep_regs_t *out_regs =
4061 core_if->dev_if->out_ep_regs[ep->num];
4063 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4064 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4066 /* Zero Length Packet */
4067 deptsiz.b.xfersize = ep->maxpacket;
4068 deptsiz.b.pktcnt = 1;
4070 if (core_if->dma_enable) {
4071 if (!core_if->dma_desc_enable) {
4072 DWC_WRITE_REG32(&out_regs->doeptsiz,
4075 DWC_WRITE_REG32(&(out_regs->doepdma),
4076 (uint32_t) ep->dma_addr);
4079 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4086 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4092 * This function does the setup for a data transfer for EP0 and starts
4093 * the transfer. For an IN transfer, the packets will be loaded into
4094 * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
4095 * unloaded from the Rx FIFO in the ISR.
4097 * @param core_if Programming view of DWC_otg controller.
4098 * @param ep The EP0 data.
4100 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4102 depctl_data_t depctl;
4103 deptsiz0_data_t deptsiz;
4104 gintmsk_data_t intr_mask = {.d32 = 0 };
4105 dwc_otg_dev_dma_desc_t *dma_desc;
4107 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4108 "xfer_buff=%p start_xfer_buff=%p \n",
4109 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
4110 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
4112 ep->total_len = ep->xfer_len;
4115 if (ep->is_in == 1) {
4116 dwc_otg_dev_in_ep_regs_t *in_regs =
4117 core_if->dev_if->in_ep_regs[0];
4119 gnptxsts_data_t gtxstatus;
4121 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4122 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4128 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4130 /* If dedicated FIFO every time flush fifo before enable ep*/
4131 if (core_if->en_multiple_tx_fifo && core_if->snpsid >= OTG_CORE_REV_3_00a)
4132 dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
4134 if (core_if->en_multiple_tx_fifo == 0
4135 && gtxstatus.b.nptxqspcavail == 0
4136 && !core_if->dma_enable) {
4138 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4139 DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
4140 DWC_READ_REG32(&in_regs->diepctl));
4141 DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
4143 deptsiz.b.xfersize, deptsiz.b.pktcnt);
4144 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4150 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4151 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4153 /* Zero Length Packet? */
4154 if (ep->xfer_len == 0) {
4155 deptsiz.b.xfersize = 0;
4156 deptsiz.b.pktcnt = 1;
4158 /* Program the transfer size and packet count
4159 * as follows: xfersize = N * maxpacket +
4160 * short_packet pktcnt = N + (short_packet
4163 if (ep->xfer_len > ep->maxpacket) {
4164 ep->xfer_len = ep->maxpacket;
4165 deptsiz.b.xfersize = ep->maxpacket;
4167 deptsiz.b.xfersize = ep->xfer_len;
4169 deptsiz.b.pktcnt = 1;
4172 DWC_DEBUGPL(DBG_PCDV,
4173 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4174 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4177 /* Write the DMA register */
4178 if (core_if->dma_enable) {
4179 if (core_if->dma_desc_enable == 0) {
4180 DWC_WRITE_REG32(&in_regs->dieptsiz,
4183 DWC_WRITE_REG32(&(in_regs->diepdma),
4184 (uint32_t) ep->dma_addr);
4186 dma_desc = core_if->dev_if->in_desc_addr;
4188 /** DMA Descriptor Setup */
4189 dma_desc->status.b.bs = BS_HOST_BUSY;
4190 dma_desc->status.b.l = 1;
4191 dma_desc->status.b.ioc = 1;
4192 dma_desc->status.b.sp =
4193 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4194 dma_desc->status.b.bytes = ep->xfer_len;
4195 dma_desc->buf = ep->dma_addr;
4196 dma_desc->status.b.sts = 0;
4197 dma_desc->status.b.bs = BS_HOST_READY;
4199 /** DIEPDMA0 Register write */
4200 DWC_WRITE_REG32(&in_regs->diepdma,
4202 dev_if->dma_in_desc_addr);
4205 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4208 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4209 depctl.b.nextep = core_if->nextep_seq[ep->num];
4210 /* EP enable, IN data in FIFO */
4213 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4216 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4217 * data will be written into the fifo by the ISR.
4219 if (!core_if->dma_enable) {
4220 if (core_if->en_multiple_tx_fifo == 0) {
4221 intr_mask.b.nptxfempty = 1;
4222 DWC_MODIFY_REG32(&core_if->
4223 core_global_regs->gintmsk,
4224 intr_mask.d32, intr_mask.d32);
4226 /* Enable the Tx FIFO Empty Interrupt for this EP */
4227 if (ep->xfer_len > 0) {
4228 uint32_t fifoemptymsk = 0;
4229 fifoemptymsk |= 1 << ep->num;
4230 DWC_MODIFY_REG32(&core_if->
4231 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4238 dwc_otg_dev_out_ep_regs_t *out_regs =
4239 core_if->dev_if->out_ep_regs[0];
4241 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4242 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4244 /* Program the transfer size and packet count as follows:
4245 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4247 /* Zero Length Packet */
4248 deptsiz.b.xfersize = ep->maxpacket;
4249 deptsiz.b.pktcnt = 1;
4250 if (core_if->snpsid >= OTG_CORE_REV_3_00a)
4251 deptsiz.b.supcnt = 3;
4253 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
4254 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4256 if (core_if->dma_enable) {
4257 if (!core_if->dma_desc_enable) {
4258 DWC_WRITE_REG32(&out_regs->doeptsiz,
4261 DWC_WRITE_REG32(&(out_regs->doepdma),
4262 (uint32_t) ep->dma_addr);
4264 dma_desc = core_if->dev_if->out_desc_addr;
4266 /** DMA Descriptor Setup */
4267 dma_desc->status.b.bs = BS_HOST_BUSY;
4268 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4269 dma_desc->status.b.mtrf = 0;
4270 dma_desc->status.b.sr = 0;
4272 dma_desc->status.b.l = 1;
4273 dma_desc->status.b.ioc = 1;
4274 dma_desc->status.b.bytes = ep->maxpacket;
4275 dma_desc->buf = ep->dma_addr;
4276 dma_desc->status.b.sts = 0;
4277 dma_desc->status.b.bs = BS_HOST_READY;
4279 /** DOEPDMA0 Register write */
4280 DWC_WRITE_REG32(&out_regs->doepdma,
4285 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4291 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
4296 * This function continues control IN transfers started by
4297 * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
4298 * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
4299 * bit for the packet count.
4301 * @param core_if Programming view of DWC_otg controller.
4302 * @param ep The EP0 data.
4304 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4306 depctl_data_t depctl;
4307 deptsiz0_data_t deptsiz;
4308 gintmsk_data_t intr_mask = {.d32 = 0 };
4309 dwc_otg_dev_dma_desc_t *dma_desc;
4311 if (ep->is_in == 1) {
4312 dwc_otg_dev_in_ep_regs_t *in_regs =
4313 core_if->dev_if->in_ep_regs[0];
4314 gnptxsts_data_t tx_status = {.d32 = 0 };
4317 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4318 /** @todo Should there be check for room in the Tx
4319 * Status Queue. If not remove the code above this comment. */
4321 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4322 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4324 /* Program the transfer size and packet count
4325 * as follows: xfersize = N * maxpacket +
4326 * short_packet pktcnt = N + (short_packet
4330 if (core_if->dma_desc_enable == 0) {
4331 deptsiz.b.xfersize =
4332 (ep->total_len - ep->xfer_count) >
4333 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4335 deptsiz.b.pktcnt = 1;
4336 if (core_if->dma_enable == 0) {
4337 ep->xfer_len += deptsiz.b.xfersize;
4339 ep->xfer_len = deptsiz.b.xfersize;
4341 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4344 (ep->total_len - ep->xfer_count) >
4345 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4348 dma_desc = core_if->dev_if->in_desc_addr;
4350 /** DMA Descriptor Setup */
4351 dma_desc->status.b.bs = BS_HOST_BUSY;
4352 dma_desc->status.b.l = 1;
4353 dma_desc->status.b.ioc = 1;
4354 dma_desc->status.b.sp =
4355 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4356 dma_desc->status.b.bytes = ep->xfer_len;
4357 dma_desc->buf = ep->dma_addr;
4358 dma_desc->status.b.sts = 0;
4359 dma_desc->status.b.bs = BS_HOST_READY;
4361 /** DIEPDMA0 Register write */
4362 DWC_WRITE_REG32(&in_regs->diepdma,
4363 core_if->dev_if->dma_in_desc_addr);
4366 DWC_DEBUGPL(DBG_PCDV,
4367 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4368 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4371 /* Write the DMA register */
4372 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4373 if (core_if->dma_desc_enable == 0)
4374 DWC_WRITE_REG32(&(in_regs->diepdma),
4375 (uint32_t) ep->dma_addr);
4377 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4378 depctl.b.nextep = core_if->nextep_seq[ep->num];
4379 /* EP enable, IN data in FIFO */
4382 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4385 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4386 * data will be written into the fifo by the ISR.
4388 if (!core_if->dma_enable) {
4389 if (core_if->en_multiple_tx_fifo == 0) {
4390 /* First clear it from GINTSTS */
4391 intr_mask.b.nptxfempty = 1;
4392 DWC_MODIFY_REG32(&core_if->
4393 core_global_regs->gintmsk,
4394 intr_mask.d32, intr_mask.d32);
4397 /* Enable the Tx FIFO Empty Interrupt for this EP */
4398 if (ep->xfer_len > 0) {
4399 uint32_t fifoemptymsk = 0;
4400 fifoemptymsk |= 1 << ep->num;
4401 DWC_MODIFY_REG32(&core_if->
4402 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4408 dwc_otg_dev_out_ep_regs_t *out_regs =
4409 core_if->dev_if->out_ep_regs[0];
4411 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4412 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4414 /* Program the transfer size and packet count
4415 * as follows: xfersize = N * maxpacket +
4416 * short_packet pktcnt = N + (short_packet
4419 deptsiz.b.xfersize = ep->maxpacket;
4420 deptsiz.b.pktcnt = 1;
4422 if (core_if->dma_desc_enable == 0) {
4423 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4425 dma_desc = core_if->dev_if->out_desc_addr;
4427 /** DMA Descriptor Setup */
4428 dma_desc->status.b.bs = BS_HOST_BUSY;
4429 dma_desc->status.b.l = 1;
4430 dma_desc->status.b.ioc = 1;
4431 dma_desc->status.b.bytes = ep->maxpacket;
4432 dma_desc->buf = ep->dma_addr;
4433 dma_desc->status.b.sts = 0;
4434 dma_desc->status.b.bs = BS_HOST_READY;
4436 /** DOEPDMA0 Register write */
4437 DWC_WRITE_REG32(&out_regs->doepdma,
4438 core_if->dev_if->dma_out_desc_addr);
4441 DWC_DEBUGPL(DBG_PCDV,
4442 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4443 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4446 /* Write the DMA register */
4447 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4448 if (core_if->dma_desc_enable == 0)
4449 DWC_WRITE_REG32(&(out_regs->doepdma),
4450 (uint32_t) ep->dma_addr);
4454 /* EP enable, IN data in FIFO */
4457 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4463 void dump_msg(const u8 * buf, unsigned int length)
4465 unsigned int start, num, i;
4471 while (length > 0) {
4472 num = length < 16u ? length : 16u;
4474 for (i = 0; i < num; ++i) {
4477 DWC_SPRINTF(p, " %02x", buf[i]);
4481 DWC_PRINTF("%6x: %s\n", start, line);
4488 static inline void dump_msg(const u8 * buf, unsigned int length)
4494 * This function writes a packet into the Tx FIFO associated with the
4495 * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
4496 * periodic EPs the periodic Tx FIFO associated with the EP is written
4497 * with all packets for the next micro-frame.
4499 * @param core_if Programming view of DWC_otg controller.
4500 * @param ep The EP to write packet for.
4501 * @param dma Indicates if DMA is being used.
4503 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
4507 * The buffer is padded to DWORD on a per packet basis in
4508 * slave/dma mode if the MPS is not DWORD aligned. The last
4509 * packet, if short, is also padded to a multiple of DWORD.
4511 * ep->xfer_buff always starts DWORD aligned in memory and is a
4512 * multiple of DWORD in length
4514 * ep->xfer_len can be any number of bytes
4516 * ep->xfer_count is a multiple of ep->maxpacket until the last
4519 * FIFO access is DWORD */
4522 uint32_t byte_count;
4523 uint32_t dword_count;
4525 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
4527 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
4529 if (ep->xfer_count >= ep->xfer_len) {
4530 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4534 /* Find the byte length of the packet either short packet or MPS */
4535 if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
4536 byte_count = ep->xfer_len - ep->xfer_count;
4538 byte_count = ep->maxpacket;
4541 /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4542 * is not a multiple of DWORD */
4543 dword_count = (byte_count + 3) / 4;
4546 dump_msg(ep->xfer_buff, byte_count);
4549 /**@todo NGS Where are the Periodic Tx FIFO addresses
4550 * intialized? What should this be? */
4552 fifo = core_if->data_fifo[ep->num];
4554 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
4555 fifo, data_buff, *data_buff, byte_count);
4558 for (i = 0; i < dword_count; i++, data_buff++) {
4559 DWC_WRITE_REG32(fifo, *data_buff);
4563 ep->xfer_count += byte_count;
4564 ep->xfer_buff += byte_count;
4565 ep->dma_addr += byte_count;
4571 * @param core_if Programming view of DWC_otg controller.
4572 * @param ep The EP to set the stall on.
4574 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4576 depctl_data_t depctl;
4577 volatile uint32_t *depctl_addr;
4579 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4580 (ep->is_in ? "IN" : "OUT"));
4582 if (ep->is_in == 1) {
4583 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4584 depctl.d32 = DWC_READ_REG32(depctl_addr);
4586 /* set the disable and stall bits */
4587 if (depctl.b.epena) {
4591 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4593 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4594 depctl.d32 = DWC_READ_REG32(depctl_addr);
4596 /* set the stall bit */
4598 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4601 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4607 * Clear the EP STALL.
4609 * @param core_if Programming view of DWC_otg controller.
4610 * @param ep The EP to clear stall from.
4612 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4614 depctl_data_t depctl;
4615 volatile uint32_t *depctl_addr;
4617 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4618 (ep->is_in ? "IN" : "OUT"));
4620 if (ep->is_in == 1) {
4621 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4623 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4626 depctl.d32 = DWC_READ_REG32(depctl_addr);
4628 /* clear the stall bits */
4632 * USB Spec 9.4.5: For endpoints using data toggle, regardless
4633 * of whether an endpoint has the Halt feature set, a
4634 * ClearFeature(ENDPOINT_HALT) request always results in the
4635 * data toggle being reinitialized to DATA0.
4637 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4638 ep->type == DWC_OTG_EP_TYPE_BULK) {
4639 depctl.b.setd0pid = 1; /* DATA0 */
4642 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4643 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4648 * This function reads a packet from the Rx FIFO into the destination
4649 * buffer. To read SETUP data use dwc_otg_read_setup_packet.
4651 * @param core_if Programming view of DWC_otg controller.
4652 * @param dest Destination buffer for the packet.
4653 * @param bytes Number of bytes to copy to the destination.
4655 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
4656 uint8_t * dest, uint16_t bytes)
4659 int word_count = (bytes + 3) / 4;
4661 volatile uint32_t *fifo = core_if->data_fifo[0];
4662 uint32_t *data_buff = (uint32_t *) dest;
4665 * @todo Account for the case where _dest is not dword aligned. This
4666 * requires reading data from the FIFO into a uint32_t temp buffer,
4667 * then moving it into the data buffer.
4670 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
4671 core_if, dest, bytes);
4673 for (i = 0; i < word_count; i++, data_buff++) {
4674 *data_buff = DWC_READ_REG32(fifo);
4681 * This functions reads the device registers and prints them
4683 * @param core_if Programming view of DWC_otg controller.
4685 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
4688 volatile uint32_t *addr;
4690 DWC_PRINTF("Device Global Registers\n");
4691 addr = &core_if->dev_if->dev_global_regs->dcfg;
4692 DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n",
4693 (unsigned long)addr, DWC_READ_REG32(addr));
4694 addr = &core_if->dev_if->dev_global_regs->dctl;
4695 DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n",
4696 (unsigned long)addr, DWC_READ_REG32(addr));
4697 addr = &core_if->dev_if->dev_global_regs->dsts;
4698 DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n",
4699 (unsigned long)addr, DWC_READ_REG32(addr));
4700 addr = &core_if->dev_if->dev_global_regs->diepmsk;
4701 DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4702 DWC_READ_REG32(addr));
4703 addr = &core_if->dev_if->dev_global_regs->doepmsk;
4704 DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4705 DWC_READ_REG32(addr));
4706 addr = &core_if->dev_if->dev_global_regs->daint;
4707 DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4708 DWC_READ_REG32(addr));
4709 addr = &core_if->dev_if->dev_global_regs->daintmsk;
4710 DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4711 DWC_READ_REG32(addr));
4712 addr = &core_if->dev_if->dev_global_regs->dtknqr1;
4713 DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4714 DWC_READ_REG32(addr));
4715 if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
4716 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
4717 DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n",
4718 (unsigned long)addr, DWC_READ_REG32(addr));
4721 addr = &core_if->dev_if->dev_global_regs->dvbusdis;
4722 DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
4723 DWC_READ_REG32(addr));
4725 addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
4726 DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n",
4727 (unsigned long)addr, DWC_READ_REG32(addr));
4729 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
4730 DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n",
4731 (unsigned long)addr, DWC_READ_REG32(addr));
4733 if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
4734 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4735 DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n",
4736 (unsigned long)addr, DWC_READ_REG32(addr));
4739 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4740 DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4741 DWC_READ_REG32(addr));
4743 if (core_if->hwcfg2.b.multi_proc_int) {
4745 addr = &core_if->dev_if->dev_global_regs->deachint;
4746 DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n",
4747 (unsigned long)addr, DWC_READ_REG32(addr));
4748 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
4749 DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n",
4750 (unsigned long)addr, DWC_READ_REG32(addr));
4752 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
4755 dev_global_regs->diepeachintmsk[i];
4756 DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4757 i, (unsigned long)addr,
4758 DWC_READ_REG32(addr));
4761 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
4764 dev_global_regs->doepeachintmsk[i];
4765 DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4766 i, (unsigned long)addr,
4767 DWC_READ_REG32(addr));
4771 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
4772 DWC_PRINTF("Device IN EP %d Registers\n", i);
4773 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
4774 DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n",
4775 (unsigned long)addr, DWC_READ_REG32(addr));
4776 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
4777 DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n",
4778 (unsigned long)addr, DWC_READ_REG32(addr));
4779 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
4780 DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n",
4781 (unsigned long)addr, DWC_READ_REG32(addr));
4782 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
4783 DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n",
4784 (unsigned long)addr, DWC_READ_REG32(addr));
4785 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
4786 DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n",
4787 (unsigned long)addr, DWC_READ_REG32(addr));
4788 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
4789 DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n",
4790 (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ );
4793 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
4794 DWC_PRINTF("Device OUT EP %d Registers\n", i);
4795 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
4796 DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n",
4797 (unsigned long)addr, DWC_READ_REG32(addr));
4798 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
4799 DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n",
4800 (unsigned long)addr, DWC_READ_REG32(addr));
4801 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
4802 DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n",
4803 (unsigned long)addr, DWC_READ_REG32(addr));
4804 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
4805 DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n",
4806 (unsigned long)addr, DWC_READ_REG32(addr));
4807 if (core_if->dma_enable) { /* Don't access this register in SLAVE mode */
4808 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
4809 DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n",
4810 (unsigned long)addr, DWC_READ_REG32(addr));
4817 * This functions reads the SPRAM and prints its content
4819 * @param core_if Programming view of DWC_otg controller.
4821 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
4823 volatile uint8_t *addr, *start_addr, *end_addr;
4825 DWC_PRINTF("SPRAM Data:\n");
4826 start_addr = (void *)core_if->core_global_regs;
4827 DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
4828 start_addr += 0x00028000;
4829 end_addr = (void *)core_if->core_global_regs;
4830 end_addr += 0x000280e0;
4832 for (addr = start_addr; addr < end_addr; addr += 16) {
4834 ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
4835 (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
4836 addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
4837 addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
4845 * This function reads the host registers and prints them
4847 * @param core_if Programming view of DWC_otg controller.
4849 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
4852 volatile uint32_t *addr;
4854 DWC_PRINTF("Host Global Registers\n");
4855 addr = &core_if->host_if->host_global_regs->hcfg;
4856 DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n",
4857 (unsigned long)addr, DWC_READ_REG32(addr));
4858 addr = &core_if->host_if->host_global_regs->hfir;
4859 DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n",
4860 (unsigned long)addr, DWC_READ_REG32(addr));
4861 addr = &core_if->host_if->host_global_regs->hfnum;
4862 DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr,
4863 DWC_READ_REG32(addr));
4864 addr = &core_if->host_if->host_global_regs->hptxsts;
4865 DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4866 DWC_READ_REG32(addr));
4867 addr = &core_if->host_if->host_global_regs->haint;
4868 DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4869 DWC_READ_REG32(addr));
4870 addr = &core_if->host_if->host_global_regs->haintmsk;
4871 DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4872 DWC_READ_REG32(addr));
4873 if (core_if->dma_desc_enable) {
4874 addr = &core_if->host_if->host_global_regs->hflbaddr;
4875 DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n",
4876 (unsigned long)addr, DWC_READ_REG32(addr));
4879 addr = core_if->host_if->hprt0;
4880 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4881 DWC_READ_REG32(addr));
4883 for (i = 0; i < core_if->core_params->host_channels; i++) {
4884 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
4885 addr = &core_if->host_if->hc_regs[i]->hcchar;
4886 DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n",
4887 (unsigned long)addr, DWC_READ_REG32(addr));
4888 addr = &core_if->host_if->hc_regs[i]->hcsplt;
4889 DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n",
4890 (unsigned long)addr, DWC_READ_REG32(addr));
4891 addr = &core_if->host_if->hc_regs[i]->hcint;
4892 DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n",
4893 (unsigned long)addr, DWC_READ_REG32(addr));
4894 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
4895 DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n",
4896 (unsigned long)addr, DWC_READ_REG32(addr));
4897 addr = &core_if->host_if->hc_regs[i]->hctsiz;
4898 DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n",
4899 (unsigned long)addr, DWC_READ_REG32(addr));
4900 addr = &core_if->host_if->hc_regs[i]->hcdma;
4901 DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n",
4902 (unsigned long)addr, DWC_READ_REG32(addr));
4903 if (core_if->dma_desc_enable) {
4904 addr = &core_if->host_if->hc_regs[i]->hcdmab;
4905 DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n",
4906 (unsigned long)addr, DWC_READ_REG32(addr));
4914 * This function reads the core global registers and prints them
4916 * @param core_if Programming view of DWC_otg controller.
4918 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
4921 volatile uint32_t *addr;
4924 DWC_PRINTF("Core Global Registers\n");
4925 addr = &core_if->core_global_regs->gotgctl;
4926 DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4927 DWC_READ_REG32(addr));
4928 addr = &core_if->core_global_regs->gotgint;
4929 DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4930 DWC_READ_REG32(addr));
4931 addr = &core_if->core_global_regs->gahbcfg;
4932 DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4933 DWC_READ_REG32(addr));
4934 addr = &core_if->core_global_regs->gusbcfg;
4935 DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4936 DWC_READ_REG32(addr));
4937 addr = &core_if->core_global_regs->grstctl;
4938 DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4939 DWC_READ_REG32(addr));
4940 addr = &core_if->core_global_regs->gintsts;
4941 DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4942 DWC_READ_REG32(addr));
4943 addr = &core_if->core_global_regs->gintmsk;
4944 DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4945 DWC_READ_REG32(addr));
4946 addr = &core_if->core_global_regs->grxstsr;
4947 DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr,
4948 DWC_READ_REG32(addr));
4949 addr = &core_if->core_global_regs->grxfsiz;
4950 DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4951 DWC_READ_REG32(addr));
4952 addr = &core_if->core_global_regs->gnptxfsiz;
4953 DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4954 DWC_READ_REG32(addr));
4955 addr = &core_if->core_global_regs->gnptxsts;
4956 DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4957 DWC_READ_REG32(addr));
4958 addr = &core_if->core_global_regs->gi2cctl;
4959 DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4960 DWC_READ_REG32(addr));
4961 addr = &core_if->core_global_regs->gpvndctl;
4962 DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4963 DWC_READ_REG32(addr));
4964 addr = &core_if->core_global_regs->ggpio;
4965 DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr,
4966 DWC_READ_REG32(addr));
4967 addr = &core_if->core_global_regs->guid;
4968 DWC_PRINTF("GUID @0x%08lX : 0x%08X\n",
4969 (unsigned long)addr, DWC_READ_REG32(addr));
4970 addr = &core_if->core_global_regs->gsnpsid;
4971 DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
4972 DWC_READ_REG32(addr));
4973 addr = &core_if->core_global_regs->ghwcfg1;
4974 DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4975 DWC_READ_REG32(addr));
4976 addr = &core_if->core_global_regs->ghwcfg2;
4977 DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4978 DWC_READ_REG32(addr));
4979 addr = &core_if->core_global_regs->ghwcfg3;
4980 DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4981 DWC_READ_REG32(addr));
4982 addr = &core_if->core_global_regs->ghwcfg4;
4983 DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4984 DWC_READ_REG32(addr));
4985 addr = &core_if->core_global_regs->glpmcfg;
4986 DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4987 DWC_READ_REG32(addr));
4988 addr = &core_if->core_global_regs->gpwrdn;
4989 DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr,
4990 DWC_READ_REG32(addr));
4991 addr = &core_if->core_global_regs->gdfifocfg;
4992 DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4993 DWC_READ_REG32(addr));
4994 addr = &core_if->core_global_regs->adpctl;
4995 DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4996 dwc_otg_adp_read_reg(core_if));
4997 addr = &core_if->core_global_regs->hptxfsiz;
4998 DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4999 DWC_READ_REG32(addr));
5001 if (core_if->en_multiple_tx_fifo == 0) {
5002 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
5003 txfsiz = "DPTXFSIZ";
5005 ep_num = core_if->hwcfg4.b.num_in_eps;
5006 txfsiz = "DIENPTXF";
5008 for (i = 0; i < ep_num; i++) {
5009 addr = &core_if->core_global_regs->dtxfsiz[i];
5010 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
5011 (unsigned long)addr, DWC_READ_REG32(addr));
5013 addr = core_if->pcgcctl;
5014 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5015 DWC_READ_REG32(addr));
5021 * @param core_if Programming view of DWC_otg controller.
5022 * @param num Tx FIFO to flush.
5024 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
5026 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5027 volatile grstctl_t greset = {.d32 = 0 };
5030 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
5032 greset.b.txfflsh = 1;
5033 greset.b.txfnum = num;
5034 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5037 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5038 if (++count > 10000) {
5039 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5040 __func__, greset.d32,
5041 DWC_READ_REG32(&global_regs->gnptxsts));
5045 } while (greset.b.txfflsh == 1);
5047 /* Wait for 3 PHY Clocks */
5054 * @param core_if Programming view of DWC_otg controller.
5056 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
5058 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5059 volatile grstctl_t greset = {.d32 = 0 };
5062 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5066 greset.b.rxfflsh = 1;
5067 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5070 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5071 if (++count > 10000) {
5072 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5077 } while (greset.b.rxfflsh == 1);
5079 /* Wait for 3 PHY Clocks */
5084 * Do core a soft reset of the core. Be careful with this because it
5085 * resets all the internal state machines of the core.
5087 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
5089 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5090 volatile grstctl_t greset = {.d32 = 0 };
5093 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5094 /* Wait for AHB master IDLE state. */
5097 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5098 if (++count > 100000) {
5099 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5104 while (greset.b.ahbidle == 0);
5106 /* Core Soft Reset */
5108 greset.b.csftrst = 1;
5109 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5111 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5112 if (++count > 10000) {
5113 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5114 __func__, greset.d32);
5119 while (greset.b.csftrst == 1);
5121 /* Wait for 3 PHY Clocks */
5125 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
5127 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5130 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
5132 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5136 * Register HCD callbacks. The callbacks are used to start and stop
5137 * the HCD for interrupt processing.
5139 * @param core_if Programming view of DWC_otg controller.
5140 * @param cb the HCD callback structure.
5141 * @param p pointer to be passed to callback function (usb_hcd*).
5143 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
5144 dwc_otg_cil_callbacks_t * cb, void *p)
5146 core_if->hcd_cb = cb;
5151 * Register PCD callbacks. The callbacks are used to start and stop
5152 * the PCD for interrupt processing.
5154 * @param core_if Programming view of DWC_otg controller.
5155 * @param cb the PCD callback structure.
5156 * @param p pointer to be passed to callback function (pcd*).
5158 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
5159 dwc_otg_cil_callbacks_t * cb, void *p)
5161 core_if->pcd_cb = cb;
5168 * This function writes isoc data per 1 (micro)frame into tx fifo
5170 * @param core_if Programming view of DWC_otg controller.
5171 * @param ep The EP to start the transfer on.
5174 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
5176 dwc_otg_dev_in_ep_regs_t *ep_regs;
5177 dtxfsts_data_t txstatus = {.d32 = 0 };
5181 ep->xfer_len = ep->data_per_frame;
5184 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
5186 len = ep->xfer_len - ep->xfer_count;
5188 if (len > ep->maxpacket) {
5189 len = ep->maxpacket;
5192 dwords = (len + 3) / 4;
5194 /* While there is space in the queue and space in the FIFO and
5195 * More data to tranfer, Write packets to the Tx FIFO */
5197 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
5198 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
5200 while (txstatus.b.txfspcavail > dwords &&
5201 ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
5202 /* Write the FIFO */
5203 dwc_otg_ep_write_packet(core_if, ep, 0);
5205 len = ep->xfer_len - ep->xfer_count;
5206 if (len > ep->maxpacket) {
5207 len = ep->maxpacket;
5210 dwords = (len + 3) / 4;
5212 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
5214 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
5220 * This function initializes a descriptor chain for Isochronous transfer
5222 * @param core_if Programming view of DWC_otg controller.
5223 * @param ep The EP to start the transfer on.
5226 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
5229 deptsiz_data_t deptsiz = {.d32 = 0 };
5230 depctl_data_t depctl = {.d32 = 0 };
5231 dsts_data_t dsts = {.d32 = 0 };
5232 volatile uint32_t *addr;
5235 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5237 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5240 ep->xfer_len = ep->data_per_frame;
5242 ep->xfer_buff = ep->cur_pkt_addr;
5243 ep->dma_addr = ep->cur_pkt_dma_addr;
5246 /* Program the transfer size and packet count
5247 * as follows: xfersize = N * maxpacket +
5248 * short_packet pktcnt = N + (short_packet
5251 deptsiz.b.xfersize = ep->xfer_len;
5253 (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
5254 deptsiz.b.mc = deptsiz.b.pktcnt;
5255 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
5258 /* Write the DMA register */
5259 if (core_if->dma_enable) {
5261 (core_if->dev_if->in_ep_regs[ep->num]->
5262 diepdma), (uint32_t) ep->dma_addr);
5266 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
5267 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5269 DWC_WRITE_REG32(&core_if->dev_if->
5270 out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
5272 if (core_if->dma_enable) {
5275 out_ep_regs[ep->num]->doepdma),
5276 (uint32_t) ep->dma_addr);
5280 /** Enable endpoint, clear nak */
5283 if (ep->bInterval == 1) {
5285 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
5286 ep->next_frame = dsts.b.soffn + ep->bInterval;
5288 if (ep->next_frame & 0x1) {
5289 depctl.b.setd1pid = 1;
5291 depctl.b.setd0pid = 1;
5294 ep->next_frame += ep->bInterval;
5296 if (ep->next_frame & 0x1) {
5297 depctl.b.setd1pid = 1;
5299 depctl.b.setd0pid = 1;
5305 DWC_MODIFY_REG32(addr, 0, depctl.d32);
5306 depctl.d32 = DWC_READ_REG32(addr);
5308 if (ep->is_in && core_if->dma_enable == 0) {
5309 write_isoc_frame_data(core_if, ep);
5313 #endif /* DWC_EN_ISOC */
5315 static void dwc_otg_set_uninitialized(int32_t * p, int size)
5318 for (i = 0; i < size; i++) {
5323 static int dwc_otg_param_initialized(int32_t val)
5328 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
5331 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
5332 if (!core_if->core_params) {
5333 return -DWC_E_NO_MEMORY;
5335 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
5336 sizeof(*core_if->core_params) /
5338 DWC_PRINTF("Setting default values for core params\n");
5339 dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
5340 dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
5341 dwc_otg_set_param_dma_desc_enable(core_if,
5342 dwc_param_dma_desc_enable_default);
5343 dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
5344 dwc_otg_set_param_dma_burst_size(core_if,
5345 dwc_param_dma_burst_size_default);
5346 dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
5347 dwc_param_host_support_fs_ls_low_power_default);
5348 dwc_otg_set_param_enable_dynamic_fifo(core_if,
5349 dwc_param_enable_dynamic_fifo_default);
5350 dwc_otg_set_param_data_fifo_size(core_if,
5351 dwc_param_data_fifo_size_default);
5352 dwc_otg_set_param_dev_rx_fifo_size(core_if,
5353 dwc_param_dev_rx_fifo_size_default);
5354 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
5355 dwc_param_dev_nperio_tx_fifo_size_default);
5356 dwc_otg_set_param_host_rx_fifo_size(core_if,
5357 dwc_param_host_rx_fifo_size_default);
5358 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
5359 dwc_param_host_nperio_tx_fifo_size_default);
5360 dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
5361 dwc_param_host_perio_tx_fifo_size_default);
5362 dwc_otg_set_param_max_transfer_size(core_if,
5363 dwc_param_max_transfer_size_default);
5364 dwc_otg_set_param_max_packet_count(core_if,
5365 dwc_param_max_packet_count_default);
5366 dwc_otg_set_param_host_channels(core_if,
5367 dwc_param_host_channels_default);
5368 dwc_otg_set_param_dev_endpoints(core_if,
5369 dwc_param_dev_endpoints_default);
5370 dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
5371 dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
5372 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
5373 dwc_param_host_ls_low_power_phy_clk_default);
5374 dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
5375 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
5376 dwc_param_phy_ulpi_ext_vbus_default);
5377 dwc_otg_set_param_phy_utmi_width(core_if,
5378 dwc_param_phy_utmi_width_default);
5379 dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
5380 dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
5381 dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
5382 dwc_otg_set_param_en_multiple_tx_fifo(core_if,
5383 dwc_param_en_multiple_tx_fifo_default);
5384 for (i = 0; i < 15; i++) {
5385 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5386 dwc_param_dev_perio_tx_fifo_size_default,
5390 for (i = 0; i < 15; i++) {
5391 dwc_otg_set_param_dev_tx_fifo_size(core_if,
5392 dwc_param_dev_tx_fifo_size_default,
5395 dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
5396 dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
5397 dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
5398 dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
5399 dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
5400 dwc_otg_set_param_tx_thr_length(core_if,
5401 dwc_param_tx_thr_length_default);
5402 dwc_otg_set_param_rx_thr_length(core_if,
5403 dwc_param_rx_thr_length_default);
5404 dwc_otg_set_param_ahb_thr_ratio(core_if,
5405 dwc_param_ahb_thr_ratio_default);
5406 dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
5407 dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
5408 dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
5409 dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
5410 dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
5411 dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
5412 dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
5413 DWC_PRINTF("Finished setting default values for core params\n");
5418 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
5420 return core_if->dma_enable;
5423 /* Checks if the parameter is outside of its valid range of values */
5424 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
5425 (((_param_) < (_low_)) || \
5426 ((_param_) > (_high_)))
5428 /* Parameter access functions */
5429 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
5433 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5434 DWC_WARN("Wrong value for otg_cap parameter\n");
5435 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
5436 retval = -DWC_E_INVALID;
5442 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
5443 if (core_if->hwcfg2.b.op_mode !=
5444 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5447 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
5448 if ((core_if->hwcfg2.b.op_mode !=
5449 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5450 && (core_if->hwcfg2.b.op_mode !=
5451 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5452 && (core_if->hwcfg2.b.op_mode !=
5453 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5454 && (core_if->hwcfg2.b.op_mode !=
5455 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
5459 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
5464 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
5466 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5470 (((core_if->hwcfg2.b.op_mode ==
5471 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5472 || (core_if->hwcfg2.b.op_mode ==
5473 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5474 || (core_if->hwcfg2.b.op_mode ==
5475 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5476 || (core_if->hwcfg2.b.op_mode ==
5477 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
5478 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
5479 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
5480 retval = -DWC_E_INVALID;
5483 core_if->core_params->otg_cap = val;
5488 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
5490 return core_if->core_params->otg_cap;
5493 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
5495 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5496 DWC_WARN("Wrong value for opt parameter\n");
5497 return -DWC_E_INVALID;
5499 core_if->core_params->opt = val;
5503 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
5505 return core_if->core_params->opt;
5508 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
5511 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5512 DWC_WARN("Wrong value for dma enable\n");
5513 return -DWC_E_INVALID;
5516 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
5517 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
5519 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5523 retval = -DWC_E_INVALID;
5526 core_if->core_params->dma_enable = val;
5528 dwc_otg_set_param_dma_desc_enable(core_if, 0);
5533 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
5535 return core_if->core_params->dma_enable;
5538 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
5541 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5542 DWC_WARN("Wrong value for dma_enable\n");
5543 DWC_WARN("dma_desc_enable must be 0 or 1\n");
5544 return -DWC_E_INVALID;
5548 && ((dwc_otg_get_param_dma_enable(core_if) == 0)
5549 || (core_if->hwcfg4.b.desc_dma == 0))) {
5550 if (dwc_otg_param_initialized
5551 (core_if->core_params->dma_desc_enable)) {
5553 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5557 retval = -DWC_E_INVALID;
5559 core_if->core_params->dma_desc_enable = val;
5563 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
5565 return core_if->core_params->dma_desc_enable;
5568 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
5571 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5572 DWC_WARN("Wrong value for host_support_fs_low_power\n");
5573 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
5574 return -DWC_E_INVALID;
5576 core_if->core_params->host_support_fs_ls_low_power = val;
5580 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
5583 return core_if->core_params->host_support_fs_ls_low_power;
5586 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
5590 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5591 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
5592 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
5593 return -DWC_E_INVALID;
5596 if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
5597 if (dwc_otg_param_initialized
5598 (core_if->core_params->enable_dynamic_fifo)) {
5600 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
5604 retval = -DWC_E_INVALID;
5606 core_if->core_params->enable_dynamic_fifo = val;
5610 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
5612 return core_if->core_params->enable_dynamic_fifo;
5615 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5618 if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
5619 DWC_WARN("Wrong value for data_fifo_size\n");
5620 DWC_WARN("data_fifo_size must be 32-32768\n");
5621 return -DWC_E_INVALID;
5624 if (val > core_if->hwcfg3.b.dfifo_depth) {
5625 if (dwc_otg_param_initialized
5626 (core_if->core_params->data_fifo_size)) {
5628 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
5631 val = core_if->hwcfg3.b.dfifo_depth;
5632 retval = -DWC_E_INVALID;
5635 core_if->core_params->data_fifo_size = val;
5639 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
5641 return core_if->core_params->data_fifo_size;
5644 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5647 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5648 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
5649 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
5650 return -DWC_E_INVALID;
5653 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5654 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
5655 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
5657 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5658 retval = -DWC_E_INVALID;
5661 core_if->core_params->dev_rx_fifo_size = val;
5665 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
5667 return core_if->core_params->dev_rx_fifo_size;
5670 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5675 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5676 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
5677 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
5678 return -DWC_E_INVALID;
5681 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5682 if (dwc_otg_param_initialized
5683 (core_if->core_params->dev_nperio_tx_fifo_size)) {
5685 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
5689 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5691 retval = -DWC_E_INVALID;
5694 core_if->core_params->dev_nperio_tx_fifo_size = val;
5698 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5700 return core_if->core_params->dev_nperio_tx_fifo_size;
5703 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
5708 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5709 DWC_WARN("Wrong value for host_rx_fifo_size\n");
5710 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
5711 return -DWC_E_INVALID;
5714 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5715 if (dwc_otg_param_initialized
5716 (core_if->core_params->host_rx_fifo_size)) {
5718 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
5721 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5722 retval = -DWC_E_INVALID;
5725 core_if->core_params->host_rx_fifo_size = val;
5730 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
5732 return core_if->core_params->host_rx_fifo_size;
5735 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5740 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5741 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
5742 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
5743 return -DWC_E_INVALID;
5746 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5747 if (dwc_otg_param_initialized
5748 (core_if->core_params->host_nperio_tx_fifo_size)) {
5750 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
5754 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5756 retval = -DWC_E_INVALID;
5759 core_if->core_params->host_nperio_tx_fifo_size = val;
5763 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5765 return core_if->core_params->host_nperio_tx_fifo_size;
5768 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5772 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5773 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
5774 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
5775 return -DWC_E_INVALID;
5778 if (val > ((core_if->hptxfsiz.d32) >> 16)) {
5779 if (dwc_otg_param_initialized
5780 (core_if->core_params->host_perio_tx_fifo_size)) {
5782 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
5785 val = (core_if->hptxfsiz.d32) >> 16;
5786 retval = -DWC_E_INVALID;
5789 core_if->core_params->host_perio_tx_fifo_size = val;
5793 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5795 return core_if->core_params->host_perio_tx_fifo_size;
5798 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
5803 if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
5804 DWC_WARN("Wrong value for max_transfer_size\n");
5805 DWC_WARN("max_transfer_size must be 2047-524288\n");
5806 return -DWC_E_INVALID;
5809 if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
5810 if (dwc_otg_param_initialized
5811 (core_if->core_params->max_transfer_size)) {
5813 ("%d invalid for max_transfer_size. Check HW configuration.\n",
5817 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
5819 retval = -DWC_E_INVALID;
5822 core_if->core_params->max_transfer_size = val;
5826 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
5828 return core_if->core_params->max_transfer_size;
5831 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
5835 if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
5836 DWC_WARN("Wrong value for max_packet_count\n");
5837 DWC_WARN("max_packet_count must be 15-511\n");
5838 return -DWC_E_INVALID;
5841 if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
5842 if (dwc_otg_param_initialized
5843 (core_if->core_params->max_packet_count)) {
5845 ("%d invalid for max_packet_count. Check HW configuration.\n",
5849 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
5850 retval = -DWC_E_INVALID;
5853 core_if->core_params->max_packet_count = val;
5857 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
5859 return core_if->core_params->max_packet_count;
5862 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
5866 if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
5867 DWC_WARN("Wrong value for host_channels\n");
5868 DWC_WARN("host_channels must be 1-16\n");
5869 return -DWC_E_INVALID;
5872 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
5873 if (dwc_otg_param_initialized
5874 (core_if->core_params->host_channels)) {
5876 ("%d invalid for host_channels. Check HW configurations.\n",
5879 val = (core_if->hwcfg2.b.num_host_chan + 1);
5880 retval = -DWC_E_INVALID;
5883 core_if->core_params->host_channels = val;
5887 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
5889 return core_if->core_params->host_channels;
5892 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
5896 if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
5897 DWC_WARN("Wrong value for dev_endpoints\n");
5898 DWC_WARN("dev_endpoints must be 1-15\n");
5899 return -DWC_E_INVALID;
5902 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
5903 if (dwc_otg_param_initialized
5904 (core_if->core_params->dev_endpoints)) {
5906 ("%d invalid for dev_endpoints. Check HW configurations.\n",
5909 val = core_if->hwcfg2.b.num_dev_ep;
5910 retval = -DWC_E_INVALID;
5913 core_if->core_params->dev_endpoints = val;
5917 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
5919 return core_if->core_params->dev_endpoints;
5922 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
5927 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5928 DWC_WARN("Wrong value for phy_type\n");
5929 DWC_WARN("phy_type must be 0,1 or 2\n");
5930 return -DWC_E_INVALID;
5932 #ifndef NO_FS_PHY_HW_CHECKS
5933 if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
5934 ((core_if->hwcfg2.b.hs_phy_type == 1) ||
5935 (core_if->hwcfg2.b.hs_phy_type == 3))) {
5937 } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
5938 ((core_if->hwcfg2.b.hs_phy_type == 2) ||
5939 (core_if->hwcfg2.b.hs_phy_type == 3))) {
5941 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
5942 (core_if->hwcfg2.b.fs_phy_type == 1)) {
5946 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
5948 ("%d invalid for phy_type. Check HW configurations.\n",
5951 if (core_if->hwcfg2.b.hs_phy_type) {
5952 if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
5953 (core_if->hwcfg2.b.hs_phy_type == 1)) {
5954 val = DWC_PHY_TYPE_PARAM_UTMI;
5956 val = DWC_PHY_TYPE_PARAM_ULPI;
5959 retval = -DWC_E_INVALID;
5962 core_if->core_params->phy_type = val;
5966 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
5968 return core_if->core_params->phy_type;
5971 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
5974 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5975 DWC_WARN("Wrong value for speed parameter\n");
5976 DWC_WARN("max_speed parameter must be 0 or 1\n");
5977 return -DWC_E_INVALID;
5980 && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
5981 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
5983 ("%d invalid for speed paremter. Check HW configuration.\n",
5987 (dwc_otg_get_param_phy_type(core_if) ==
5988 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
5989 retval = -DWC_E_INVALID;
5991 core_if->core_params->speed = val;
5995 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
5997 return core_if->core_params->speed;
6000 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
6005 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6007 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
6008 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
6009 return -DWC_E_INVALID;
6012 if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
6013 && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
6014 if (dwc_otg_param_initialized
6015 (core_if->core_params->host_ls_low_power_phy_clk)) {
6017 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6021 (dwc_otg_get_param_phy_type(core_if) ==
6022 DWC_PHY_TYPE_PARAM_FS) ?
6023 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
6024 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
6025 retval = -DWC_E_INVALID;
6028 core_if->core_params->host_ls_low_power_phy_clk = val;
6032 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
6034 return core_if->core_params->host_ls_low_power_phy_clk;
6037 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
6039 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6040 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
6041 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
6042 return -DWC_E_INVALID;
6045 core_if->core_params->phy_ulpi_ddr = val;
6049 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
6051 return core_if->core_params->phy_ulpi_ddr;
6054 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
6057 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6058 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
6059 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
6060 return -DWC_E_INVALID;
6063 core_if->core_params->phy_ulpi_ext_vbus = val;
6067 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
6069 return core_if->core_params->phy_ulpi_ext_vbus;
6072 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
6074 if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
6075 DWC_WARN("Wrong valaue for phy_utmi_width\n");
6076 DWC_WARN("phy_utmi_width must be 8 or 16\n");
6077 return -DWC_E_INVALID;
6080 core_if->core_params->phy_utmi_width = val;
6084 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
6086 return core_if->core_params->phy_utmi_width;
6089 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
6091 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6092 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
6093 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
6094 return -DWC_E_INVALID;
6097 core_if->core_params->ulpi_fs_ls = val;
6101 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
6103 return core_if->core_params->ulpi_fs_ls;
6106 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
6108 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6109 DWC_WARN("Wrong valaue for ts_dline\n");
6110 DWC_WARN("ts_dline must be 0 or 1\n");
6111 return -DWC_E_INVALID;
6114 core_if->core_params->ts_dline = val;
6118 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
6120 return core_if->core_params->ts_dline;
6123 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
6126 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6127 DWC_WARN("Wrong valaue for i2c_enable\n");
6128 DWC_WARN("i2c_enable must be 0 or 1\n");
6129 return -DWC_E_INVALID;
6131 #ifndef NO_FS_PHY_HW_CHECK
6132 if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
6133 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
6135 ("%d invalid for i2c_enable. Check HW configuration.\n",
6139 retval = -DWC_E_INVALID;
6143 core_if->core_params->i2c_enable = val;
6147 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
6149 return core_if->core_params->i2c_enable;
6152 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6153 int32_t val, int fifo_num)
6157 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
6158 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
6159 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
6160 return -DWC_E_INVALID;
6164 (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
6165 if (dwc_otg_param_initialized
6166 (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
6168 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6171 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
6172 retval = -DWC_E_INVALID;
6175 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
6179 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6182 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
6185 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
6189 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6190 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
6191 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
6192 return -DWC_E_INVALID;
6195 if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
6196 if (dwc_otg_param_initialized
6197 (core_if->core_params->en_multiple_tx_fifo)) {
6199 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6203 retval = -DWC_E_INVALID;
6206 core_if->core_params->en_multiple_tx_fifo = val;
6210 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
6212 return core_if->core_params->en_multiple_tx_fifo;
6215 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
6220 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
6221 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
6222 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
6223 return -DWC_E_INVALID;
6227 (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
6228 if (dwc_otg_param_initialized
6229 (core_if->core_params->dev_tx_fifo_size[fifo_num])) {
6231 ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
6234 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
6235 retval = -DWC_E_INVALID;
6238 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
6242 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
6245 return core_if->core_params->dev_tx_fifo_size[fifo_num];
6248 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6252 if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
6253 DWC_WARN("Wrong value for thr_ctl\n");
6254 DWC_WARN("thr_ctl must be 0-7\n");
6255 return -DWC_E_INVALID;
6259 (!dwc_otg_get_param_dma_enable(core_if) ||
6260 !core_if->hwcfg4.b.ded_fifo_en)) {
6261 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
6263 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6267 retval = -DWC_E_INVALID;
6270 core_if->core_params->thr_ctl = val;
6274 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
6276 return core_if->core_params->thr_ctl;
6279 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
6283 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6284 DWC_WARN("Wrong value for lpm_enable\n");
6285 DWC_WARN("lpm_enable must be 0 or 1\n");
6286 return -DWC_E_INVALID;
6289 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
6290 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
6292 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6296 retval = -DWC_E_INVALID;
6299 core_if->core_params->lpm_enable = val;
6303 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
6305 return core_if->core_params->lpm_enable;
6308 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6310 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6311 DWC_WARN("Wrong valaue for tx_thr_length\n");
6312 DWC_WARN("tx_thr_length must be 8 - 128\n");
6313 return -DWC_E_INVALID;
6316 core_if->core_params->tx_thr_length = val;
6320 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
6322 return core_if->core_params->tx_thr_length;
6325 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6327 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6328 DWC_WARN("Wrong valaue for rx_thr_length\n");
6329 DWC_WARN("rx_thr_length must be 8 - 128\n");
6330 return -DWC_E_INVALID;
6333 core_if->core_params->rx_thr_length = val;
6337 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
6339 return core_if->core_params->rx_thr_length;
6342 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
6344 if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
6345 DWC_OTG_PARAM_TEST(val, 4, 4) &&
6346 DWC_OTG_PARAM_TEST(val, 8, 8) &&
6347 DWC_OTG_PARAM_TEST(val, 16, 16) &&
6348 DWC_OTG_PARAM_TEST(val, 32, 32) &&
6349 DWC_OTG_PARAM_TEST(val, 64, 64) &&
6350 DWC_OTG_PARAM_TEST(val, 128, 128) &&
6351 DWC_OTG_PARAM_TEST(val, 256, 256)) {
6352 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
6353 return -DWC_E_INVALID;
6355 core_if->core_params->dma_burst_size = val;
6359 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
6361 return core_if->core_params->dma_burst_size;
6364 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
6367 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6368 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
6369 return -DWC_E_INVALID;
6371 if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
6372 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
6374 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6377 retval = -DWC_E_INVALID;
6380 core_if->core_params->pti_enable = val;
6384 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
6386 return core_if->core_params->pti_enable;
6389 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
6392 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6393 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
6394 return -DWC_E_INVALID;
6396 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
6397 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
6399 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6402 retval = -DWC_E_INVALID;
6405 core_if->core_params->mpi_enable = val;
6409 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
6411 return core_if->core_params->mpi_enable;
6414 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
6417 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6418 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
6419 return -DWC_E_INVALID;
6421 if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
6422 if (dwc_otg_param_initialized
6423 (core_if->core_params->adp_supp_enable)) {
6425 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6428 retval = -DWC_E_INVALID;
6431 core_if->core_params->adp_supp_enable = val;
6432 /*Set OTG version 2.0 in case of enabling ADP*/
6434 dwc_otg_set_param_otg_ver(core_if, 1);
6439 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
6441 return core_if->core_params->adp_supp_enable;
6444 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
6447 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6448 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
6449 DWC_WARN("ic_usb_cap must be 0 or 1\n");
6450 return -DWC_E_INVALID;
6453 if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
6454 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
6456 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6459 retval = -DWC_E_INVALID;
6462 core_if->core_params->ic_usb_cap = val;
6466 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
6468 return core_if->core_params->ic_usb_cap;
6471 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
6476 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6477 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
6478 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
6479 return -DWC_E_INVALID;
6483 && (core_if->snpsid < OTG_CORE_REV_2_81a
6484 || !dwc_otg_get_param_thr_ctl(core_if))) {
6487 && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
6492 if (dwc_otg_param_initialized
6493 (core_if->core_params->ahb_thr_ratio)) {
6495 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6498 retval = -DWC_E_INVALID;
6502 core_if->core_params->ahb_thr_ratio = val;
6506 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
6508 return core_if->core_params->ahb_thr_ratio;
6511 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
6515 hwcfg4_data_t hwcfg4 = {.d32 = 0 };
6516 hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
6518 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6519 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
6520 DWC_WARN("power_down must be 0 - 2\n");
6521 return -DWC_E_INVALID;
6524 if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
6528 && ((core_if->snpsid < OTG_CORE_REV_3_00a)
6529 || (hwcfg4.b.xhiber == 0))) {
6533 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
6535 ("%d invalid for parameter power_down. Check HW configuration.\n",
6538 retval = -DWC_E_INVALID;
6541 core_if->core_params->power_down = val;
6545 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
6547 return core_if->core_params->power_down;
6550 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6555 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6556 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
6557 DWC_WARN("reload_ctl must be 0 or 1\n");
6558 return -DWC_E_INVALID;
6561 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
6565 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
6566 DWC_ERROR("%d invalid for parameter reload_ctl."
6567 "Check HW configuration.\n", val);
6569 retval = -DWC_E_INVALID;
6572 core_if->core_params->reload_ctl = val;
6576 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
6578 return core_if->core_params->reload_ctl;
6581 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
6586 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6587 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
6588 DWC_WARN("dev_out_nak must be 0 or 1\n");
6589 return -DWC_E_INVALID;
6592 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
6593 !(core_if->core_params->dma_desc_enable))) {
6597 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
6598 DWC_ERROR("%d invalid for parameter dev_out_nak."
6599 "Check HW configuration.\n", val);
6601 retval = -DWC_E_INVALID;
6604 core_if->core_params->dev_out_nak = val;
6608 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
6610 return core_if->core_params->dev_out_nak;
6613 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
6618 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6619 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
6620 DWC_WARN("cont_on_bna must be 0 or 1\n");
6621 return -DWC_E_INVALID;
6624 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
6625 !(core_if->core_params->dma_desc_enable))) {
6629 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
6630 DWC_ERROR("%d invalid for parameter cont_on_bna."
6631 "Check HW configuration.\n", val);
6633 retval = -DWC_E_INVALID;
6636 core_if->core_params->cont_on_bna = val;
6640 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
6642 return core_if->core_params->cont_on_bna;
6645 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
6650 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6651 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
6652 DWC_WARN("ahb_single must be 0 or 1\n");
6653 return -DWC_E_INVALID;
6656 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
6660 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
6661 DWC_ERROR("%d invalid for parameter ahb_single."
6662 "Check HW configuration.\n", val);
6664 retval = -DWC_E_INVALID;
6667 core_if->core_params->ahb_single = val;
6671 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
6673 return core_if->core_params->ahb_single;
6676 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
6680 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6681 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
6683 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
6684 return -DWC_E_INVALID;
6687 core_if->core_params->otg_ver = val;
6691 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
6693 return core_if->core_params->otg_ver;
6696 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
6698 gotgctl_data_t otgctl;
6699 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6700 return otgctl.b.hstnegscs;
6703 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
6705 gotgctl_data_t otgctl;
6706 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6707 return otgctl.b.sesreqscs;
6710 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
6712 if(core_if->otg_ver == 0) {
6713 gotgctl_data_t otgctl;
6714 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6715 otgctl.b.hnpreq = val;
6716 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
6718 core_if->otg_sts = val;
6722 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
6724 return core_if->snpsid;
6727 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
6729 gintsts_data_t gintsts;
6730 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6731 return gintsts.b.curmode;
6734 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
6736 gusbcfg_data_t usbcfg;
6737 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6738 return usbcfg.b.hnpcap;
6741 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6743 gusbcfg_data_t usbcfg;
6744 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6745 usbcfg.b.hnpcap = val;
6746 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6749 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
6751 gusbcfg_data_t usbcfg;
6752 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6753 return usbcfg.b.srpcap;
6756 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6758 gusbcfg_data_t usbcfg;
6759 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6760 usbcfg.b.srpcap = val;
6761 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6764 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
6767 /* originally: dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); */
6769 dcfg.d32 = -1; //GRAYG
6770 DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)\n", __func__, core_if);
6771 if (NULL == core_if)
6772 DWC_ERROR("reg request with NULL core_if\n");
6773 DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)->dev_if(%p)\n", __func__,
6774 core_if, core_if->dev_if);
6775 if (NULL == core_if->dev_if)
6776 DWC_ERROR("reg request with NULL dev_if\n");
6777 DWC_DEBUGPL(DBG_CILV, "%s - core_if(%p)->dev_if(%p)->"
6778 "dev_global_regs(%p)\n", __func__,
6779 core_if, core_if->dev_if,
6780 core_if->dev_if->dev_global_regs);
6781 if (NULL == core_if->dev_if->dev_global_regs)
6782 DWC_ERROR("reg request with NULL dev_global_regs\n");
6784 DWC_DEBUGPL(DBG_CILV, "%s - &core_if(%p)->dev_if(%p)->"
6785 "dev_global_regs(%p)->dcfg = %p\n", __func__,
6786 core_if, core_if->dev_if,
6787 core_if->dev_if->dev_global_regs,
6788 &core_if->dev_if->dev_global_regs->dcfg);
6789 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6791 return dcfg.b.devspd;
6794 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
6797 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6798 dcfg.b.devspd = val;
6799 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
6802 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
6805 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6806 return hprt0.b.prtconnsts;
6809 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
6812 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
6813 return dsts.b.enumspd;
6816 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
6819 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6820 return hprt0.b.prtpwr;
6824 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
6826 return core_if->hibernation_suspend;
6829 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
6832 hprt0.d32 = dwc_otg_read_hprt0(core_if);
6833 hprt0.b.prtpwr = val;
6834 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6837 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
6840 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6841 return hprt0.b.prtsusp;
6845 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
6848 hprt0.d32 = dwc_otg_read_hprt0(core_if);
6849 hprt0.b.prtsusp = val;
6850 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6853 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
6856 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6857 return hfir.b.frint;
6861 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
6865 fram_int = calc_frame_interval(core_if);
6866 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6867 if (!core_if->core_params->reload_ctl) {
6868 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
6869 "not set to 1.\nShould load driver with reload_ctl=1"
6870 " module parameter\n");
6875 if ((val < 3350) || (val > 4150)) {
6876 DWC_WARN("HFIR interval for HS core and 30 MHz"
6877 "clock freq should be from 3350 to 4150\n");
6882 if ((val < 26820) || (val > 33180)) {
6883 DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
6884 "clock freq should be from 26820 to 33180\n");
6889 if ((val < 5360) || (val > 6640)) {
6890 DWC_WARN("HFIR interval for HS core and 48 MHz"
6891 "clock freq should be from 5360 to 6640\n");
6896 if ((val < 42912) || (val > 53088)) {
6897 DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
6898 "clock freq should be from 42912 to 53088\n");
6903 if ((val < 6700) || (val > 8300)) {
6904 DWC_WARN("HFIR interval for HS core and 60 MHz"
6905 "clock freq should be from 6700 to 8300\n");
6910 if ((val < 53640) || (val > 65536)) {
6911 DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
6912 "clock freq should be from 53640 to 65536\n");
6917 DWC_WARN("Unknown frame interval\n");
6923 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
6926 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
6929 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
6930 return hcfg.b.modechtimen;
6934 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
6937 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
6938 hcfg.b.modechtimen = val;
6939 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
6942 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
6945 hprt0.d32 = dwc_otg_read_hprt0(core_if);
6946 hprt0.b.prtres = val;
6947 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6950 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
6953 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
6954 return dctl.b.rmtwkupsig;
6957 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
6959 glpmcfg_data_t lpmcfg;
6960 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6963 ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
6964 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
6965 core_if->lx_state, lpmcfg.b.prt_sleep_sts);
6967 return lpmcfg.b.prt_sleep_sts;
6970 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
6972 glpmcfg_data_t lpmcfg;
6973 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6974 return lpmcfg.b.rem_wkup_en;
6977 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
6979 glpmcfg_data_t lpmcfg;
6980 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6981 return lpmcfg.b.appl_resp;
6984 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
6986 glpmcfg_data_t lpmcfg;
6987 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6988 lpmcfg.b.appl_resp = val;
6989 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
6992 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
6994 glpmcfg_data_t lpmcfg;
6995 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6996 return lpmcfg.b.hsic_connect;
6999 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
7001 glpmcfg_data_t lpmcfg;
7002 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7003 lpmcfg.b.hsic_connect = val;
7004 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7007 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
7009 glpmcfg_data_t lpmcfg;
7010 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7011 return lpmcfg.b.inv_sel_hsic;
7015 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
7017 glpmcfg_data_t lpmcfg;
7018 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7019 lpmcfg.b.inv_sel_hsic = val;
7020 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7023 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
7025 return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7028 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
7030 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
7033 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
7035 return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7038 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
7040 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
7043 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
7045 return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
7048 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7050 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
7053 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
7055 return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
7058 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7060 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
7063 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
7065 return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
7068 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
7070 DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
7073 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
7075 return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
7078 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
7080 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
7083 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
7085 return DWC_READ_REG32(core_if->host_if->hprt0);
7089 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
7091 DWC_WRITE_REG32(core_if->host_if->hprt0, val);
7094 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
7096 return DWC_READ_REG32(&core_if->core_global_regs->guid);
7099 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
7101 DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
7104 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
7106 return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
7109 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
7111 return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7115 * Start the SRP timer to detect when the SRP does not complete within
7118 * @param core_if the pointer to core_if strucure.
7120 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
7122 core_if->srp_timer_started = 1;
7123 DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
7126 void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if)
7128 uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
7132 val.d32 = DWC_READ_REG32(addr);
7134 DWC_ERROR("Session Request Already active!\n");
7138 DWC_INFO("Session Request Initated\n"); //NOTICE
7139 mem.d32 = DWC_READ_REG32(addr);
7141 DWC_WRITE_REG32(addr, mem.d32);
7143 /* Start the SRP timer */
7144 dwc_otg_pcd_start_srp_timer(core_if);