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
60 #include "common_port/dwc_os.h"
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
63 #include "dwc_otg_driver.h"
64 #include "usbdev_rk.h"
65 #include "dwc_otg_hcd.h"
67 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
70 * This function is called to initialize the DWC_otg CSR data
71 * structures. The register addresses in the device and host
72 * structures are initialized from the base address supplied by the
73 * caller. The calling function must make the OS calls to get the
74 * base address of the DWC_otg controller registers. The core_params
75 * argument holds the parameters that specify how the core should be
78 * @param reg_base_addr Base address of DWC_otg core registers
81 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
83 dwc_otg_core_if_t *core_if = 0;
84 dwc_otg_dev_if_t *dev_if = 0;
85 dwc_otg_host_if_t *host_if = 0;
86 uint8_t *reg_base = (uint8_t *) reg_base_addr;
89 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
91 core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
93 if (core_if == NULL) {
95 "Allocation of dwc_otg_core_if_t failed\n");
98 core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
101 * Allocate the Device Mode structures.
103 dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
105 if (dev_if == NULL) {
106 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
111 dev_if->dev_global_regs =
112 (dwc_otg_device_global_regs_t *) (reg_base +
113 DWC_DEV_GLOBAL_REG_OFFSET);
115 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
116 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
117 (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
118 (i * DWC_EP_REG_OFFSET));
120 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
121 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
122 (i * DWC_EP_REG_OFFSET));
123 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
124 i, &dev_if->in_ep_regs[i]->diepctl);
125 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
126 i, &dev_if->out_ep_regs[i]->doepctl);
129 dev_if->speed = 0; // unknown
131 core_if->dev_if = dev_if;
134 * Allocate the Host Mode structures.
136 host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
138 if (host_if == NULL) {
140 "Allocation of dwc_otg_host_if_t failed\n");
146 host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
147 (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
150 (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
152 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
153 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
154 (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
155 (i * DWC_OTG_CHAN_REGS_OFFSET));
156 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
157 i, &host_if->hc_regs[i]->hcchar);
160 host_if->num_host_channels = MAX_EPS_CHANNELS;
161 core_if->host_if = host_if;
163 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
164 core_if->data_fifo[i] =
165 (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
166 (i * DWC_OTG_DATA_FIFO_SIZE));
167 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n",
168 i, (unsigned long)core_if->data_fifo[i]);
171 core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
173 /* Initiate lx_state to L3 disconnected state */
174 core_if->lx_state = DWC_OTG_L3;
176 * Store the contents of the hardware configuration registers here for
179 core_if->hwcfg1.d32 =
180 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
181 core_if->hwcfg2.d32 =
182 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
183 core_if->hwcfg3.d32 =
184 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
185 core_if->hwcfg4.d32 =
186 DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
188 /* Force host mode to get HPTXFSIZ exact power on value */
190 gusbcfg_data_t gusbcfg = {.d32 = 0 };
191 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
192 gusbcfg.b.force_host_mode = 1;
193 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
195 core_if->hptxfsiz.d32 =
196 DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
197 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
198 gusbcfg.b.force_host_mode = 0;
199 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
203 DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
204 DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
205 DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
206 DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
209 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
211 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
213 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
214 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
216 DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
217 DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
218 DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
219 DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
220 core_if->hwcfg2.b.num_host_chan);
221 DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
222 core_if->hwcfg2.b.nonperio_tx_q_depth);
223 DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
224 core_if->hwcfg2.b.host_perio_tx_q_depth);
225 DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
226 core_if->hwcfg2.b.dev_token_q_depth);
228 DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
229 core_if->hwcfg3.b.dfifo_depth);
230 DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
231 core_if->hwcfg3.b.xfer_size_cntr_width);
234 * Set the SRP sucess bit for FS-I2c
236 core_if->srp_success = 0;
237 core_if->srp_timer_started = 0;
240 * Create new workqueue and init works
242 core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
243 if (core_if->wq_otg == 0) {
244 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
251 core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
252 DWC_PRINTF("%p\n",&core_if->core_global_regs->gsnpsid);
253 DWC_PRINTF("Core Release: %x.%x%x%x\n",
254 (core_if->snpsid >> 12 & 0xF),
255 (core_if->snpsid >> 8 & 0xF),
256 (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
258 core_if->wkp_tasklet = DWC_TASK_ALLOC("wkp_tasklet", w_wakeup_detected, core_if);
260 if (dwc_otg_setup_params(core_if)) {
261 DWC_WARN("Error while setting core params\n");
264 core_if->hibernation_suspend = 0;
265 if (core_if->otg_ver)
266 core_if->test_mode = 0;
268 /** ADP initialization */
269 dwc_otg_adp_init(core_if);
275 * This function frees the structures allocated by dwc_otg_cil_init().
277 * @param core_if The core interface pointer returned from
278 * dwc_otg_cil_init().
281 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
283 dctl_data_t dctl = {.d32 = 0 };
284 /* Disable all interrupts */
285 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
286 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
288 dctl.b.sftdiscon = 1;
289 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
290 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0,
294 if (core_if->wq_otg) {
295 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
296 DWC_WORKQ_FREE(core_if->wq_otg);
298 if (core_if->dev_if) {
299 DWC_FREE(core_if->dev_if);
301 if (core_if->host_if) {
302 DWC_FREE(core_if->host_if);
305 /** Remove ADP Stuff */
306 dwc_otg_adp_remove(core_if);
307 if (core_if->core_params) {
308 DWC_FREE(core_if->core_params);
310 if (core_if->wkp_tasklet){
311 DWC_TASK_FREE(core_if->wkp_tasklet);
313 if (core_if->srp_timer) {
314 DWC_TIMER_FREE(core_if->srp_timer);
320 * This function enables the controller's Global Interrupt in the AHB Config
323 * @param core_if Programming view of DWC_otg controller.
325 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
327 gahbcfg_data_t ahbcfg = {.d32 = 0 };
328 ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
329 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
333 * This function disables the controller's Global Interrupt in the AHB Config
336 * @param core_if Programming view of DWC_otg controller.
338 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
340 gahbcfg_data_t ahbcfg = {.d32 = 0 };
341 ahbcfg.b.glblintrmsk = 1; /* Disable interrupts */
342 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
346 * This function initializes the commmon interrupts, used in both
347 * device and host modes.
349 * @param core_if Programming view of the DWC_otg controller
352 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
354 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
355 gintmsk_data_t intr_mask = {.d32 = 0 };
357 /* Clear any pending OTG Interrupts */
358 DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
360 /* Clear any pending interrupts */
361 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
364 * Enable the interrupts in the GINTMSK.
366 intr_mask.b.modemismatch = 1;
367 intr_mask.b.otgintr = 1;
369 if (!core_if->dma_enable) {
370 intr_mask.b.rxstsqlvl = 1;
373 intr_mask.b.conidstschng = 1;
374 intr_mask.b.wkupintr = 1;
375 intr_mask.b.disconnect = 0;
376 intr_mask.b.usbsuspend = 1;
377 //intr_mask.b.sessreqintr = 1;
378 #ifdef CONFIG_USB_DWC_OTG_LPM
379 if (core_if->core_params->lpm_enable) {
380 intr_mask.b.lpmtranrcvd = 1;
383 DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
387 * The restore operation is modified to support Synopsys Emulated Powerdown and
388 * Hibernation. This function is for exiting from Device mode hibernation by
389 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
390 * @param core_if Programming view of DWC_otg controller.
391 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
392 * @param reset - indicates whether resume is initiated by Reset.
394 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
395 int rem_wakeup, int reset)
397 gpwrdn_data_t gpwrdn = {.d32 = 0 };
398 pcgcctl_data_t pcgcctl = {.d32 = 0 };
399 dctl_data_t dctl = {.d32 = 0 };
403 if (!core_if->hibernation_suspend) {
404 DWC_PRINTF("Already exited from Hibernation\n");
408 DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
409 /* Switch-on voltage to the core */
410 gpwrdn.b.pwrdnswtch = 1;
411 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
416 gpwrdn.b.pwrdnrstn = 1;
417 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
420 /* Assert Restore signal */
422 gpwrdn.b.restore = 1;
423 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
426 /* Disable power clamps */
428 gpwrdn.b.pwrdnclmp = 1;
429 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
435 /* Deassert Reset core */
437 gpwrdn.b.pwrdnrstn = 1;
438 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
441 /* Disable PMU interrupt */
443 gpwrdn.b.pmuintsel = 1;
444 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
446 /* Mask interrupts from gpwrdn */
448 gpwrdn.b.connect_det_msk = 1;
449 gpwrdn.b.srp_det_msk = 1;
450 gpwrdn.b.disconn_det_msk = 1;
451 gpwrdn.b.rst_det_msk = 1;
452 gpwrdn.b.lnstchng_msk = 1;
453 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
455 /* Indicates that we are going out from hibernation */
456 core_if->hibernation_suspend = 0;
459 * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
460 * indicates restore from remote_wakeup
462 restore_essential_regs(core_if, rem_wakeup, 0);
465 * Wait a little for seeing new value of variable hibernation_suspend if
466 * Restore done interrupt received before polling
470 if (core_if->hibernation_suspend == 0) {
472 * Wait For Restore_done Interrupt. This mechanism of polling the
473 * interrupt is introduced to avoid any possible race conditions
476 gintsts_data_t gintsts;
478 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
479 if (gintsts.b.restoredone) {
481 gintsts.b.restoredone = 1;
482 DWC_WRITE_REG32(&core_if->core_global_regs->
483 gintsts, gintsts.d32);
484 DWC_PRINTF("Restore Done Interrupt seen\n");
490 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
493 /* Clear all pending interupts */
494 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
496 /* De-assert Restore */
498 gpwrdn.b.restore = 1;
499 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
504 pcgcctl.b.rstpdwnmodule = 1;
505 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
508 /* Restore GUSBCFG and DCFG */
509 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
510 core_if->gr_backup->gusbcfg_local);
511 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
512 core_if->dr_backup->dcfg);
514 /* De-assert Wakeup Logic */
516 gpwrdn.b.pmuactv = 1;
517 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
521 /* Set Device programming done bit */
522 dctl.b.pwronprgdone = 1;
523 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
525 /* Start Remote Wakeup Signaling */
526 dctl.d32 = core_if->dr_backup->dctl;
527 dctl.b.rmtwkupsig = 1;
528 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
532 /* Clear all pending interupts */
533 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
535 /* Restore global registers */
536 dwc_otg_restore_global_regs(core_if);
537 /* Restore device global registers */
538 dwc_otg_restore_dev_regs(core_if, rem_wakeup);
543 dctl.b.rmtwkupsig = 1;
544 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
547 core_if->hibernation_suspend = 0;
548 /* The core will be in ON STATE */
549 core_if->lx_state = DWC_OTG_L0;
550 DWC_PRINTF("Hibernation recovery completes here\n");
556 * The restore operation is modified to support Synopsys Emulated Powerdown and
557 * Hibernation. This function is for exiting from Host mode hibernation by
558 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
559 * @param core_if Programming view of DWC_otg controller.
560 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
561 * @param reset - indicates whether resume is initiated by Reset.
563 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
564 int rem_wakeup, int reset)
566 gpwrdn_data_t gpwrdn = {.d32 = 0 };
567 hprt0_data_t hprt0 = {.d32 = 0 };
571 DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
572 /* Switch-on voltage to the core */
573 gpwrdn.b.pwrdnswtch = 1;
574 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
579 gpwrdn.b.pwrdnrstn = 1;
580 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
583 /* Assert Restore signal */
585 gpwrdn.b.restore = 1;
586 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
589 /* Disable power clamps */
591 gpwrdn.b.pwrdnclmp = 1;
592 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
598 /* Deassert Reset core */
600 gpwrdn.b.pwrdnrstn = 1;
601 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
604 /* Disable PMU interrupt */
606 gpwrdn.b.pmuintsel = 1;
607 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
610 gpwrdn.b.connect_det_msk = 1;
611 gpwrdn.b.srp_det_msk = 1;
612 gpwrdn.b.disconn_det_msk = 1;
613 gpwrdn.b.rst_det_msk = 1;
614 gpwrdn.b.lnstchng_msk = 1;
615 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
617 /* Indicates that we are going out from hibernation */
618 core_if->hibernation_suspend = 0;
620 /* Set Restore Essential Regs bit in PCGCCTL register */
621 restore_essential_regs(core_if, rem_wakeup, 1);
623 /* Wait a little for seeing new value of variable hibernation_suspend if
624 * Restore done interrupt received before polling */
627 if (core_if->hibernation_suspend == 0) {
628 /* Wait For Restore_done Interrupt. This mechanism of polling the
629 * interrupt is introduced to avoid any possible race conditions
632 gintsts_data_t gintsts;
633 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
634 if (gintsts.b.restoredone) {
636 gintsts.b.restoredone = 1;
637 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
638 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");
644 DWC_WARN("Restore Done interrupt wasn't generated\n");
648 /* Set the flag's value to 0 again after receiving restore done interrupt */
649 core_if->hibernation_suspend = 0;
651 /* This step is not described in functional spec but if not wait for this
652 * delay, mismatch interrupts occurred because just after restore core is
653 * in Device mode(gintsts.curmode == 0) */
656 /* Clear all pending interrupts */
657 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
659 /* De-assert Restore */
661 gpwrdn.b.restore = 1;
662 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
665 /* Restore GUSBCFG and HCFG */
666 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
667 core_if->gr_backup->gusbcfg_local);
668 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
669 core_if->hr_backup->hcfg_local);
671 /* De-assert Wakeup Logic */
673 gpwrdn.b.pmuactv = 1;
674 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
677 /* Start the Resume operation by programming HPRT0 */
678 hprt0.d32 = core_if->hr_backup->hprt0_local;
682 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
684 DWC_PRINTF("Resume Starts Now\n");
685 if (!reset) { // Indicates it is Resume Operation
686 hprt0.d32 = core_if->hr_backup->hprt0_local;
691 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
695 /* Wait for Resume time and then program HPRT again */
697 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
699 } else { // Indicates it is Reset Operation
700 hprt0.d32 = core_if->hr_backup->hprt0_local;
705 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
706 /* Wait for Reset time and then program HPRT again */
709 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
711 /* Clear all interrupt status */
712 hprt0.d32 = dwc_otg_read_hprt0(core_if);
713 hprt0.b.prtconndet = 1;
714 hprt0.b.prtenchng = 1;
715 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
717 /* Clear all pending interupts */
718 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
720 /* Restore global registers */
721 dwc_otg_restore_global_regs(core_if);
722 /* Restore host global registers */
723 dwc_otg_restore_host_regs(core_if, reset);
725 /* The core will be in ON STATE */
726 core_if->lx_state = DWC_OTG_L0;
727 DWC_PRINTF("Hibernation recovery is complete here\n");
731 /** Saves some register values into system memory. */
732 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
734 struct dwc_otg_global_regs_backup *gr;
737 gr = core_if->gr_backup;
739 gr = DWC_ALLOC(sizeof(*gr));
741 return -DWC_E_NO_MEMORY;
743 core_if->gr_backup = gr;
746 gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
747 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
748 gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
749 gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
750 gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
751 gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
752 gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
753 #ifdef CONFIG_USB_DWC_OTG_LPM
754 gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
756 gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
757 gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
758 gr->gdfifocfg_local =
759 DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
760 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
761 gr->dtxfsiz_local[i] =
762 DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
765 DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
766 DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl = %08x\n", gr->gotgctl_local);
767 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
768 DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg = %08x\n", gr->gahbcfg_local);
769 DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg = %08x\n", gr->gusbcfg_local);
770 DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz = %08x\n", gr->grxfsiz_local);
771 DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
772 gr->gnptxfsiz_local);
773 DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz = %08x\n",
775 #ifdef CONFIG_USB_DWC_OTG_LPM
776 DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local);
778 DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl = %08x\n", gr->gi2cctl_local);
779 DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl = %08x\n", gr->pcgcctl_local);
780 DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg = %08x\n",gr->gdfifocfg_local);
785 /** Saves GINTMSK register before setting the msk bits. */
786 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
788 struct dwc_otg_global_regs_backup *gr;
790 gr = core_if->gr_backup;
792 gr = DWC_ALLOC(sizeof(*gr));
794 return -DWC_E_NO_MEMORY;
796 core_if->gr_backup = gr;
799 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
801 DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
802 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
807 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
809 struct dwc_otg_dev_regs_backup *dr;
812 dr = core_if->dr_backup;
814 dr = DWC_ALLOC(sizeof(*dr));
816 return -DWC_E_NO_MEMORY;
818 core_if->dr_backup = dr;
821 dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
822 dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
824 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
826 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
828 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
830 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
832 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
834 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
836 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
840 "=============Backing Host registers==============\n");
841 DWC_DEBUGPL(DBG_ANY, "Backed up dcfg = %08x\n", dr->dcfg);
842 DWC_DEBUGPL(DBG_ANY, "Backed up dctl = %08x\n", dr->dctl);
843 DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk = %08x\n",
845 DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk = %08x\n", dr->diepmsk);
846 DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk = %08x\n", dr->doepmsk);
847 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
848 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d] = %08x\n", i,
850 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n",
852 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i,
859 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
861 struct dwc_otg_host_regs_backup *hr;
864 hr = core_if->hr_backup;
866 hr = DWC_ALLOC(sizeof(*hr));
868 return -DWC_E_NO_MEMORY;
870 core_if->hr_backup = hr;
874 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
876 DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
877 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
878 hr->hcintmsk_local[i] =
879 DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
881 hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
883 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
886 "=============Backing Host registers===============\n");
887 DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n",
889 DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
890 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
891 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
892 hr->hcintmsk_local[i]);
894 DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n",
896 DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n",
902 int dwc_otg_restore_global_regs(dwc_otg_core_if_t * core_if)
904 struct dwc_otg_global_regs_backup *gr;
907 gr = core_if->gr_backup;
909 return -DWC_E_INVALID;
912 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
913 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
914 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
915 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
916 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
917 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
918 gr->gnptxfsiz_local);
919 DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
921 DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
922 gr->gdfifocfg_local);
923 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
924 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
925 gr->dtxfsiz_local[i]);
928 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
929 DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
930 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
931 (gr->gahbcfg_local));
935 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
937 struct dwc_otg_dev_regs_backup *dr;
940 dr = core_if->dr_backup;
943 return -DWC_E_INVALID;
947 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
951 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
952 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
953 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
955 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
956 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
957 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
958 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
964 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
966 struct dwc_otg_host_regs_backup *hr;
968 hr = core_if->hr_backup;
971 return -DWC_E_INVALID;
974 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
977 // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
980 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
982 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
983 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
984 hr->hcintmsk_local[i]);
990 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
992 struct dwc_otg_global_regs_backup *gr;
994 gr = core_if->gr_backup;
996 /* Restore values for LPM and I2C */
997 #ifdef CONFIG_USB_DWC_OTG_LPM
998 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
1000 DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
1005 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
1007 struct dwc_otg_global_regs_backup *gr;
1008 pcgcctl_data_t pcgcctl = {.d32 = 0 };
1009 gahbcfg_data_t gahbcfg = {.d32 = 0 };
1010 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1011 gintmsk_data_t gintmsk = {.d32 = 0 };
1013 /* Restore LPM and I2C registers */
1014 restore_lpm_i2c_regs(core_if);
1016 /* Set PCGCCTL to 0 */
1017 DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
1019 gr = core_if->gr_backup;
1020 /* Load restore values for [31:14] bits */
1021 DWC_WRITE_REG32(core_if->pcgcctl,
1022 ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
1024 /* Umnask global Interrupt in GAHBCFG and restore it */
1025 gahbcfg.d32 = gr->gahbcfg_local;
1026 gahbcfg.b.glblintrmsk = 1;
1027 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
1029 /* Clear all pending interupts */
1030 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
1032 /* Unmask restore done interrupt */
1033 gintmsk.b.restoredone = 1;
1034 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1036 /* Restore GUSBCFG and HCFG/DCFG */
1037 gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
1038 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
1041 hcfg_data_t hcfg = {.d32 = 0 };
1042 hcfg.d32 = core_if->hr_backup->hcfg_local;
1043 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
1046 /* Load restore values for [31:14] bits */
1047 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1048 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1051 pcgcctl.b.restoremode = 1;
1052 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1055 /* Load restore values for [31:14] bits and set EssRegRestored bit */
1056 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
1057 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1058 pcgcctl.b.ess_reg_restored = 1;
1060 pcgcctl.b.restoremode = 1;
1061 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1063 dcfg_data_t dcfg = {.d32 = 0 };
1064 dcfg.d32 = core_if->dr_backup->dcfg;
1065 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1067 /* Load restore values for [31:14] bits */
1068 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1069 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1071 pcgcctl.d32 |= 0x208;
1073 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1076 /* Load restore values for [31:14] bits */
1077 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1078 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1079 pcgcctl.b.ess_reg_restored = 1;
1081 pcgcctl.d32 |= 0x208;
1082 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1089 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1092 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
1097 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1098 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1099 (core_if->core_params->ulpi_fs_ls)) ||
1100 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1101 /* Full speed PHY */
1102 val = DWC_HCFG_48_MHZ;
1104 /* High speed PHY running at full speed or high speed */
1105 val = DWC_HCFG_30_60_MHZ;
1108 DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1109 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
1110 hcfg.b.fslspclksel = val;
1111 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1115 * Initializes the DevSpd field of the DCFG register depending on the PHY type
1116 * and the enumeration speed of the device.
1118 static void init_devspd(dwc_otg_core_if_t * core_if)
1123 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1124 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1125 (core_if->core_params->ulpi_fs_ls)) ||
1126 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1127 /* Full speed PHY */
1129 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1130 /* High speed PHY running at full speed */
1133 /* High speed PHY running at high speed */
1137 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1139 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
1140 dcfg.b.devspd = val;
1141 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1145 * This function calculates the number of IN EPS
1146 * using GHWCFG1 and GHWCFG2 registers values
1148 * @param core_if Programming view of the DWC_otg controller
1150 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
1152 uint32_t num_in_eps = 0;
1153 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1154 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
1155 uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
1158 for (i = 0; i < num_eps; ++i) {
1159 if (!(hwcfg1 & 0x1))
1165 if (core_if->hwcfg4.b.ded_fifo_en) {
1167 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1174 * This function calculates the number of OUT EPS
1175 * using GHWCFG1 and GHWCFG2 registers values
1177 * @param core_if Programming view of the DWC_otg controller
1179 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
1181 uint32_t num_out_eps = 0;
1182 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1183 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
1186 for (i = 0; i < num_eps; ++i) {
1187 if (!(hwcfg1 & 0x1))
1196 * This function initializes the DWC_otg controller registers and
1197 * prepares the core for device mode or host mode operation.
1199 * @param core_if Programming view of the DWC_otg controller
1202 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
1205 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1206 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1207 gahbcfg_data_t ahbcfg = {.d32 = 0 };
1208 gusbcfg_data_t usbcfg = {.d32 = 0 };
1209 gi2cctl_data_t i2cctl = {.d32 = 0 };
1211 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
1213 /* Common Initialization */
1214 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1216 /* Program the ULPI External VBUS bit if needed */
1217 usbcfg.b.ulpi_ext_vbus_drv =
1218 (core_if->core_params->phy_ulpi_ext_vbus ==
1219 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1221 /* Set external TS Dline pulsing */
1222 usbcfg.b.term_sel_dl_pulse =
1223 (core_if->core_params->ts_dline == 1) ? 1 : 0;
1224 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1226 /* Reset the Controller */
1227 dwc_otg_core_reset(core_if);
1229 core_if->adp_enable = core_if->core_params->adp_supp_enable;
1230 core_if->power_down = core_if->core_params->power_down;
1232 /* Initialize parameters from Hardware configuration registers. */
1233 dev_if->num_in_eps = calc_num_in_eps(core_if);
1234 dev_if->num_out_eps = calc_num_out_eps(core_if);
1236 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1237 core_if->hwcfg4.b.num_dev_perio_in_ep);
1239 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1240 dev_if->perio_tx_fifo_size[i] =
1241 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1242 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1243 i, dev_if->perio_tx_fifo_size[i]);
1246 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1247 dev_if->tx_fifo_size[i] =
1248 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1249 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1250 i, dev_if->tx_fifo_size[i]);
1253 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1254 core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
1255 core_if->nperio_tx_fifo_size =
1256 DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
1258 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1259 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1260 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
1261 core_if->nperio_tx_fifo_size);
1263 /* This programming sequence needs to happen in FS mode before any other
1264 * programming occurs */
1265 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1266 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1267 /* If FS mode with FS PHY */
1269 /* core_init() is now called on every switch so only call the
1270 * following for the first time through. */
1271 if (!core_if->phy_init_done) {
1272 core_if->phy_init_done = 1;
1273 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1274 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1275 usbcfg.b.physel = 1;
1276 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1278 /* Reset after a PHY select */
1279 dwc_otg_core_reset(core_if);
1282 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1283 * do this on HNP Dev/Host mode switches (done in dev_init and
1285 if (dwc_otg_is_host_mode(core_if)) {
1286 init_fslspclksel(core_if);
1288 init_devspd(core_if);
1291 if (core_if->core_params->i2c_enable) {
1292 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1293 /* Program GUSBCFG.OtgUtmifsSel to I2C */
1294 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1295 usbcfg.b.otgutmifssel = 1;
1296 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1298 /* Program GI2CCTL.I2CEn */
1299 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1300 i2cctl.b.i2cdevaddr = 1;
1302 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1304 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1307 } /* endif speed == DWC_SPEED_PARAM_FULL */
1309 /* High speed PHY. */
1310 if (!core_if->phy_init_done) {
1311 core_if->phy_init_done = 1;
1312 /* HS PHY parameters. These parameters are preserved
1313 * during soft reset so only program the first time. Do
1314 * a soft reset immediately after setting phyif. */
1316 if (core_if->core_params->phy_type == 2) {
1317 /* ULPI interface */
1318 usbcfg.b.ulpi_utmi_sel = 1;
1321 core_if->core_params->phy_ulpi_ddr;
1322 } else if (core_if->core_params->phy_type == 1) {
1323 /* UTMI+ interface */
1324 usbcfg.b.ulpi_utmi_sel = 0;
1325 if (core_if->core_params->phy_utmi_width == 16) {
1332 DWC_ERROR("FS PHY TYPE\n");
1334 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1335 /* Reset after setting the PHY parameters */
1336 dwc_otg_core_reset(core_if);
1340 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1341 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1342 (core_if->core_params->ulpi_fs_ls)) {
1343 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1344 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1345 usbcfg.b.ulpi_fsls = 1;
1346 usbcfg.b.ulpi_clk_sus_m = 1;
1347 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1349 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1350 usbcfg.b.ulpi_fsls = 0;
1351 usbcfg.b.ulpi_clk_sus_m = 0;
1352 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1355 /* Program the GAHBCFG Register. */
1356 switch (core_if->hwcfg2.b.architecture) {
1358 case DWC_SLAVE_ONLY_ARCH:
1359 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1360 ahbcfg.b.nptxfemplvl_txfemplvl =
1361 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1362 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1363 core_if->dma_enable = 0;
1364 core_if->dma_desc_enable = 0;
1367 case DWC_EXT_DMA_ARCH:
1368 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1370 uint8_t brst_sz = core_if->core_params->dma_burst_size;
1371 ahbcfg.b.hburstlen = 0;
1372 while (brst_sz > 1) {
1373 ahbcfg.b.hburstlen++;
1377 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1378 core_if->dma_desc_enable =
1379 (core_if->core_params->dma_desc_enable != 0);
1382 case DWC_INT_DMA_ARCH:
1383 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1384 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
1385 Host mode ISOC in issue fix - vahrama */
1386 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1387 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1388 core_if->dma_desc_enable =
1389 (core_if->core_params->dma_desc_enable != 0);
1393 if (core_if->dma_enable) {
1394 if (core_if->dma_desc_enable) {
1395 DWC_PRINTF("Using Descriptor DMA mode\n");
1397 DWC_PRINTF("Using Buffer DMA mode\n");
1400 DWC_PRINTF("Using Slave mode\n");
1401 core_if->dma_desc_enable = 0;
1404 if (core_if->core_params->ahb_single) {
1405 ahbcfg.b.ahbsingle = 1;
1408 ahbcfg.b.dmaenable = core_if->dma_enable;
1409 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1411 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1413 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1414 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1415 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1416 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
1417 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1418 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
1421 * Program the GUSBCFG register.
1423 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1425 switch (core_if->hwcfg2.b.op_mode) {
1426 case DWC_MODE_HNP_SRP_CAPABLE:
1427 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1428 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1429 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1430 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1433 case DWC_MODE_SRP_ONLY_CAPABLE:
1434 usbcfg.b.hnpcap = 0;
1435 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1436 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1439 case DWC_MODE_NO_HNP_SRP_CAPABLE:
1440 usbcfg.b.hnpcap = 0;
1441 usbcfg.b.srpcap = 0;
1444 case DWC_MODE_SRP_CAPABLE_DEVICE:
1445 usbcfg.b.hnpcap = 0;
1446 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1447 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1450 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1451 usbcfg.b.hnpcap = 0;
1452 usbcfg.b.srpcap = 0;
1455 case DWC_MODE_SRP_CAPABLE_HOST:
1456 usbcfg.b.hnpcap = 0;
1457 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1458 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1461 case DWC_MODE_NO_SRP_CAPABLE_HOST:
1462 usbcfg.b.hnpcap = 0;
1463 usbcfg.b.srpcap = 0;
1467 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1469 #ifdef CONFIG_USB_DWC_OTG_LPM
1470 if (core_if->core_params->lpm_enable) {
1471 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1473 /* To enable LPM support set lpm_cap_en bit */
1474 lpmcfg.b.lpm_cap_en = 1;
1476 /* Make AppL1Res ACK */
1477 lpmcfg.b.appl_resp = 1;
1480 lpmcfg.b.retry_count = 3;
1482 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1487 if (core_if->core_params->ic_usb_cap) {
1488 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1489 gusbcfg.b.ic_usb_cap = 1;
1490 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
1494 gotgctl_data_t gotgctl = {.d32 = 0 };
1495 gotgctl.b.otgver = core_if->core_params->otg_ver;
1496 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
1498 /* Set OTG version supported */
1499 core_if->otg_ver = core_if->core_params->otg_ver;
1500 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1501 core_if->core_params->otg_ver, core_if->otg_ver);
1504 /* Enable common interrupts */
1505 dwc_otg_enable_common_interrupts(core_if);
1507 /* Do device or host intialization based on mode during PCD
1508 * and HCD initialization */
1509 if (dwc_otg_is_host_mode(core_if)) {
1510 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
1511 core_if->op_state = A_HOST;
1513 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
1514 core_if->op_state = B_PERIPHERAL;
1515 #ifdef DWC_DEVICE_ONLY
1516 dwc_otg_core_dev_init(core_if);
1522 * This function enables the Device mode interrupts.
1524 * @param core_if Programming view of DWC_otg controller
1526 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
1528 gintmsk_data_t intr_mask = {.d32 = 0 };
1529 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1531 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1533 /* Disable all interrupts. */
1534 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
1536 /* Clear any pending interrupts */
1537 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
1539 /* Enable the common interrupts */
1540 dwc_otg_enable_common_interrupts(core_if);
1542 /* Enable interrupts */
1543 intr_mask.b.usbreset = 1;
1544 intr_mask.b.enumdone = 1;
1545 /* Disable Disconnect interrupt in Device mode */
1546 intr_mask.b.disconnect = 0;
1548 if (!core_if->multiproc_int_enable) {
1549 intr_mask.b.inepintr = 1;
1550 intr_mask.b.outepintr = 1;
1553 intr_mask.b.erlysuspend = 1;
1555 if (core_if->en_multiple_tx_fifo == 0) {
1556 intr_mask.b.epmismatch = 1;
1559 //intr_mask.b.incomplisoout = 1;
1560 intr_mask.b.incomplisoin = 1;
1562 /* Enable the ignore frame number for ISOC xfers - MAS */
1563 /* Disable to support high bandwith ISOC transfers - manukz */
1565 #ifdef DWC_UTE_PER_IO
1566 if (core_if->dma_enable) {
1567 if (core_if->dma_desc_enable) {
1568 dctl_data_t dctl1 = {.d32 = 0 };
1569 dctl1.b.ifrmnum = 1;
1570 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
1571 dctl, 0, dctl1.d32);
1572 DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
1573 DWC_READ_REG32(&core_if->dev_if->
1574 dev_global_regs->dctl));
1580 if (core_if->dma_enable) {
1581 if (core_if->dma_desc_enable == 0) {
1582 if (core_if->pti_enh_enable) {
1583 dctl_data_t dctl = {.d32 = 0 };
1585 DWC_MODIFY_REG32(&core_if->
1586 dev_if->dev_global_regs->dctl,
1589 intr_mask.b.incomplisoin = 1;
1590 intr_mask.b.incomplisoout = 1;
1594 intr_mask.b.incomplisoin = 1;
1595 intr_mask.b.incomplisoout = 1;
1597 #endif /* DWC_EN_ISOC */
1599 /** @todo NGS: Should this be a module parameter? */
1600 #ifdef USE_PERIODIC_EP
1601 intr_mask.b.isooutdrop = 1;
1602 intr_mask.b.eopframe = 1;
1603 intr_mask.b.incomplisoin = 1;
1604 intr_mask.b.incomplisoout = 1;
1607 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1609 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1610 DWC_READ_REG32(&global_regs->gintmsk));
1614 * This function initializes the DWC_otg controller registers for
1617 * @param core_if Programming view of DWC_otg controller
1620 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
1623 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1624 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1625 dwc_otg_core_params_t *params = core_if->core_params;
1626 dcfg_data_t dcfg = {.d32 = 0 };
1627 depctl_data_t diepctl = {.d32 = 0 };
1628 grstctl_t resetctl = {.d32 = 0 };
1629 uint32_t rx_fifo_size;
1630 fifosize_data_t nptxfifosize;
1631 fifosize_data_t txfifosize;
1632 dthrctl_data_t dthrctl;
1633 fifosize_data_t ptxfifosize;
1634 // uint16_t rxfsiz, nptxfsiz;
1635 // gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
1636 // hwcfg3_data_t hwcfg3 = {.d32 = 0 };
1637 gotgctl_data_t gotgctl = {.d32 = 0 };
1638 gahbcfg_data_t gahbcfg = {.d32 = 0};
1640 /* Restart the Phy Clock */
1641 pcgcctl_data_t pcgcctl = {.d32 = 0 };
1642 /* Restart the Phy Clock */
1643 pcgcctl.b.stoppclk = 1;
1644 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
1647 gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1648 DWC_MODIFY_REG32(&global_regs->gahbcfg, 0 , gahbcfg.b.hburstlen);
1650 /* Device configuration register */
1651 init_devspd(core_if);
1652 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1653 dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
1654 dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1655 /* Enable Device OUT NAK in case of DDMA mode */
1656 if (core_if->core_params->dev_out_nak) {
1657 dcfg.b.endevoutnak = 1;
1660 if (core_if->core_params->cont_on_bna) {
1661 dctl_data_t dctl = {.d32 = 0 };
1662 dctl.b.encontonbna = 1;
1663 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1665 /** should be done before every reset */
1666 if (core_if->otg_ver) {
1667 core_if->otg_sts = 0;
1668 gotgctl.b.devhnpen = 1;
1669 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, gotgctl.d32, 0);
1672 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1674 /* Configure data FIFO sizes */
1676 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1678 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
1679 core_if->init_rxfsiz = params->dev_rx_fifo_size;
1681 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1682 DWC_READ_REG32(&global_regs->grxfsiz));
1684 /** Set Periodic Tx FIFO Mask all bits 0 */
1685 core_if->p_tx_msk = 0;
1687 /** Set Tx FIFO Mask all bits 0 */
1688 core_if->tx_msk = 0;
1689 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
1690 * and ded_fifo_en is 1 in default*/
1691 if (core_if->en_multiple_tx_fifo == 0) {
1692 /* Non-periodic Tx FIFO */
1693 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1694 DWC_READ_REG32(&global_regs->gnptxfsiz));
1696 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1697 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1699 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1702 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1703 DWC_READ_REG32(&global_regs->gnptxfsiz));
1705 /**@todo NGS: Fix Periodic FIFO Sizing! */
1707 * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1708 * Indexes of the FIFO size module parameters in the
1709 * dev_perio_tx_fifo_size array and the FIFO size registers in
1710 * the dptxfsiz array run from 0 to 14.
1712 /** @todo Finish debug of this */
1713 ptxfifosize.b.startaddr =
1714 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1715 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1716 ptxfifosize.b.depth =
1717 params->dev_perio_tx_fifo_size[i];
1718 DWC_DEBUGPL(DBG_CIL,
1719 "initial dtxfsiz[%d]=%08x\n", i,
1720 DWC_READ_REG32(&global_regs->dtxfsiz
1722 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1724 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
1726 DWC_READ_REG32(&global_regs->dtxfsiz
1728 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
1732 * Tx FIFOs These FIFOs are numbered from 1 to 15.
1733 * Indexes of the FIFO size module parameters in the
1734 * dev_tx_fifo_size array and the FIFO size registers in
1735 * the dtxfsiz array run from 0 to 14.
1738 /* Non-periodic Tx FIFO */
1739 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1740 DWC_READ_REG32(&global_regs->gnptxfsiz));
1743 core_if->pwron_gnptxfsiz =
1744 (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1745 core_if->init_gnptxfsiz =
1746 params->dev_nperio_tx_fifo_size;
1748 rx_fifo_size = params->dev_rx_fifo_size;
1749 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
1750 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1751 DWC_READ_REG32(&global_regs->grxfsiz));
1753 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1754 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1755 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1758 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1759 DWC_READ_REG32(&global_regs->gnptxfsiz));
1761 txfifosize.b.startaddr =
1762 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1764 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1766 txfifosize.b.depth =
1767 params->dev_tx_fifo_size[i];
1769 DWC_DEBUGPL(DBG_CIL,
1770 "initial dtxfsiz[%d]=%08x\n",
1772 DWC_READ_REG32(&global_regs->dtxfsiz
1776 core_if->pwron_txfsiz[i] =
1778 (&global_regs->dtxfsiz[i]) >> 16);
1779 core_if->init_txfsiz[i] =
1780 params->dev_tx_fifo_size[i];
1782 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1785 DWC_DEBUGPL(DBG_CIL,
1786 "new dtxfsiz[%d]=%08x\n",
1788 DWC_READ_REG32(&global_regs->dtxfsiz
1791 txfifosize.b.startaddr += txfifosize.b.depth;
1794 /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO
1795 * Before 3.00a EpInfoBase was being configured in ep enable/disable
1796 * routine as well. Starting from 3.00a it will be set to the end of
1797 * allocated FIFO space here due to ep 0 OUT always keeping enabled
1799 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
1800 hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
1801 gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
1802 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1803 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
1804 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
1805 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1806 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
1808 gdfifocfg.b.epinfobase = txfifosize.b.startaddr;
1810 //DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1815 /* Flush the FIFOs */
1816 dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
1817 dwc_otg_flush_rx_fifo(core_if);
1819 /* Flush the Learning Queue. */
1820 resetctl.b.intknqflsh = 1;
1821 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
1823 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
1824 core_if->start_predict = 0;
1825 for (i = 0; i <= core_if->dev_if->num_in_eps; ++i) {
1826 core_if->nextep_seq[i] = 0xff; // 0xff - EP not active
1828 core_if->nextep_seq[0] = 0;
1829 core_if->first_in_nextep_seq = 0;
1830 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
1831 diepctl.b.nextep = 0;
1832 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
1834 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
1835 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1837 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1839 DWC_DEBUGPL(DBG_CILV,
1840 "%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->dev_global_regs->
1855 diepeachintmsk[i], 0);
1858 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1859 DWC_WRITE_REG32(&dev_if->dev_global_regs->
1860 doepeachintmsk[i], 0);
1863 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1864 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
1866 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
1867 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
1868 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1869 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
1872 for (i = 0; i <= dev_if->num_in_eps; i++) {
1873 depctl_data_t depctl;
1874 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
1875 if (depctl.b.epena) {
1883 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1885 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1886 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
1887 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1890 for (i = 1; i <= dev_if->num_out_eps; i++) {
1891 depctl_data_t depctl;
1892 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
1893 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);
1903 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
1905 DWC_ERROR("SNAK as not set during 10s\n");
1908 } while (!gintsts.b.goutnakeff);
1910 gintsts.b.goutnakeff = 1;
1911 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1917 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1920 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
1921 out_ep_regs[i]->doepint);
1923 DWC_ERROR("EPDIS was not set during 10s\n");
1926 } while (!doepint.b.epdisabled);
1928 doepint.b.epdisabled = 1;
1929 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32);
1932 dctl.b.cgoutnak = 1;
1933 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1938 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1939 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
1940 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
1941 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
1944 if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1945 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
1946 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
1947 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
1949 dev_if->rx_thr_length = params->rx_thr_length;
1950 dev_if->tx_thr_length = params->tx_thr_length;
1952 dev_if->setup_desc_index = 0;
1955 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1956 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1957 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1958 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1959 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1960 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
1962 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1965 DWC_DEBUGPL(DBG_CIL,
1966 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1967 dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1968 dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1969 dthrctl.b.rx_thr_len);
1973 dwc_otg_enable_device_interrupts(core_if);
1976 diepmsk_data_t msk = {.d32 = 0 };
1977 msk.b.txfifoundrn = 1;
1978 if (core_if->multiproc_int_enable) {
1979 DWC_MODIFY_REG32(&dev_if->dev_global_regs->
1980 diepeachintmsk[0], msk.d32, msk.d32);
1982 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
1987 if (core_if->multiproc_int_enable) {
1988 /* Set NAK on Babble */
1989 dctl_data_t dctl = {.d32 = 0 };
1990 dctl.b.nakonbble = 1;
1991 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1996 * This function enables the Host mode interrupts.
1998 * @param core_if Programming view of DWC_otg controller
2000 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
2002 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2003 gintmsk_data_t intr_mask = {.d32 = 0 };
2005 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
2007 /* Disable all interrupts. */
2008 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
2010 /* Clear any pending interrupts. */
2011 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
2013 /* Enable the common interrupts */
2014 dwc_otg_enable_common_interrupts(core_if);
2017 * Enable host mode interrupts without disturbing common
2021 intr_mask.b.disconnect = 1;
2022 intr_mask.b.portintr = 1;
2023 intr_mask.b.hcintr = 1;
2025 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2029 * This function disables the Host Mode interrupts.
2031 * @param core_if Programming view of DWC_otg controller
2033 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
2035 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2036 gintmsk_data_t intr_mask = {.d32 = 0 };
2038 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2041 * Disable host mode interrupts without disturbing common
2044 intr_mask.b.sofintr = 1;
2045 intr_mask.b.portintr = 1;
2046 intr_mask.b.hcintr = 1;
2047 intr_mask.b.ptxfempty = 1;
2048 intr_mask.b.nptxfempty = 1;
2050 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
2054 * This function initializes the DWC_otg controller registers for
2057 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2058 * request queues. Host channels are reset to ensure that they are ready for
2059 * performing transfers.
2061 * @param core_if Programming view of DWC_otg controller
2064 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
2066 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2067 dwc_otg_host_if_t *host_if = core_if->host_if;
2068 dwc_otg_core_params_t *params = core_if->core_params;
2069 hprt0_data_t hprt0 = {.d32 = 0 };
2070 fifosize_data_t nptxfifosize;
2071 fifosize_data_t ptxfifosize;
2072 // uint16_t rxfsiz, nptxfsiz, hptxfsiz;
2073 // gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
2075 hcchar_data_t hcchar;
2078 dwc_otg_hc_regs_t *hc_regs;
2080 gotgctl_data_t gotgctl = {.d32 = 0 };
2081 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2082 struct dwc_otg_platform_data *pldata;
2083 pldata = core_if->otg_dev->pldata;
2087 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
2089 /* Restart the Phy Clock */
2090 pcgcctl.b.stoppclk = 1;
2091 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
2094 if ((core_if->otg_ver == 1) && (core_if->op_state == A_HOST)) {
2095 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
2096 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2097 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2098 if (hprt0.b.prtpwr == 0) {
2100 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2104 /* Initialize Host Configuration Register */
2105 init_fslspclksel(core_if);
2106 if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
2107 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2108 hcfg.b.fslssupp = 1;
2109 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2113 /* This bit allows dynamic reloading of the HFIR register
2114 * during runtime. This bit needs to be programmed during
2115 * initial configuration and its value must not be changed
2117 if (core_if->core_params->reload_ctl == 1) {
2118 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
2119 hfir.b.hfirrldctrl = 1;
2120 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
2123 if (core_if->core_params->dma_desc_enable) {
2124 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
2126 (core_if->hwcfg4.b.desc_dma
2127 && (core_if->snpsid >= OTG_CORE_REV_2_90a)
2128 && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
2129 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
2131 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
2132 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
2134 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
2136 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
2137 "Either core version is below 2.90a or "
2138 "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
2139 "To run the driver in Buffer DMA host mode set dma_desc_enable "
2140 "module parameter to 0.\n");
2143 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2145 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2148 /* Configure data FIFO sizes */
2149 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2150 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
2151 core_if->total_fifo_size);
2152 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
2153 params->host_rx_fifo_size);
2154 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
2155 params->host_nperio_tx_fifo_size);
2156 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
2157 params->host_perio_tx_fifo_size);
2160 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
2161 DWC_READ_REG32(&global_regs->grxfsiz));
2162 DWC_WRITE_REG32(&global_regs->grxfsiz, 0x0200);//params->host_rx_fifo_size);
2163 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
2164 DWC_READ_REG32(&global_regs->grxfsiz));
2166 /* Non-periodic Tx FIFO */
2167 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2168 DWC_READ_REG32(&global_regs->gnptxfsiz));
2169 nptxfifosize.b.depth = 0x0080;//params->host_nperio_tx_fifo_size;
2170 nptxfifosize.b.startaddr = 0x0200;//params->host_rx_fifo_size;
2171 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2172 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2173 DWC_READ_REG32(&global_regs->gnptxfsiz));
2175 /* Periodic Tx FIFO */
2176 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
2177 DWC_READ_REG32(&global_regs->hptxfsiz));
2178 ptxfifosize.b.depth = 0x0100;//params->host_perio_tx_fifo_size;
2179 ptxfifosize.b.startaddr = 0x0280;//nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2180 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
2181 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
2182 DWC_READ_REG32(&global_regs->hptxfsiz));
2184 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
2185 * and ded_fifo_en is 1 in default
2187 if (core_if->en_multiple_tx_fifo) {
2188 /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
2189 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
2190 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
2191 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2192 hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
2193 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
2194 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2199 /* TODO - check this */
2200 /* Clear Host Set HNP Enable in the OTG Control Register */
2201 gotgctl.b.hstsethnpen = 1;
2202 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2203 /* Make sure the FIFOs are flushed. */
2204 dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ );
2205 dwc_otg_flush_rx_fifo(core_if);
2207 /* Clear Host Set HNP Enable in the OTG Control Register */
2208 gotgctl.b.hstsethnpen = 1;
2209 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2211 if (!core_if->core_params->dma_desc_enable) {
2212 /* Flush out any leftover queued requests. */
2213 num_channels = core_if->core_params->host_channels;
2215 for (i = 0; i < num_channels; i++) {
2216 hc_regs = core_if->host_if->hc_regs[i];
2217 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2221 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2224 /* Halt all channels to put them into a known state. */
2225 for (i = 0; i < num_channels; i++) {
2227 hc_regs = core_if->host_if->hc_regs[i];
2228 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2232 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2233 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
2235 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2236 if (++count > 1000) {
2238 ("%s: Unable to clear halt on channel %d\n",
2243 } while (hcchar.b.chen);
2247 /* Turn on the vbus power. */
2248 if ((core_if->otg_ver == 0) && (core_if->op_state == A_HOST)) {
2249 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2250 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2251 if (hprt0.b.prtpwr == 0) {
2253 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2255 if(pldata->power_enable)
2256 pldata->power_enable(1);
2259 dwc_otg_enable_host_interrupts(core_if);
2263 * Prepares a host channel for transferring packets to/from a specific
2264 * endpoint. The HCCHARn register is set up with the characteristics specified
2265 * in _hc. Host channel interrupts that may need to be serviced while this
2266 * transfer is in progress are enabled.
2268 * @param core_if Programming view of DWC_otg controller
2269 * @param hc Information needed to initialize the host channel
2271 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2273 uint32_t intr_enable;
2274 hcintmsk_data_t hc_intr_mask;
2275 gintmsk_data_t gintmsk = {.d32 = 0 };
2276 hcchar_data_t hcchar;
2277 hcsplt_data_t hcsplt;
2279 uint8_t hc_num = hc->hc_num;
2280 dwc_otg_host_if_t *host_if = core_if->host_if;
2281 dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2283 /* Clear old interrupt conditions for this host channel. */
2284 hc_intr_mask.d32 = 0xFFFFFFFF;
2285 hc_intr_mask.b.reserved14_31 = 0;
2286 DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
2288 /* Enable channel interrupts required for this transfer. */
2289 hc_intr_mask.d32 = 0;
2290 hc_intr_mask.b.chhltd = 1;
2291 if (core_if->dma_enable) {
2292 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
2293 if (!core_if->dma_desc_enable)
2294 hc_intr_mask.b.ahberr = 1;
2296 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2297 hc_intr_mask.b.xfercompl = 1;
2300 if (hc->error_state && !hc->do_split &&
2301 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2302 hc_intr_mask.b.ack = 1;
2304 hc_intr_mask.b.datatglerr = 1;
2305 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2306 hc_intr_mask.b.nak = 1;
2311 switch (hc->ep_type) {
2312 case DWC_OTG_EP_TYPE_CONTROL:
2313 case DWC_OTG_EP_TYPE_BULK:
2314 hc_intr_mask.b.xfercompl = 1;
2315 hc_intr_mask.b.stall = 1;
2316 hc_intr_mask.b.xacterr = 1;
2317 hc_intr_mask.b.datatglerr = 1;
2319 hc_intr_mask.b.bblerr = 1;
2321 hc_intr_mask.b.nak = 1;
2322 hc_intr_mask.b.nyet = 1;
2324 hc_intr_mask.b.ack = 1;
2329 hc_intr_mask.b.nak = 1;
2330 if (hc->complete_split) {
2331 hc_intr_mask.b.nyet = 1;
2333 hc_intr_mask.b.ack = 1;
2337 if (hc->error_state) {
2338 hc_intr_mask.b.ack = 1;
2341 case DWC_OTG_EP_TYPE_INTR:
2342 hc_intr_mask.b.xfercompl = 1;
2343 hc_intr_mask.b.nak = 1;
2344 hc_intr_mask.b.stall = 1;
2345 hc_intr_mask.b.xacterr = 1;
2346 hc_intr_mask.b.datatglerr = 1;
2347 hc_intr_mask.b.frmovrun = 1;
2350 hc_intr_mask.b.bblerr = 1;
2352 if (hc->error_state) {
2353 hc_intr_mask.b.ack = 1;
2356 if (hc->complete_split) {
2357 hc_intr_mask.b.nyet = 1;
2359 hc_intr_mask.b.ack = 1;
2363 case DWC_OTG_EP_TYPE_ISOC:
2364 hc_intr_mask.b.xfercompl = 1;
2365 hc_intr_mask.b.frmovrun = 1;
2366 hc_intr_mask.b.ack = 1;
2369 hc_intr_mask.b.xacterr = 1;
2370 hc_intr_mask.b.bblerr = 1;
2375 DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2377 /* Enable the top level host channel interrupt. */
2378 intr_enable = (1 << hc_num);
2379 DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
2381 /* Make sure host channel interrupts are enabled. */
2382 gintmsk.b.hcintr = 1;
2383 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
2386 * Program the HCCHARn register with the endpoint characteristics for
2387 * the current transfer.
2390 hcchar.b.devaddr = hc->dev_addr;
2391 hcchar.b.epnum = hc->ep_num;
2392 hcchar.b.epdir = hc->ep_is_in;
2393 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2394 hcchar.b.eptype = hc->ep_type;
2395 hcchar.b.mps = hc->max_packet;
2397 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2399 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2400 DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
2401 DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
2402 DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
2403 DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
2404 DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
2405 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2406 DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
2409 * Program the HCSPLIT register for SPLITs
2413 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
2415 hc->complete_split ? "CSPLIT" : "SSPLIT");
2416 hcsplt.b.compsplt = hc->complete_split;
2417 hcsplt.b.xactpos = hc->xact_pos;
2418 hcsplt.b.hubaddr = hc->hub_addr;
2419 hcsplt.b.prtaddr = hc->port_addr;
2420 DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
2421 DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
2422 DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
2423 DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
2424 DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
2425 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2426 DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
2428 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2433 * Attempts to halt a host channel. This function should only be called in
2434 * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2435 * normal circumstances in DMA mode, the controller halts the channel when the
2436 * transfer is complete or a condition occurs that requires application
2439 * In slave mode, checks for a free request queue entry, then sets the Channel
2440 * Enable and Channel Disable bits of the Host Channel Characteristics
2441 * register of the specified channel to intiate the halt. If there is no free
2442 * request queue entry, sets only the Channel Disable bit of the HCCHARn
2443 * register to flush requests for this channel. In the latter case, sets a
2444 * flag to indicate that the host channel needs to be halted when a request
2445 * queue slot is open.
2447 * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2448 * HCCHARn register. The controller ensures there is space in the request
2449 * queue before submitting the halt request.
2451 * Some time may elapse before the core flushes any posted requests for this
2452 * host channel and halts. The Channel Halted interrupt handler completes the
2453 * deactivation of the host channel.
2455 * @param core_if Controller register interface.
2456 * @param hc Host channel to halt.
2457 * @param halt_status Reason for halting the channel.
2459 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
2460 dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
2462 gnptxsts_data_t nptxsts;
2463 hptxsts_data_t hptxsts;
2464 hcchar_data_t hcchar;
2465 dwc_otg_hc_regs_t *hc_regs;
2466 dwc_otg_core_global_regs_t *global_regs;
2467 dwc_otg_host_global_regs_t *host_global_regs;
2469 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2470 global_regs = core_if->core_global_regs;
2471 host_global_regs = core_if->host_if->host_global_regs;
2473 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
2474 "halt_status = %d\n", halt_status);
2476 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2477 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2479 * Disable all channel interrupts except Ch Halted. The QTD
2480 * and QH state associated with this transfer has been cleared
2481 * (in the case of URB_DEQUEUE), so the channel needs to be
2482 * shut down carefully to prevent crashes.
2484 hcintmsk_data_t hcintmsk;
2486 hcintmsk.b.chhltd = 1;
2487 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
2490 * Make sure no other interrupts besides halt are currently
2491 * pending. Handling another interrupt could cause a crash due
2492 * to the QTD and QH state.
2494 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
2497 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2498 * even if the channel was already halted for some other
2501 hc->halt_status = halt_status;
2503 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2504 if (hcchar.b.chen == 0) {
2506 * The channel is either already halted or it hasn't
2507 * started yet. In DMA mode, the transfer may halt if
2508 * it finishes normally or a condition occurs that
2509 * requires driver intervention. Don't want to halt
2510 * the channel again. In either Slave or DMA mode,
2511 * it's possible that the transfer has been assigned
2512 * to a channel, but not started yet when an URB is
2513 * dequeued. Don't want to halt a channel that hasn't
2519 if (hc->halt_pending) {
2521 * A halt has already been issued for this channel. This might
2522 * happen when a transfer is aborted by a higher level in
2527 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2528 __func__, hc->hc_num);
2534 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2536 /* No need to set the bit in DDMA for disabling the channel */
2537 //TODO check it everywhere channel is disabled
2538 if (!core_if->core_params->dma_desc_enable)
2542 if (!core_if->dma_enable) {
2543 /* Check for space in the request queue to issue the halt. */
2544 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2545 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2546 nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
2547 if (nptxsts.b.nptxqspcavail == 0) {
2552 DWC_READ_REG32(&host_global_regs->hptxsts);
2553 if ((hptxsts.b.ptxqspcavail == 0)
2554 || (core_if->queuing_high_bandwidth)) {
2559 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2561 hc->halt_status = halt_status;
2563 if (hcchar.b.chen) {
2564 hc->halt_pending = 1;
2565 hc->halt_on_queue = 0;
2567 hc->halt_on_queue = 1;
2570 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2571 DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
2572 DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
2573 DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
2574 DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
2580 * Clears the transfer state for a host channel. This function is normally
2581 * called after a transfer is done and the host channel is being released.
2583 * @param core_if Programming view of DWC_otg controller.
2584 * @param hc Identifies the host channel to clean up.
2586 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2588 dwc_otg_hc_regs_t *hc_regs;
2590 hc->xfer_started = 0;
2593 * Clear channel interrupt enables and any unhandled channel interrupt
2596 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2597 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
2598 DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
2600 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
2605 * Sets the channel property that indicates in which frame a periodic transfer
2606 * should occur. This is always set to the _next_ frame. This function has no
2607 * effect on non-periodic transfers.
2609 * @param core_if Programming view of DWC_otg controller.
2610 * @param hc Identifies the host channel to set up and its properties.
2611 * @param hcchar Current value of the HCCHAR register for the specified host
2614 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
2615 dwc_hc_t * hc, hcchar_data_t * hcchar)
2617 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2618 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2621 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
2623 /* 1 if _next_ frame is odd, 0 if it's even */
2624 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2626 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
2627 && !hc->complete_split) {
2628 switch (hfnum.b.frnum & 0x7) {
2630 core_if->hfnum_7_samples++;
2631 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2634 core_if->hfnum_0_samples++;
2635 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2638 core_if->hfnum_other_samples++;
2639 core_if->hfnum_other_frrem_accum +=
2649 void hc_xfer_timeout(void *ptr)
2651 hc_xfer_info_t *xfer_info = NULL;
2655 xfer_info = (hc_xfer_info_t *) ptr;
2657 if (!xfer_info->hc) {
2658 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
2662 hc_num = xfer_info->hc->hc_num;
2663 DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2664 DWC_WARN(" start_hcchar_val 0x%08x\n",
2665 xfer_info->core_if->start_hcchar_val[hc_num]);
2669 void ep_xfer_timeout(void *ptr)
2671 ep_xfer_info_t *xfer_info = NULL;
2673 dctl_data_t dctl = {.d32 = 0 };
2674 gintsts_data_t gintsts = {.d32 = 0 };
2675 gintmsk_data_t gintmsk = {.d32 = 0 };
2678 xfer_info = (ep_xfer_info_t *) ptr;
2680 if (!xfer_info->ep) {
2681 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
2685 ep_num = xfer_info->ep->num;
2686 DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
2687 /* Put the sate to 2 as it was time outed */
2688 xfer_info->state = 2;
2691 DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl);
2693 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts);
2695 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk);
2697 if (!gintmsk.b.goutnakeff) {
2699 gintmsk.b.goutnakeff = 1;
2700 DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk,
2705 if (!gintsts.b.goutnakeff) {
2706 dctl.b.sgoutnak = 1;
2708 DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl,
2713 void set_pid_isoc(dwc_hc_t * hc)
2715 /* Set up the initial PID for the transfer. */
2716 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2718 if (hc->multi_count == 1) {
2719 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2720 } else if (hc->multi_count == 2) {
2721 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2723 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2726 if (hc->multi_count == 1) {
2727 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2729 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2733 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2738 * This function does the setup for a data transfer for a host channel and
2739 * starts the transfer. May be called in either Slave mode or DMA mode. In
2740 * Slave mode, the caller must ensure that there is sufficient space in the
2741 * request queue and Tx Data FIFO.
2743 * For an OUT transfer in Slave mode, it loads a data packet into the
2744 * appropriate FIFO. If necessary, additional data packets will be loaded in
2747 * For an IN transfer in Slave mode, a data packet is requested. The data
2748 * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2749 * additional data packets are requested in the Host ISR.
2751 * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2752 * register along with a packet count of 1 and the channel is enabled. This
2753 * causes a single PING transaction to occur. Other fields in HCTSIZ are
2754 * simply set to 0 since no data transfer occurs in this case.
2756 * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2757 * all the information required to perform the subsequent data transfer. In
2758 * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2759 * controller performs the entire PING protocol, then starts the data
2762 * @param core_if Programming view of DWC_otg controller.
2763 * @param hc Information needed to initialize the host channel. The xfer_len
2764 * value may be reduced to accommodate the max widths of the XferSize and
2765 * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2766 * to reflect the final xfer_len value.
2768 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2770 hcchar_data_t hcchar;
2771 hctsiz_data_t hctsiz;
2772 uint16_t num_packets;
2773 uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
2774 uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
2775 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2780 if (!core_if->dma_enable) {
2781 dwc_otg_hc_do_ping(core_if, hc);
2782 hc->xfer_started = 1;
2792 if (hc->complete_split && !hc->ep_is_in) {
2793 /* For CSPLIT OUT Transfer, set the size to 0 so the
2794 * core doesn't expect any data written to the FIFO */
2796 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
2797 hc->xfer_len = hc->max_packet;
2798 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
2802 hctsiz.b.xfersize = hc->xfer_len;
2805 * Ensure that the transfer length and packet count will fit
2806 * in the widths allocated for them in the HCTSIZn register.
2808 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2809 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2811 * Make sure the transfer size is no larger than one
2812 * (micro)frame's worth of data. (A check was done
2813 * when the periodic transfer was accepted to ensure
2814 * that a (micro)frame's worth of data can be
2815 * programmed into a channel.)
2817 uint32_t max_periodic_len =
2818 hc->multi_count * hc->max_packet;
2819 if (hc->xfer_len > max_periodic_len) {
2820 hc->xfer_len = max_periodic_len;
2823 } else if (hc->xfer_len > max_hc_xfer_size) {
2824 /* Make sure that xfer_len is a multiple of max packet size. */
2825 hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
2828 if (hc->xfer_len > 0) {
2830 (hc->xfer_len + hc->max_packet -
2831 1) / hc->max_packet;
2832 if (num_packets > max_hc_pkt_count) {
2833 num_packets = max_hc_pkt_count;
2834 hc->xfer_len = num_packets * hc->max_packet;
2837 /* Need 1 packet for transfer length of 0. */
2842 /* Always program an integral # of max packets for IN transfers. */
2843 hc->xfer_len = num_packets * hc->max_packet;
2846 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2847 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2849 * Make sure that the multi_count field matches the
2850 * actual transfer length.
2852 hc->multi_count = num_packets;
2855 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2858 hctsiz.b.xfersize = hc->xfer_len;
2861 hc->start_pkt_count = num_packets;
2862 hctsiz.b.pktcnt = num_packets;
2863 hctsiz.b.pid = hc->data_pid_start;
2864 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2866 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2867 DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
2868 DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
2869 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2871 if (core_if->dma_enable) {
2873 if (hc->align_buff) {
2874 dma_addr = hc->align_buff;
2876 dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
2878 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
2881 /* Start the split */
2883 hcsplt_data_t hcsplt;
2884 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
2885 hcsplt.b.spltena = 1;
2886 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
2889 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2890 hcchar.b.multicnt = hc->multi_count;
2891 hc_set_even_odd_frame(core_if, hc, &hcchar);
2893 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2894 if (hcchar.b.chdis) {
2895 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2896 __func__, hc->hc_num, hcchar.d32);
2900 /* Set host channel enable after all other setup is complete. */
2903 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2905 hc->xfer_started = 1;
2908 if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
2909 /* Load OUT packet into the appropriate Tx FIFO. */
2910 dwc_otg_hc_write_packet(core_if, hc);
2913 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2914 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2915 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2917 /* Start a timer for this transfer. */
2918 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2924 * This function does the setup for a data transfer for a host channel
2925 * and starts the transfer in Descriptor DMA mode.
2927 * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set.
2928 * Sets PID and NTD values. For periodic transfers
2929 * initializes SCHED_INFO field with micro-frame bitmap.
2931 * Initializes HCDMA register with descriptor list address and CTD value
2932 * then starts the transfer via enabling the channel.
2934 * @param core_if Programming view of DWC_otg controller.
2935 * @param hc Information needed to initialize the host channel.
2937 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2939 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2940 hcchar_data_t hcchar;
2941 hctsiz_data_t hctsiz;
2947 hctsiz.b_ddma.dopng = 1;
2949 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2952 /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
2953 hctsiz.b_ddma.pid = hc->data_pid_start;
2954 hctsiz.b_ddma.ntd = hc->ntd - 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
2955 hctsiz.b_ddma.schinfo = hc->schinfo; /* Non-zero only for high-speed interrupt endpoints */
2957 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2958 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
2959 DWC_DEBUGPL(DBG_HCDV, " NTD: %d\n", hctsiz.b_ddma.ntd);
2961 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2964 hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
2966 /* Always start from first descriptor. */
2968 DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
2970 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2971 hcchar.b.multicnt = hc->multi_count;
2974 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2975 if (hcchar.b.chdis) {
2976 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2977 __func__, hc->hc_num, hcchar.d32);
2981 /* Set host channel enable after all other setup is complete. */
2985 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2987 hc->xfer_started = 1;
2991 if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
2992 && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
2993 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2994 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2995 /* Start a timer for this transfer. */
2996 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
3003 * This function continues a data transfer that was started by previous call
3004 * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
3005 * sufficient space in the request queue and Tx Data FIFO. This function
3006 * should only be called in Slave mode. In DMA mode, the controller acts
3007 * autonomously to complete transfers programmed to a host channel.
3009 * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
3010 * if there is any data remaining to be queued. For an IN transfer, another
3011 * data packet is always requested. For the SETUP phase of a control transfer,
3012 * this function does nothing.
3014 * @return 1 if a new request is queued, 0 if no more requests are required
3015 * for this transfer.
3017 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3019 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3022 /* SPLITs always queue just once per channel */
3024 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
3025 /* SETUPs are queued only once since they can't be NAKed. */
3027 } else if (hc->ep_is_in) {
3029 * Always queue another request for other IN transfers. If
3030 * back-to-back INs are issued and NAKs are received for both,
3031 * the driver may still be processing the first NAK when the
3032 * second NAK is received. When the interrupt handler clears
3033 * the NAK interrupt for the first NAK, the second NAK will
3034 * not be seen. So we can't depend on the NAK interrupt
3035 * handler to requeue a NAKed request. Instead, IN requests
3036 * are issued each time this function is called. When the
3037 * transfer completes, the extra requests for the channel will
3040 hcchar_data_t hcchar;
3041 dwc_otg_hc_regs_t *hc_regs =
3042 core_if->host_if->hc_regs[hc->hc_num];
3044 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3045 hc_set_even_odd_frame(core_if, hc, &hcchar);
3048 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
3050 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3054 /* OUT transfers. */
3055 if (hc->xfer_count < hc->xfer_len) {
3056 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3057 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3058 hcchar_data_t hcchar;
3059 dwc_otg_hc_regs_t *hc_regs;
3060 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3061 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3062 hc_set_even_odd_frame(core_if, hc, &hcchar);
3065 /* Load OUT packet into the appropriate Tx FIFO. */
3066 dwc_otg_hc_write_packet(core_if, hc);
3076 * Starts a PING transfer. This function should only be called in Slave mode.
3077 * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
3079 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3081 hcchar_data_t hcchar;
3082 hctsiz_data_t hctsiz;
3083 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3085 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3089 hctsiz.b.pktcnt = 1;
3090 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3092 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3095 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3099 * This function writes a packet into the Tx FIFO associated with the Host
3100 * Channel. For a channel associated with a non-periodic EP, the non-periodic
3101 * Tx FIFO is written. For a channel associated with a periodic EP, the
3102 * periodic Tx FIFO is written. This function should only be called in Slave
3105 * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
3106 * then number of bytes written to the Tx FIFO.
3108 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3111 uint32_t remaining_count;
3112 uint32_t byte_count;
3113 uint32_t dword_count;
3115 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
3116 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
3118 remaining_count = hc->xfer_len - hc->xfer_count;
3119 if (remaining_count > hc->max_packet) {
3120 byte_count = hc->max_packet;
3122 byte_count = remaining_count;
3125 dword_count = (byte_count + 3) / 4;
3127 if ((((unsigned long)data_buff) & 0x3) == 0) {
3128 /* xfer_buff is DWORD aligned. */
3129 for (i = 0; i < dword_count; i++, data_buff++) {
3130 DWC_WRITE_REG32(data_fifo, *data_buff);
3133 /* xfer_buff is not DWORD aligned. */
3134 for (i = 0; i < dword_count; i++, data_buff++) {
3137 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
3138 16 | data_buff[3] << 24);
3139 DWC_WRITE_REG32(data_fifo, data);
3143 hc->xfer_count += byte_count;
3144 hc->xfer_buff += byte_count;
3148 * Gets the current USB frame number. This is the frame number from the last
3151 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
3154 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
3156 /* read current frame/microframe number from DSTS register */
3157 return dsts.b.soffn;
3161 * Calculates and gets the frame Interval value of HFIR register according PHY
3162 * type and speed.The application can modify a value of HFIR register only after
3163 * the Port Enable bit of the Host Port Control and Status register
3164 * (HPRT.PrtEnaPort) has been set.
3167 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
3169 gusbcfg_data_t usbcfg;
3170 hwcfg2_data_t hwcfg2;
3172 int clock = 60; // default value
3173 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
3174 hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
3175 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
3176 if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3178 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
3180 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3181 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3183 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3184 !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3186 if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3187 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3189 if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
3191 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
3193 if (hprt0.b.prtspd == 0)
3194 /* High speed case */
3198 return 1000 * clock;
3202 * This function reads a setup packet from the Rx FIFO into the destination
3203 * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3204 * Interrupt routine when a SETUP packet has been received in Slave mode.
3206 * @param core_if Programming view of DWC_otg controller.
3207 * @param dest Destination buffer for packet data.
3209 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
3211 device_grxsts_data_t status;
3212 /* Get the 8 bytes of a setup transaction data */
3214 /* Pop 2 DWORDS off the receive data FIFO into memory */
3215 dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
3216 dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
3217 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
3219 DWC_READ_REG32(&core_if->core_global_regs->grxstsp);
3220 DWC_DEBUGPL(DBG_ANY,
3221 "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n",
3222 status.b.epnum, status.b.bcnt, status.b.pktsts,
3223 status.b.fn, status.b.fn);
3228 * This function enables EP0 OUT to receive SETUP packets and configures EP0
3229 * IN for transmitting packets. It is normally called when the
3230 * "Enumeration Done" interrupt occurs.
3232 * @param core_if Programming view of DWC_otg controller.
3233 * @param ep The EP0 data.
3235 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3237 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3239 depctl_data_t diepctl;
3240 depctl_data_t doepctl;
3241 dctl_data_t dctl = {.d32 = 0 };
3243 ep->stp_rollover = 0;
3244 /* Read the Device Status and Endpoint 0 Control registers */
3245 dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
3246 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
3247 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
3249 /* Set the MPS of the IN EP based on the enumeration speed */
3250 switch (dsts.b.enumspd) {
3251 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
3252 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
3253 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
3254 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
3256 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3257 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3261 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3263 /* Enable OUT EP for receive */
3264 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
3265 doepctl.b.epena = 1;
3266 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
3269 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
3270 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
3271 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
3272 DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
3274 dctl.b.cgnpinnak = 1;
3276 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3277 DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
3278 DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
3283 * This function activates an EP. The Device EP control register for
3284 * the EP is configured as defined in the ep structure. Note: This
3285 * function is not used for EP0.
3287 * @param core_if Programming view of DWC_otg controller.
3288 * @param ep The EP to activate.
3290 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3292 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3293 depctl_data_t depctl;
3294 volatile uint32_t *addr;
3295 daint_data_t daintmsk = {.d32 = 0 };
3299 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3300 (ep->is_in ? "IN" : "OUT"));
3302 #ifdef DWC_UTE_PER_IO
3303 ep->xiso_frame_num = 0xFFFFFFFF;
3304 ep->xiso_active_xfers = 0;
3305 ep->xiso_queued_xfers = 0;
3307 /* Read DEPCTLn register */
3308 if (ep->is_in == 1) {
3309 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
3310 daintmsk.ep.in = 1 << ep->num;
3312 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3313 daintmsk.ep.out = 1 << ep->num;
3316 /* If the EP is already active don't change the EP Control
3318 depctl.d32 = DWC_READ_REG32(addr);
3319 if (!depctl.b.usbactep) {
3320 depctl.b.mps = ep->maxpacket;
3321 depctl.b.eptype = ep->type;
3322 depctl.b.txfnum = ep->tx_fifo_num;
3324 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3325 depctl.b.setd0pid = 1; // ???
3327 depctl.b.setd0pid = 1;
3329 depctl.b.usbactep = 1;
3331 /* Update nextep_seq array and EPMSCNT in DCFG */
3332 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) { // NP IN EP
3333 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3334 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
3337 core_if->nextep_seq[i] = ep->num;
3338 core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
3339 depctl.b.nextep = core_if->nextep_seq[ep->num];
3340 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
3342 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3344 DWC_DEBUGPL(DBG_PCDV,
3345 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3346 __func__, core_if->first_in_nextep_seq);
3347 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3348 DWC_DEBUGPL(DBG_PCDV, "%2d\n",
3349 core_if->nextep_seq[i]);
3355 DWC_WRITE_REG32(addr, depctl.d32);
3356 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
3359 /* Enable the Interrupt for this EP */
3360 if (core_if->multiproc_int_enable) {
3361 if (ep->is_in == 1) {
3362 diepmsk_data_t diepmsk = {.d32 = 0 };
3363 diepmsk.b.xfercompl = 1;
3364 diepmsk.b.timeout = 1;
3365 diepmsk.b.epdisabled = 1;
3366 diepmsk.b.ahberr = 1;
3367 diepmsk.b.intknepmis = 1;
3368 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
3369 diepmsk.b.intknepmis = 0;
3370 diepmsk.b.txfifoundrn = 1; //?????
3371 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3376 if (core_if->dma_desc_enable) {
3381 if (core_if->dma_enable) {
3385 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3386 diepeachintmsk[ep->num], diepmsk.d32);
3389 doepmsk_data_t doepmsk = {.d32 = 0 };
3390 doepmsk.b.xfercompl = 1;
3391 doepmsk.b.ahberr = 1;
3392 doepmsk.b.epdisabled = 1;
3393 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3394 doepmsk.b.outtknepdis = 1;
3398 if (core_if->dma_desc_enable) {
3403 doepmsk.b.babble = 1;
3407 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3408 doepeachintmsk[ep->num], doepmsk.d32);
3410 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
3413 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3415 diepmsk_data_t diepmsk = {.d32 = 0 };
3417 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
3419 doepmsk_data_t doepmsk = {.d32 = 0 };
3420 doepmsk.b.outtknepdis = 1;
3421 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
3424 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
3428 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
3429 DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
3431 ep->stall_clear_flag = 0;
3437 * This function deactivates an EP. This is done by clearing the USB Active
3438 * EP bit in the Device EP control register. Note: This function is not used
3439 * for EP0. EP0 cannot be deactivated.
3441 * @param core_if Programming view of DWC_otg controller.
3442 * @param ep The EP to deactivate.
3444 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3446 depctl_data_t depctl = {.d32 = 0 };
3447 volatile uint32_t *addr;
3448 daint_data_t daintmsk = {.d32 = 0 };
3452 #ifdef DWC_UTE_PER_IO
3453 ep->xiso_frame_num = 0xFFFFFFFF;
3454 ep->xiso_active_xfers = 0;
3455 ep->xiso_queued_xfers = 0;
3458 /* Read DEPCTLn register */
3459 if (ep->is_in == 1) {
3460 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3461 daintmsk.ep.in = 1 << ep->num;
3463 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3464 daintmsk.ep.out = 1 << ep->num;
3467 depctl.d32 = DWC_READ_REG32(addr);
3469 depctl.b.usbactep = 0;
3471 /* Update nextep_seq array and EPMSCNT in DCFG */
3472 if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN
3473 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3474 if (core_if->nextep_seq[i] == ep->num)
3477 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];
3478 if (core_if->first_in_nextep_seq == ep->num)
3479 core_if->first_in_nextep_seq = i;
3480 core_if->nextep_seq[ep->num] = 0xff;
3481 depctl.b.nextep = 0;
3483 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
3485 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
3488 DWC_DEBUGPL(DBG_PCDV,
3489 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3490 __func__, core_if->first_in_nextep_seq);
3491 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3492 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
3497 depctl.b.txfnum = 0;
3499 if (core_if->dma_desc_enable)
3502 DWC_WRITE_REG32(addr, depctl.d32);
3503 depctl.d32 = DWC_READ_REG32(addr);
3504 if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC
3505 && depctl.b.epena) {
3506 depctl_data_t depctl = {.d32 = 0 };
3508 diepint_data_t diepint = {.d32 = 0 };
3511 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3512 diepctl, depctl.d32);
3516 DWC_READ_REG32(&core_if->
3517 dev_if->in_ep_regs[ep->num]->
3519 } while (!diepint.b.inepnakeff);
3520 diepint.b.inepnakeff = 1;
3521 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3522 diepint, diepint.d32);
3525 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3526 diepctl, depctl.d32);
3530 DWC_READ_REG32(&core_if->
3531 dev_if->in_ep_regs[ep->num]->
3533 } while (!diepint.b.epdisabled);
3534 diepint.b.epdisabled = 1;
3535 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3536 diepint, diepint.d32);
3538 dctl_data_t dctl = {.d32 = 0};
3539 gintmsk_data_t gintsts = {.d32 = 0};
3540 doepint_data_t doepint = {.d32 = 0};
3541 dctl.b.sgoutnak = 1;
3542 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3546 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
3547 } while (!gintsts.b.goutnakeff);
3549 gintsts.b.goutnakeff = 1;
3550 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
3555 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
3559 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
3560 out_ep_regs[ep->num]->doepint);
3561 } while (!doepint.b.epdisabled);
3563 doepint.b.epdisabled = 1;
3564 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
3567 dctl.b.cgoutnak = 1;
3568 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
3572 /* Disable the Interrupt for this EP */
3573 if (core_if->multiproc_int_enable) {
3574 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
3577 if (ep->is_in == 1) {
3578 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3579 diepeachintmsk[ep->num], 0);
3581 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3582 doepeachintmsk[ep->num], 0);
3585 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
3592 * This function initializes dma descriptor chain.
3594 * @param core_if Programming view of DWC_otg controller.
3595 * @param ep The EP to start the transfer on.
3597 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3599 dwc_otg_dev_dma_desc_t *dma_desc;
3603 unsigned maxxfer_local, total_len;
3605 if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR &&
3606 (ep->maxpacket % 4)) {
3607 maxxfer_local = ep->maxpacket;
3608 total_len = ep->xfer_len;
3610 maxxfer_local = ep->maxxfer;
3611 total_len = ep->total_len;
3614 ep->desc_cnt = (total_len / maxxfer_local) +
3615 ((total_len % maxxfer_local) ? 1 : 0);
3620 if (ep->desc_cnt > MAX_DMA_DESC_CNT)
3621 ep->desc_cnt = MAX_DMA_DESC_CNT;
3623 dma_desc = ep->desc_addr;
3624 if (maxxfer_local == ep->maxpacket) {
3625 if ((total_len % maxxfer_local) &&
3626 (total_len / maxxfer_local < MAX_DMA_DESC_CNT)) {
3627 xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
3628 (total_len % maxxfer_local);
3630 xfer_est = ep->desc_cnt * maxxfer_local;
3632 xfer_est = total_len;
3634 for (i = 0; i < ep->desc_cnt; ++i) {
3635 /** DMA Descriptor Setup */
3636 if (xfer_est > maxxfer_local) {
3637 dma_desc->status.b.bs = BS_HOST_BUSY;
3638 dma_desc->status.b.l = 0;
3639 dma_desc->status.b.ioc = 0;
3640 dma_desc->status.b.sp = 0;
3641 dma_desc->status.b.bytes = maxxfer_local;
3642 dma_desc->buf = ep->dma_addr + offset;
3643 dma_desc->status.b.sts = 0;
3644 dma_desc->status.b.bs = BS_HOST_READY;
3646 xfer_est -= maxxfer_local;
3647 offset += maxxfer_local;
3649 dma_desc->status.b.bs = BS_HOST_BUSY;
3650 dma_desc->status.b.l = 1;
3651 dma_desc->status.b.ioc = 1;
3653 dma_desc->status.b.sp =
3655 ep->maxpacket) ? 1 : ((ep->
3657 dma_desc->status.b.bytes = xfer_est;
3659 if (maxxfer_local == ep->maxpacket)
3660 dma_desc->status.b.bytes = xfer_est;
3662 dma_desc->status.b.bytes =
3663 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
3666 dma_desc->buf = ep->dma_addr + offset;
3667 dma_desc->status.b.sts = 0;
3668 dma_desc->status.b.bs = BS_HOST_READY;
3675 * This function is called when to write ISOC data into appropriate dedicated
3678 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
3680 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3681 dwc_otg_dev_in_ep_regs_t *ep_regs;
3682 dtxfsts_data_t txstatus = {.d32 = 0 };
3684 int epnum = dwc_ep->num;
3687 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
3689 ep_regs = core_if->dev_if->in_ep_regs[epnum];
3691 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3693 if (len > dwc_ep->maxpacket) {
3694 len = dwc_ep->maxpacket;
3697 dwords = (len + 3) / 4;
3699 /* While there is space in the queue and space in the FIFO and
3700 * More data to tranfer, Write packets to the Tx FIFO */
3701 txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3702 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
3704 while (txstatus.b.txfspcavail > dwords &&
3705 dwc_ep->xfer_count < dwc_ep->xfer_len && dwc_ep->xfer_len != 0) {
3706 /* Write the FIFO */
3707 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
3709 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3710 if (len > dwc_ep->maxpacket) {
3711 len = dwc_ep->maxpacket;
3714 dwords = (len + 3) / 4;
3716 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3717 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
3721 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
3722 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
3728 * This function does the setup for a data transfer for an EP and
3729 * starts the transfer. For an IN transfer, the packets will be
3730 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3731 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3733 * @param core_if Programming view of DWC_otg controller.
3734 * @param ep The EP to start the transfer on.
3737 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3739 depctl_data_t depctl;
3740 deptsiz_data_t deptsiz;
3741 gintmsk_data_t intr_mask = {.d32 = 0 };
3743 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3744 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3745 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
3746 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
3747 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
3750 if (ep->is_in == 1) {
3751 dwc_otg_dev_in_ep_regs_t *in_regs =
3752 core_if->dev_if->in_ep_regs[ep->num];
3754 gnptxsts_data_t gtxstatus;
3757 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
3759 if (core_if->en_multiple_tx_fifo == 0
3760 && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) {
3762 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3767 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
3768 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
3770 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3771 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3772 ep->maxxfer : (ep->total_len - ep->xfer_len);
3774 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
3775 MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3778 /* Zero Length Packet? */
3779 if ((ep->xfer_len - ep->xfer_count) == 0) {
3780 deptsiz.b.xfersize = 0;
3781 deptsiz.b.pktcnt = 1;
3783 /* Program the transfer size and packet count
3784 * as follows: xfersize = N * maxpacket +
3785 * short_packet pktcnt = N + (short_packet
3788 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3790 (ep->xfer_len - ep->xfer_count - 1 +
3791 ep->maxpacket) / ep->maxpacket;
3792 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3793 deptsiz.b.pktcnt = MAX_PKT_CNT;
3794 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
3796 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3797 deptsiz.b.mc = deptsiz.b.pktcnt;
3800 /* Write the DMA register */
3801 if (core_if->dma_enable) {
3802 if (core_if->dma_desc_enable == 0) {
3803 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
3805 DWC_WRITE_REG32(&in_regs->dieptsiz,
3807 DWC_WRITE_REG32(&(in_regs->diepdma),
3808 (uint32_t) ep->dma_addr);
3811 /* The descriptor chain should be already initialized by now */
3812 if (ep->buff_mode != BM_STANDARD) {
3813 DWC_WRITE_REG32(&in_regs->diepdma,
3814 ep->descs_dma_addr);
3817 init_dma_desc_chain(core_if, ep);
3818 /** DIEPDMAn Register write */
3819 DWC_WRITE_REG32(&in_regs->diepdma,
3826 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
3827 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
3829 * Enable the Non-Periodic Tx FIFO empty interrupt,
3830 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3831 * the data will be written into the fifo by the ISR.
3833 if (core_if->en_multiple_tx_fifo == 0) {
3834 intr_mask.b.nptxfempty = 1;
3836 (&core_if->core_global_regs->gintmsk,
3837 intr_mask.d32, intr_mask.d32);
3839 /* Enable the Tx FIFO Empty Interrupt for this EP */
3840 if (ep->xfer_len > 0) {
3841 uint32_t fifoemptymsk = 0;
3842 fifoemptymsk = 1 << ep->num;
3844 (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3850 write_isoc_tx_fifo(core_if, ep);
3853 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
3854 depctl.b.nextep = core_if->nextep_seq[ep->num];
3856 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3857 dsts_data_t dsts = {.d32 = 0 };
3858 if (ep->bInterval == 1) {
3860 DWC_READ_REG32(&core_if->dev_if->
3861 dev_global_regs->dsts);
3862 ep->frame_num = dsts.b.soffn + ep->bInterval;
3863 if (ep->frame_num > 0x3FFF) {
3864 ep->frm_overrun = 1;
3865 ep->frame_num &= 0x3FFF;
3867 ep->frm_overrun = 0;
3868 if (ep->frame_num & 0x1) {
3869 depctl.b.setd1pid = 1;
3871 depctl.b.setd0pid = 1;
3875 /* EP enable, IN data in FIFO */
3878 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
3882 dwc_otg_dev_out_ep_regs_t *out_regs =
3883 core_if->dev_if->out_ep_regs[ep->num];
3885 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
3886 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
3888 if (!core_if->dma_desc_enable) {
3889 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3890 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3891 ep->maxxfer : (ep->total_len - ep->xfer_len);
3893 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len
3894 - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3897 /* Program the transfer size and packet count as follows:
3900 * xfersize = N * maxpacket
3902 if ((ep->xfer_len - ep->xfer_count) == 0) {
3903 /* Zero Length Packet */
3904 deptsiz.b.xfersize = ep->maxpacket;
3905 deptsiz.b.pktcnt = 1;
3908 (ep->xfer_len - ep->xfer_count +
3909 (ep->maxpacket - 1)) / ep->maxpacket;
3910 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3911 deptsiz.b.pktcnt = MAX_PKT_CNT;
3913 if (!core_if->dma_desc_enable) {
3915 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
3917 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3920 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3921 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
3923 if (core_if->dma_enable) {
3924 if (!core_if->dma_desc_enable) {
3925 DWC_WRITE_REG32(&out_regs->doeptsiz,
3928 DWC_WRITE_REG32(&(out_regs->doepdma),
3929 (uint32_t) ep->dma_addr);
3932 /* The descriptor chain should be already initialized by now */
3933 if (ep->buff_mode != BM_STANDARD) {
3934 DWC_WRITE_REG32(&out_regs->doepdma,
3935 ep->descs_dma_addr);
3938 /** This is used for interrupt out transfers*/
3940 ep->xfer_len = ep->total_len;
3941 init_dma_desc_chain(core_if, ep);
3943 if (core_if->core_params->dev_out_nak) {
3944 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
3945 deptsiz.b.pktcnt = (ep->total_len +
3946 (ep->maxpacket - 1)) / ep->maxpacket;
3947 deptsiz.b.xfersize = ep->total_len;
3948 /* Remember initial value of doeptsiz */
3949 core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
3950 DWC_WRITE_REG32(&out_regs->doeptsiz,
3954 /** DOEPDMAn Register write */
3955 DWC_WRITE_REG32(&out_regs->doepdma,
3962 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
3965 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3966 dsts_data_t dsts = {.d32 = 0 };
3967 if (ep->bInterval == 1) {
3969 DWC_READ_REG32(&core_if->dev_if->
3970 dev_global_regs->dsts);
3971 ep->frame_num = dsts.b.soffn + ep->bInterval;
3972 if (ep->frame_num > 0x3FFF) {
3973 ep->frm_overrun = 1;
3974 ep->frame_num &= 0x3FFF;
3976 ep->frm_overrun = 0;
3978 if (ep->frame_num & 0x1) {
3979 depctl.b.setd1pid = 1;
3981 depctl.b.setd0pid = 1;
3990 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
3992 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3993 DWC_READ_REG32(&out_regs->doepctl),
3994 DWC_READ_REG32(&out_regs->doeptsiz));
3995 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3996 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->
3998 DWC_READ_REG32(&core_if->core_global_regs->
4001 /* Timer is scheduling only for out bulk transfers for
4002 * "Device DDMA OUT NAK Enhancement" feature to inform user
4003 * about received data payload in case of timeout
4005 if (core_if->core_params->dev_out_nak) {
4006 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
4007 core_if->ep_xfer_info[ep->num].core_if = core_if;
4008 core_if->ep_xfer_info[ep->num].ep = ep;
4009 core_if->ep_xfer_info[ep->num].state = 1;
4011 /* Start a timer for this transfer. */
4012 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
4019 * This function setup a zero length transfer in Buffer DMA and
4020 * Slave modes for usb requests with zero field set
4022 * @param core_if Programming view of DWC_otg controller.
4023 * @param ep The EP to start the transfer on.
4026 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4029 depctl_data_t depctl;
4030 deptsiz_data_t deptsiz;
4031 gintmsk_data_t intr_mask = {.d32 = 0 };
4033 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4034 DWC_PRINTF("zero length transfer is called\n");
4037 if (ep->is_in == 1) {
4038 dwc_otg_dev_in_ep_regs_t *in_regs =
4039 core_if->dev_if->in_ep_regs[ep->num];
4041 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4042 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4044 deptsiz.b.xfersize = 0;
4045 deptsiz.b.pktcnt = 1;
4047 /* Write the DMA register */
4048 if (core_if->dma_enable) {
4049 if (core_if->dma_desc_enable == 0) {
4051 DWC_WRITE_REG32(&in_regs->dieptsiz,
4053 DWC_WRITE_REG32(&(in_regs->diepdma),
4054 (uint32_t) ep->dma_addr);
4057 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4059 * Enable the Non-Periodic Tx FIFO empty interrupt,
4060 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4061 * the data will be written into the fifo by the ISR.
4063 if (core_if->en_multiple_tx_fifo == 0) {
4064 intr_mask.b.nptxfempty = 1;
4065 DWC_MODIFY_REG32(&core_if->
4066 core_global_regs->gintmsk,
4067 intr_mask.d32, intr_mask.d32);
4069 /* Enable the Tx FIFO Empty Interrupt for this EP */
4070 if (ep->xfer_len > 0) {
4071 uint32_t fifoemptymsk = 0;
4072 fifoemptymsk = 1 << ep->num;
4073 DWC_MODIFY_REG32(&core_if->
4074 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4080 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4081 depctl.b.nextep = core_if->nextep_seq[ep->num];
4082 /* EP enable, IN data in FIFO */
4085 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4089 dwc_otg_dev_out_ep_regs_t *out_regs =
4090 core_if->dev_if->out_ep_regs[ep->num];
4092 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4093 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4095 /* Zero Length Packet */
4096 deptsiz.b.xfersize = ep->maxpacket;
4097 deptsiz.b.pktcnt = 1;
4099 if (core_if->dma_enable) {
4100 if (!core_if->dma_desc_enable) {
4101 DWC_WRITE_REG32(&out_regs->doeptsiz,
4104 DWC_WRITE_REG32(&(out_regs->doepdma),
4105 (uint32_t) ep->dma_addr);
4108 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4115 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4121 * This function does the setup for a data transfer for EP0 and starts
4122 * the transfer. For an IN transfer, the packets will be loaded into
4123 * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
4124 * unloaded from the Rx FIFO in the ISR.
4126 * @param core_if Programming view of DWC_otg controller.
4127 * @param ep The EP0 data.
4129 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4131 depctl_data_t depctl;
4132 deptsiz0_data_t deptsiz;
4133 gintmsk_data_t intr_mask = {.d32 = 0 };
4134 dwc_otg_dev_dma_desc_t *dma_desc;
4136 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4137 "xfer_buff=%p start_xfer_buff=%p \n",
4138 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
4139 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
4141 ep->total_len = ep->xfer_len;
4144 if (ep->is_in == 1) {
4145 dwc_otg_dev_in_ep_regs_t *in_regs =
4146 core_if->dev_if->in_ep_regs[0];
4148 gnptxsts_data_t gtxstatus;
4150 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4151 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4157 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4159 /* If dedicated FIFO every time flush fifo before enable ep*/
4160 if (core_if->en_multiple_tx_fifo && core_if->snpsid >= OTG_CORE_REV_3_00a)
4161 dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
4163 if (core_if->en_multiple_tx_fifo == 0
4164 && gtxstatus.b.nptxqspcavail == 0
4165 && !core_if->dma_enable) {
4167 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4168 DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
4169 DWC_READ_REG32(&in_regs->diepctl));
4170 DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
4172 deptsiz.b.xfersize, deptsiz.b.pktcnt);
4173 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4179 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4180 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4182 /* Zero Length Packet? */
4183 if (ep->xfer_len == 0) {
4184 deptsiz.b.xfersize = 0;
4185 deptsiz.b.pktcnt = 1;
4187 /* Program the transfer size and packet count
4188 * as follows: xfersize = N * maxpacket +
4189 * short_packet pktcnt = N + (short_packet
4192 if (ep->xfer_len > ep->maxpacket) {
4193 ep->xfer_len = ep->maxpacket;
4194 deptsiz.b.xfersize = ep->maxpacket;
4196 deptsiz.b.xfersize = ep->xfer_len;
4198 deptsiz.b.pktcnt = 1;
4201 DWC_DEBUGPL(DBG_PCDV,
4202 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4203 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4206 /* Write the DMA register */
4207 if (core_if->dma_enable) {
4208 if (core_if->dma_desc_enable == 0) {
4209 DWC_WRITE_REG32(&in_regs->dieptsiz,
4212 DWC_WRITE_REG32(&(in_regs->diepdma),
4213 (uint32_t) ep->dma_addr);
4215 dma_desc = core_if->dev_if->in_desc_addr;
4217 /** DMA Descriptor Setup */
4218 dma_desc->status.b.bs = BS_HOST_BUSY;
4219 dma_desc->status.b.l = 1;
4220 dma_desc->status.b.ioc = 1;
4221 dma_desc->status.b.sp =
4222 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4223 dma_desc->status.b.bytes = ep->xfer_len;
4224 dma_desc->buf = ep->dma_addr;
4225 dma_desc->status.b.sts = 0;
4226 dma_desc->status.b.bs = BS_HOST_READY;
4228 /** DIEPDMA0 Register write */
4229 DWC_WRITE_REG32(&in_regs->diepdma,
4231 dev_if->dma_in_desc_addr);
4234 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4237 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4238 depctl.b.nextep = core_if->nextep_seq[ep->num];
4239 /* EP enable, IN data in FIFO */
4242 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4245 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4246 * data will be written into the fifo by the ISR.
4248 if (!core_if->dma_enable) {
4249 if (core_if->en_multiple_tx_fifo == 0) {
4250 intr_mask.b.nptxfempty = 1;
4251 DWC_MODIFY_REG32(&core_if->
4252 core_global_regs->gintmsk,
4253 intr_mask.d32, intr_mask.d32);
4255 /* Enable the Tx FIFO Empty Interrupt for this EP */
4256 if (ep->xfer_len > 0) {
4257 uint32_t fifoemptymsk = 0;
4258 fifoemptymsk |= 1 << ep->num;
4259 DWC_MODIFY_REG32(&core_if->
4260 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4267 dwc_otg_dev_out_ep_regs_t *out_regs =
4268 core_if->dev_if->out_ep_regs[0];
4270 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4271 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4273 /* Program the transfer size and packet count as follows:
4274 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4276 /* Zero Length Packet */
4277 deptsiz.b.xfersize = ep->maxpacket;
4278 deptsiz.b.pktcnt = 1;
4279 if (core_if->snpsid >= OTG_CORE_REV_3_00a)
4280 deptsiz.b.supcnt = 3;
4282 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
4283 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4285 if (core_if->dma_enable) {
4286 if (!core_if->dma_desc_enable) {
4287 DWC_WRITE_REG32(&out_regs->doeptsiz,
4290 DWC_WRITE_REG32(&(out_regs->doepdma),
4291 (uint32_t) ep->dma_addr);
4293 dma_desc = core_if->dev_if->out_desc_addr;
4295 /** DMA Descriptor Setup */
4296 dma_desc->status.b.bs = BS_HOST_BUSY;
4297 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4298 dma_desc->status.b.mtrf = 0;
4299 dma_desc->status.b.sr = 0;
4301 dma_desc->status.b.l = 1;
4302 dma_desc->status.b.ioc = 1;
4303 dma_desc->status.b.bytes = ep->maxpacket;
4304 dma_desc->buf = ep->dma_addr;
4305 dma_desc->status.b.sts = 0;
4306 dma_desc->status.b.bs = BS_HOST_READY;
4308 /** DOEPDMA0 Register write */
4309 DWC_WRITE_REG32(&out_regs->doepdma,
4314 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4320 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
4325 * This function continues control IN transfers started by
4326 * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
4327 * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
4328 * bit for the packet count.
4330 * @param core_if Programming view of DWC_otg controller.
4331 * @param ep The EP0 data.
4333 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4335 depctl_data_t depctl;
4336 deptsiz0_data_t deptsiz;
4337 gintmsk_data_t intr_mask = {.d32 = 0 };
4338 dwc_otg_dev_dma_desc_t *dma_desc;
4340 if (ep->is_in == 1) {
4341 dwc_otg_dev_in_ep_regs_t *in_regs =
4342 core_if->dev_if->in_ep_regs[0];
4343 gnptxsts_data_t tx_status = {.d32 = 0 };
4346 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4347 /** @todo Should there be check for room in the Tx
4348 * Status Queue. If not remove the code above this comment. */
4350 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4351 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4353 /* Program the transfer size and packet count
4354 * as follows: xfersize = N * maxpacket +
4355 * short_packet pktcnt = N + (short_packet
4359 if (core_if->dma_desc_enable == 0) {
4360 deptsiz.b.xfersize =
4361 (ep->total_len - ep->xfer_count) >
4362 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4364 deptsiz.b.pktcnt = 1;
4365 if (core_if->dma_enable == 0) {
4366 ep->xfer_len += deptsiz.b.xfersize;
4368 ep->xfer_len = deptsiz.b.xfersize;
4370 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4373 (ep->total_len - ep->xfer_count) >
4374 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4377 dma_desc = core_if->dev_if->in_desc_addr;
4379 /** DMA Descriptor Setup */
4380 dma_desc->status.b.bs = BS_HOST_BUSY;
4381 dma_desc->status.b.l = 1;
4382 dma_desc->status.b.ioc = 1;
4383 dma_desc->status.b.sp =
4384 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4385 dma_desc->status.b.bytes = ep->xfer_len;
4386 dma_desc->buf = ep->dma_addr;
4387 dma_desc->status.b.sts = 0;
4388 dma_desc->status.b.bs = BS_HOST_READY;
4390 /** DIEPDMA0 Register write */
4391 DWC_WRITE_REG32(&in_regs->diepdma,
4392 core_if->dev_if->dma_in_desc_addr);
4395 DWC_DEBUGPL(DBG_PCDV,
4396 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4397 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4400 /* Write the DMA register */
4401 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4402 if (core_if->dma_desc_enable == 0)
4403 DWC_WRITE_REG32(&(in_regs->diepdma),
4404 (uint32_t) ep->dma_addr);
4406 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4407 depctl.b.nextep = core_if->nextep_seq[ep->num];
4408 /* EP enable, IN data in FIFO */
4411 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4414 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4415 * data will be written into the fifo by the ISR.
4417 if (!core_if->dma_enable) {
4418 if (core_if->en_multiple_tx_fifo == 0) {
4419 /* First clear it from GINTSTS */
4420 intr_mask.b.nptxfempty = 1;
4421 DWC_MODIFY_REG32(&core_if->
4422 core_global_regs->gintmsk,
4423 intr_mask.d32, intr_mask.d32);
4426 /* Enable the Tx FIFO Empty Interrupt for this EP */
4427 if (ep->xfer_len > 0) {
4428 uint32_t fifoemptymsk = 0;
4429 fifoemptymsk |= 1 << ep->num;
4430 DWC_MODIFY_REG32(&core_if->
4431 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4437 dwc_otg_dev_out_ep_regs_t *out_regs =
4438 core_if->dev_if->out_ep_regs[0];
4440 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4441 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4443 /* Program the transfer size and packet count
4444 * as follows: xfersize = N * maxpacket +
4445 * short_packet pktcnt = N + (short_packet
4448 deptsiz.b.xfersize = ep->maxpacket;
4449 deptsiz.b.pktcnt = 1;
4451 if (core_if->dma_desc_enable == 0) {
4452 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4454 dma_desc = core_if->dev_if->out_desc_addr;
4456 /** DMA Descriptor Setup */
4457 dma_desc->status.b.bs = BS_HOST_BUSY;
4458 dma_desc->status.b.l = 1;
4459 dma_desc->status.b.ioc = 1;
4460 dma_desc->status.b.bytes = ep->maxpacket;
4461 dma_desc->buf = ep->dma_addr;
4462 dma_desc->status.b.sts = 0;
4463 dma_desc->status.b.bs = BS_HOST_READY;
4465 /** DOEPDMA0 Register write */
4466 DWC_WRITE_REG32(&out_regs->doepdma,
4467 core_if->dev_if->dma_out_desc_addr);
4470 DWC_DEBUGPL(DBG_PCDV,
4471 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4472 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4475 /* Write the DMA register */
4476 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4477 if (core_if->dma_desc_enable == 0)
4478 DWC_WRITE_REG32(&(out_regs->doepdma),
4479 (uint32_t) ep->dma_addr);
4483 /* EP enable, IN data in FIFO */
4486 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4492 void dump_msg(const u8 * buf, unsigned int length)
4494 unsigned int start, num, i;
4500 while (length > 0) {
4501 num = length < 16u ? length : 16u;
4503 for (i = 0; i < num; ++i) {
4506 DWC_SPRINTF(p, " %02x", buf[i]);
4510 DWC_PRINTF("%6x: %s\n", start, line);
4517 static inline void dump_msg(const u8 * buf, unsigned int length)
4523 * This function writes a packet into the Tx FIFO associated with the
4524 * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
4525 * periodic EPs the periodic Tx FIFO associated with the EP is written
4526 * with all packets for the next micro-frame.
4528 * @param core_if Programming view of DWC_otg controller.
4529 * @param ep The EP to write packet for.
4530 * @param dma Indicates if DMA is being used.
4532 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
4536 * The buffer is padded to DWORD on a per packet basis in
4537 * slave/dma mode if the MPS is not DWORD aligned. The last
4538 * packet, if short, is also padded to a multiple of DWORD.
4540 * ep->xfer_buff always starts DWORD aligned in memory and is a
4541 * multiple of DWORD in length
4543 * ep->xfer_len can be any number of bytes
4545 * ep->xfer_count is a multiple of ep->maxpacket until the last
4548 * FIFO access is DWORD */
4551 uint32_t byte_count;
4552 uint32_t dword_count;
4554 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
4556 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
4558 if (ep->xfer_count >= ep->xfer_len) {
4559 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4563 /* Find the byte length of the packet either short packet or MPS */
4564 if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
4565 byte_count = ep->xfer_len - ep->xfer_count;
4567 byte_count = ep->maxpacket;
4570 /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4571 * is not a multiple of DWORD */
4572 dword_count = (byte_count + 3) / 4;
4575 dump_msg(ep->xfer_buff, byte_count);
4578 /**@todo NGS Where are the Periodic Tx FIFO addresses
4579 * intialized? What should this be? */
4581 fifo = core_if->data_fifo[ep->num];
4583 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
4584 fifo, data_buff, *data_buff, byte_count);
4587 for (i = 0; i < dword_count; i++, data_buff++) {
4588 DWC_WRITE_REG32(fifo, *data_buff);
4592 ep->xfer_count += byte_count;
4593 ep->xfer_buff += byte_count;
4594 ep->dma_addr += byte_count;
4600 * @param core_if Programming view of DWC_otg controller.
4601 * @param ep The EP to set the stall on.
4603 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4605 depctl_data_t depctl;
4606 volatile uint32_t *depctl_addr;
4608 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4609 (ep->is_in ? "IN" : "OUT"));
4611 if (ep->is_in == 1) {
4612 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4613 depctl.d32 = DWC_READ_REG32(depctl_addr);
4615 /* set the disable and stall bits */
4616 if (depctl.b.epena) {
4620 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4622 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4623 depctl.d32 = DWC_READ_REG32(depctl_addr);
4625 /* set the stall bit */
4627 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4630 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4636 * Clear the EP STALL.
4638 * @param core_if Programming view of DWC_otg controller.
4639 * @param ep The EP to clear stall from.
4641 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4643 depctl_data_t depctl;
4644 volatile uint32_t *depctl_addr;
4646 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4647 (ep->is_in ? "IN" : "OUT"));
4649 if (ep->is_in == 1) {
4650 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4652 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4655 depctl.d32 = DWC_READ_REG32(depctl_addr);
4657 /* clear the stall bits */
4661 * USB Spec 9.4.5: For endpoints using data toggle, regardless
4662 * of whether an endpoint has the Halt feature set, a
4663 * ClearFeature(ENDPOINT_HALT) request always results in the
4664 * data toggle being reinitialized to DATA0.
4666 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4667 ep->type == DWC_OTG_EP_TYPE_BULK) {
4668 depctl.b.setd0pid = 1; /* DATA0 */
4671 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4672 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4677 * This function reads a packet from the Rx FIFO into the destination
4678 * buffer. To read SETUP data use dwc_otg_read_setup_packet.
4680 * @param core_if Programming view of DWC_otg controller.
4681 * @param dest Destination buffer for the packet.
4682 * @param bytes Number of bytes to copy to the destination.
4684 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
4685 uint8_t * dest, uint16_t bytes)
4688 int word_count = (bytes + 3) / 4;
4690 volatile uint32_t *fifo = core_if->data_fifo[0];
4691 uint32_t *data_buff = (uint32_t *) dest;
4694 * @todo Account for the case where _dest is not dword aligned. This
4695 * requires reading data from the FIFO into a uint32_t temp buffer,
4696 * then moving it into the data buffer.
4699 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
4700 core_if, dest, bytes);
4702 for (i = 0; i < word_count; i++, data_buff++) {
4703 *data_buff = DWC_READ_REG32(fifo);
4710 * This functions reads the device registers and prints them
4712 * @param core_if Programming view of DWC_otg controller.
4714 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
4717 volatile uint32_t *addr;
4720 hwcfg1 = ~core_if->core_global_regs->ghwcfg1;
4722 DWC_PRINTF("Device Global Registers\n");
4723 addr = &core_if->dev_if->dev_global_regs->dcfg;
4724 DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n",
4725 (unsigned long)addr, DWC_READ_REG32(addr));
4726 addr = &core_if->dev_if->dev_global_regs->dctl;
4727 DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n",
4728 (unsigned long)addr, DWC_READ_REG32(addr));
4729 addr = &core_if->dev_if->dev_global_regs->dsts;
4730 DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n",
4731 (unsigned long)addr, DWC_READ_REG32(addr));
4732 addr = &core_if->dev_if->dev_global_regs->diepmsk;
4733 DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4734 DWC_READ_REG32(addr));
4735 addr = &core_if->dev_if->dev_global_regs->doepmsk;
4736 DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4737 DWC_READ_REG32(addr));
4738 addr = &core_if->dev_if->dev_global_regs->daint;
4739 DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4740 DWC_READ_REG32(addr));
4741 addr = &core_if->dev_if->dev_global_regs->daintmsk;
4742 DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4743 DWC_READ_REG32(addr));
4744 addr = &core_if->dev_if->dev_global_regs->dtknqr1;
4745 DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4746 DWC_READ_REG32(addr));
4747 if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
4748 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
4749 DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n",
4750 (unsigned long)addr, DWC_READ_REG32(addr));
4753 addr = &core_if->dev_if->dev_global_regs->dvbusdis;
4754 DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
4755 DWC_READ_REG32(addr));
4757 addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
4758 DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n",
4759 (unsigned long)addr, DWC_READ_REG32(addr));
4761 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
4762 DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n",
4763 (unsigned long)addr, DWC_READ_REG32(addr));
4765 if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
4766 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4767 DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n",
4768 (unsigned long)addr, DWC_READ_REG32(addr));
4771 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4772 DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4773 DWC_READ_REG32(addr));
4775 if (core_if->hwcfg2.b.multi_proc_int) {
4777 addr = &core_if->dev_if->dev_global_regs->deachint;
4778 DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n",
4779 (unsigned long)addr, DWC_READ_REG32(addr));
4780 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
4781 DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n",
4782 (unsigned long)addr, DWC_READ_REG32(addr));
4784 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
4787 dev_global_regs->diepeachintmsk[i];
4788 DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4789 i, (unsigned long)addr,
4790 DWC_READ_REG32(addr));
4793 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
4796 dev_global_regs->doepeachintmsk[i];
4797 DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4798 i, (unsigned long)addr,
4799 DWC_READ_REG32(addr));
4803 for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
4804 if(hwcfg1 & (2<<(i<<1))){
4805 DWC_PRINTF("Device IN EP %d Registers\n", i);
4806 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
4807 DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n",
4808 (unsigned long)addr, DWC_READ_REG32(addr));
4809 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
4810 DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n",
4811 (unsigned long)addr, DWC_READ_REG32(addr));
4812 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
4813 DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n",
4814 (unsigned long)addr, DWC_READ_REG32(addr));
4815 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
4816 DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n",
4817 (unsigned long)addr, DWC_READ_REG32(addr));
4818 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
4819 DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n",
4820 (unsigned long)addr, DWC_READ_REG32(addr));
4821 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
4822 DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n",
4823 (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ );
4827 for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
4828 if(hwcfg1 & (1<<(i<<1))){
4829 DWC_PRINTF("Device OUT EP %d Registers\n", i);
4830 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
4831 DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n",
4832 (unsigned long)addr, DWC_READ_REG32(addr));
4833 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
4834 DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n",
4835 (unsigned long)addr, DWC_READ_REG32(addr));
4836 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
4837 DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n",
4838 (unsigned long)addr, DWC_READ_REG32(addr));
4839 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
4840 DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n",
4841 (unsigned long)addr, DWC_READ_REG32(addr));
4842 if (core_if->dma_enable) { /* Don't access this register in SLAVE mode */
4843 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
4844 DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n",
4845 (unsigned long)addr, DWC_READ_REG32(addr));
4853 * This functions reads the SPRAM and prints its content
4855 * @param core_if Programming view of DWC_otg controller.
4857 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
4859 volatile uint8_t *addr, *start_addr, *end_addr;
4861 DWC_PRINTF("SPRAM Data:\n");
4862 start_addr = (void *)core_if->core_global_regs;
4863 DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
4864 start_addr += 0x00028000;
4865 end_addr = (void *)core_if->core_global_regs;
4866 end_addr += 0x000280e0;
4868 for (addr = start_addr; addr < end_addr; addr += 16) {
4870 ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
4871 (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
4872 addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
4873 addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
4881 * This function reads the host registers and prints them
4883 * @param core_if Programming view of DWC_otg controller.
4885 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
4888 volatile uint32_t *addr;
4890 DWC_PRINTF("Host Global Registers\n");
4891 addr = &core_if->host_if->host_global_regs->hcfg;
4892 DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n",
4893 (unsigned long)addr, DWC_READ_REG32(addr));
4894 addr = &core_if->host_if->host_global_regs->hfir;
4895 DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n",
4896 (unsigned long)addr, DWC_READ_REG32(addr));
4897 addr = &core_if->host_if->host_global_regs->hfnum;
4898 DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr,
4899 DWC_READ_REG32(addr));
4900 addr = &core_if->host_if->host_global_regs->hptxsts;
4901 DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4902 DWC_READ_REG32(addr));
4903 addr = &core_if->host_if->host_global_regs->haint;
4904 DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4905 DWC_READ_REG32(addr));
4906 addr = &core_if->host_if->host_global_regs->haintmsk;
4907 DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4908 DWC_READ_REG32(addr));
4909 if (core_if->dma_desc_enable) {
4910 addr = &core_if->host_if->host_global_regs->hflbaddr;
4911 DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n",
4912 (unsigned long)addr, DWC_READ_REG32(addr));
4915 addr = core_if->host_if->hprt0;
4916 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4917 DWC_READ_REG32(addr));
4919 for (i = 0; i < core_if->core_params->host_channels; i++) {
4920 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
4921 addr = &core_if->host_if->hc_regs[i]->hcchar;
4922 DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n",
4923 (unsigned long)addr, DWC_READ_REG32(addr));
4924 addr = &core_if->host_if->hc_regs[i]->hcsplt;
4925 DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n",
4926 (unsigned long)addr, DWC_READ_REG32(addr));
4927 addr = &core_if->host_if->hc_regs[i]->hcint;
4928 DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n",
4929 (unsigned long)addr, DWC_READ_REG32(addr));
4930 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
4931 DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n",
4932 (unsigned long)addr, DWC_READ_REG32(addr));
4933 addr = &core_if->host_if->hc_regs[i]->hctsiz;
4934 DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n",
4935 (unsigned long)addr, DWC_READ_REG32(addr));
4936 addr = &core_if->host_if->hc_regs[i]->hcdma;
4937 DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n",
4938 (unsigned long)addr, DWC_READ_REG32(addr));
4939 if (core_if->dma_desc_enable) {
4940 addr = &core_if->host_if->hc_regs[i]->hcdmab;
4941 DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n",
4942 (unsigned long)addr, DWC_READ_REG32(addr));
4950 * This function reads the core global registers and prints them
4952 * @param core_if Programming view of DWC_otg controller.
4954 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
4957 volatile uint32_t *addr;
4960 DWC_PRINTF("Core Global Registers\n");
4961 addr = &core_if->core_global_regs->gotgctl;
4962 DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4963 DWC_READ_REG32(addr));
4964 addr = &core_if->core_global_regs->gotgint;
4965 DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
4966 DWC_READ_REG32(addr));
4967 addr = &core_if->core_global_regs->gahbcfg;
4968 DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4969 DWC_READ_REG32(addr));
4970 addr = &core_if->core_global_regs->gusbcfg;
4971 DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
4972 DWC_READ_REG32(addr));
4973 addr = &core_if->core_global_regs->grstctl;
4974 DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4975 DWC_READ_REG32(addr));
4976 addr = &core_if->core_global_regs->gintsts;
4977 DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4978 DWC_READ_REG32(addr));
4979 addr = &core_if->core_global_regs->gintmsk;
4980 DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
4981 DWC_READ_REG32(addr));
4982 addr = &core_if->core_global_regs->grxstsr;
4983 DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr,
4984 DWC_READ_REG32(addr));
4985 addr = &core_if->core_global_regs->grxfsiz;
4986 DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4987 DWC_READ_REG32(addr));
4988 addr = &core_if->core_global_regs->gnptxfsiz;
4989 DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4990 DWC_READ_REG32(addr));
4991 addr = &core_if->core_global_regs->gnptxsts;
4992 DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
4993 DWC_READ_REG32(addr));
4994 addr = &core_if->core_global_regs->gi2cctl;
4995 DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4996 DWC_READ_REG32(addr));
4997 addr = &core_if->core_global_regs->gpvndctl;
4998 DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
4999 DWC_READ_REG32(addr));
5000 addr = &core_if->core_global_regs->ggpio;
5001 DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr,
5002 DWC_READ_REG32(addr));
5003 addr = &core_if->core_global_regs->guid;
5004 DWC_PRINTF("GUID @0x%08lX : 0x%08X\n",
5005 (unsigned long)addr, DWC_READ_REG32(addr));
5006 addr = &core_if->core_global_regs->gsnpsid;
5007 DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
5008 DWC_READ_REG32(addr));
5009 addr = &core_if->core_global_regs->ghwcfg1;
5010 DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5011 DWC_READ_REG32(addr));
5012 addr = &core_if->core_global_regs->ghwcfg2;
5013 DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5014 DWC_READ_REG32(addr));
5015 addr = &core_if->core_global_regs->ghwcfg3;
5016 DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5017 DWC_READ_REG32(addr));
5018 addr = &core_if->core_global_regs->ghwcfg4;
5019 DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5020 DWC_READ_REG32(addr));
5021 addr = &core_if->core_global_regs->glpmcfg;
5022 DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5023 DWC_READ_REG32(addr));
5024 addr = &core_if->core_global_regs->gpwrdn;
5025 DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr,
5026 DWC_READ_REG32(addr));
5027 addr = &core_if->core_global_regs->gdfifocfg;
5028 DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5029 DWC_READ_REG32(addr));
5030 addr = &core_if->core_global_regs->adpctl;
5031 DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5032 dwc_otg_adp_read_reg(core_if));
5033 addr = &core_if->core_global_regs->hptxfsiz;
5034 DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
5035 DWC_READ_REG32(addr));
5037 if (core_if->en_multiple_tx_fifo == 0) {
5038 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
5039 txfsiz = "DPTXFSIZ";
5041 ep_num = core_if->hwcfg4.b.num_in_eps;
5042 txfsiz = "DIENPTXF";
5044 for (i = 0; i < ep_num; i++) {
5045 addr = &core_if->core_global_regs->dtxfsiz[i];
5046 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
5047 (unsigned long)addr, DWC_READ_REG32(addr));
5049 addr = core_if->pcgcctl;
5050 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5051 DWC_READ_REG32(addr));
5057 * @param core_if Programming view of DWC_otg controller.
5058 * @param num Tx FIFO to flush.
5060 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
5062 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5063 volatile grstctl_t greset = {.d32 = 0 };
5066 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
5068 greset.b.txfflsh = 1;
5069 greset.b.txfnum = num;
5070 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5073 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5074 if (++count > 10000) {
5075 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5076 __func__, greset.d32,
5077 DWC_READ_REG32(&global_regs->gnptxsts));
5081 } while (greset.b.txfflsh == 1);
5083 /* Wait for 3 PHY Clocks */
5090 * @param core_if Programming view of DWC_otg controller.
5092 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
5094 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5095 volatile grstctl_t greset = {.d32 = 0 };
5098 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5102 greset.b.rxfflsh = 1;
5103 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5106 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5107 if (++count > 10000) {
5108 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5113 } while (greset.b.rxfflsh == 1);
5115 /* Wait for 3 PHY Clocks */
5120 * Do core a soft reset of the core. Be careful with this because it
5121 * resets all the internal state machines of the core.
5123 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
5125 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5126 volatile grstctl_t greset = {.d32 = 0 };
5129 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5130 /* Wait for AHB master IDLE state. */
5133 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5134 if (++count > 100000) {
5135 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5140 while (greset.b.ahbidle == 0);
5142 /* Core Soft Reset */
5144 greset.b.csftrst = 1;
5145 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5147 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5148 if (++count > 10000) {
5149 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5150 __func__, greset.d32);
5155 while (greset.b.csftrst == 1);
5157 /* Wait for 3 PHY Clocks */
5162 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
5164 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5167 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
5169 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5173 * Register HCD callbacks. The callbacks are used to start and stop
5174 * the HCD for interrupt processing.
5176 * @param core_if Programming view of DWC_otg controller.
5177 * @param cb the HCD callback structure.
5178 * @param p pointer to be passed to callback function (usb_hcd*).
5180 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
5181 dwc_otg_cil_callbacks_t * cb, void *p)
5183 core_if->hcd_cb = cb;
5185 core_if->hcd_cb_p = p;
5189 * Register PCD callbacks. The callbacks are used to start and stop
5190 * the PCD for interrupt processing.
5192 * @param core_if Programming view of DWC_otg controller.
5193 * @param cb the PCD callback structure.
5194 * @param p pointer to be passed to callback function (pcd*).
5196 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
5197 dwc_otg_cil_callbacks_t * cb, void *p)
5199 core_if->pcd_cb = cb;
5206 * This function writes isoc data per 1 (micro)frame into tx fifo
5208 * @param core_if Programming view of DWC_otg controller.
5209 * @param ep The EP to start the transfer on.
5212 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
5214 dwc_otg_dev_in_ep_regs_t *ep_regs;
5215 dtxfsts_data_t txstatus = {.d32 = 0 };
5219 ep->xfer_len = ep->data_per_frame;
5222 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
5224 len = ep->xfer_len - ep->xfer_count;
5226 if (len > ep->maxpacket) {
5227 len = ep->maxpacket;
5230 dwords = (len + 3) / 4;
5232 /* While there is space in the queue and space in the FIFO and
5233 * More data to tranfer, Write packets to the Tx FIFO */
5235 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
5236 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
5238 while (txstatus.b.txfspcavail > dwords &&
5239 ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
5240 /* Write the FIFO */
5241 dwc_otg_ep_write_packet(core_if, ep, 0);
5243 len = ep->xfer_len - ep->xfer_count;
5244 if (len > ep->maxpacket) {
5245 len = ep->maxpacket;
5248 dwords = (len + 3) / 4;
5250 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
5252 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
5258 * This function initializes a descriptor chain for Isochronous transfer
5260 * @param core_if Programming view of DWC_otg controller.
5261 * @param ep The EP to start the transfer on.
5264 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
5267 deptsiz_data_t deptsiz = {.d32 = 0 };
5268 depctl_data_t depctl = {.d32 = 0 };
5269 dsts_data_t dsts = {.d32 = 0 };
5270 volatile uint32_t *addr;
5273 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5275 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5278 ep->xfer_len = ep->data_per_frame;
5280 ep->xfer_buff = ep->cur_pkt_addr;
5281 ep->dma_addr = ep->cur_pkt_dma_addr;
5284 /* Program the transfer size and packet count
5285 * as follows: xfersize = N * maxpacket +
5286 * short_packet pktcnt = N + (short_packet
5289 deptsiz.b.xfersize = ep->xfer_len;
5291 (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
5292 deptsiz.b.mc = deptsiz.b.pktcnt;
5293 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
5296 /* Write the DMA register */
5297 if (core_if->dma_enable) {
5299 (core_if->dev_if->in_ep_regs[ep->num]->
5300 diepdma), (uint32_t) ep->dma_addr);
5304 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
5305 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5307 DWC_WRITE_REG32(&core_if->dev_if->
5308 out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
5310 if (core_if->dma_enable) {
5313 out_ep_regs[ep->num]->doepdma),
5314 (uint32_t) ep->dma_addr);
5318 /** Enable endpoint, clear nak */
5321 if (ep->bInterval == 1) {
5323 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
5324 ep->next_frame = dsts.b.soffn + ep->bInterval;
5326 if (ep->next_frame & 0x1) {
5327 depctl.b.setd1pid = 1;
5329 depctl.b.setd0pid = 1;
5332 ep->next_frame += ep->bInterval;
5334 if (ep->next_frame & 0x1) {
5335 depctl.b.setd1pid = 1;
5337 depctl.b.setd0pid = 1;
5343 DWC_MODIFY_REG32(addr, 0, depctl.d32);
5344 depctl.d32 = DWC_READ_REG32(addr);
5346 if (ep->is_in && core_if->dma_enable == 0) {
5347 write_isoc_frame_data(core_if, ep);
5351 #endif /* DWC_EN_ISOC */
5353 static void dwc_otg_set_uninitialized(int32_t * p, int size)
5356 for (i = 0; i < size; i++) {
5361 static int dwc_otg_param_initialized(int32_t val)
5366 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
5369 gintsts_data_t gintsts;
5370 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
5372 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
5373 if (!core_if->core_params) {
5374 return -DWC_E_NO_MEMORY;
5376 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
5377 sizeof(*core_if->core_params) /
5379 DWC_PRINTF("Setting default values for core params\n");
5380 dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
5381 dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
5382 dwc_otg_set_param_dma_desc_enable(core_if,
5383 dwc_param_dma_desc_enable_default);
5384 dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
5385 dwc_otg_set_param_dma_burst_size(core_if,
5386 dwc_param_dma_burst_size_default);
5387 dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
5388 dwc_param_host_support_fs_ls_low_power_default);
5389 dwc_otg_set_param_enable_dynamic_fifo(core_if,
5390 dwc_param_enable_dynamic_fifo_default);
5391 dwc_otg_set_param_data_fifo_size(core_if,
5392 dwc_param_data_fifo_size_default);
5393 dwc_otg_set_param_dev_rx_fifo_size(core_if,
5394 dwc_param_dev_rx_fifo_size_default);
5395 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
5396 dwc_param_dev_nperio_tx_fifo_size_default);
5397 dwc_otg_set_param_host_rx_fifo_size(core_if,
5398 dwc_param_host_rx_fifo_size_default);
5399 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
5400 dwc_param_host_nperio_tx_fifo_size_default);
5401 dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
5402 dwc_param_host_perio_tx_fifo_size_default);
5403 dwc_otg_set_param_max_transfer_size(core_if,
5404 dwc_param_max_transfer_size_default);
5405 dwc_otg_set_param_max_packet_count(core_if,
5406 dwc_param_max_packet_count_default);
5407 dwc_otg_set_param_host_channels(core_if,
5408 dwc_param_host_channels_default);
5409 dwc_otg_set_param_dev_endpoints(core_if,
5410 dwc_param_dev_endpoints_default);
5411 dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
5412 dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
5413 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
5414 dwc_param_host_ls_low_power_phy_clk_default);
5415 dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
5416 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
5417 dwc_param_phy_ulpi_ext_vbus_default);
5418 dwc_otg_set_param_phy_utmi_width(core_if,
5419 dwc_param_phy_utmi_width_default);
5420 dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
5421 dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
5422 dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
5423 dwc_otg_set_param_en_multiple_tx_fifo(core_if,
5424 dwc_param_en_multiple_tx_fifo_default);
5426 if (gintsts.b.curmode) {
5427 /* Force device mode to get power-on values of device FIFOs */
5428 gusbcfg_data_t gusbcfg = {.d32 = 0 };
5429 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5430 gusbcfg.b.force_dev_mode = 1;
5431 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5433 for (i = 0; i < 15; i++) {
5434 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5435 dwc_param_dev_perio_tx_fifo_size_default, i);
5437 for (i = 0; i < 15; i++) {
5438 dwc_otg_set_param_dev_tx_fifo_size(core_if,
5439 dwc_param_dev_tx_fifo_size_default, i);
5441 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5442 gusbcfg.b.force_dev_mode = 0;
5443 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5446 for (i = 0; i < 15; i++) {
5447 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5448 dwc_param_dev_perio_tx_fifo_size_default, i);
5450 for (i = 0; i < 15; i++) {
5451 dwc_otg_set_param_dev_tx_fifo_size(core_if,
5452 dwc_param_dev_tx_fifo_size_default, i);
5456 dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
5457 dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
5458 dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
5459 dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
5461 dwc_otg_set_param_besl_enable(core_if, dwc_param_besl_enable_default);
5462 dwc_otg_set_param_baseline_besl(core_if, dwc_param_baseline_besl_default);
5463 dwc_otg_set_param_deep_besl(core_if, dwc_param_deep_besl_default);
5465 dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
5466 dwc_otg_set_param_tx_thr_length(core_if,
5467 dwc_param_tx_thr_length_default);
5468 dwc_otg_set_param_rx_thr_length(core_if,
5469 dwc_param_rx_thr_length_default);
5470 dwc_otg_set_param_ahb_thr_ratio(core_if,
5471 dwc_param_ahb_thr_ratio_default);
5472 dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
5473 dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
5474 dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
5475 dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
5476 dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
5477 dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
5478 dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
5482 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
5484 return core_if->dma_enable;
5487 /* Checks if the parameter is outside of its valid range of values */
5488 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
5489 (((_param_) < (_low_)) || \
5490 ((_param_) > (_high_)))
5492 /* Parameter access functions */
5493 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
5497 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5498 DWC_WARN("Wrong value for otg_cap parameter\n");
5499 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
5500 retval = -DWC_E_INVALID;
5506 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
5507 if (core_if->hwcfg2.b.op_mode !=
5508 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5511 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
5512 if ((core_if->hwcfg2.b.op_mode !=
5513 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5514 && (core_if->hwcfg2.b.op_mode !=
5515 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5516 && (core_if->hwcfg2.b.op_mode !=
5517 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5518 && (core_if->hwcfg2.b.op_mode !=
5519 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
5523 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
5528 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
5530 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5534 (((core_if->hwcfg2.b.op_mode ==
5535 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5536 || (core_if->hwcfg2.b.op_mode ==
5537 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5538 || (core_if->hwcfg2.b.op_mode ==
5539 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5540 || (core_if->hwcfg2.b.op_mode ==
5541 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
5542 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
5543 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
5544 retval = -DWC_E_INVALID;
5547 core_if->core_params->otg_cap = val;
5552 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
5554 return core_if->core_params->otg_cap;
5557 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
5559 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5560 DWC_WARN("Wrong value for opt parameter\n");
5561 return -DWC_E_INVALID;
5563 core_if->core_params->opt = val;
5567 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
5569 return core_if->core_params->opt;
5572 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
5575 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5576 DWC_WARN("Wrong value for dma enable\n");
5577 return -DWC_E_INVALID;
5580 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
5581 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
5583 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5587 retval = -DWC_E_INVALID;
5590 core_if->core_params->dma_enable = val;
5592 dwc_otg_set_param_dma_desc_enable(core_if, 0);
5597 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
5599 return core_if->core_params->dma_enable;
5602 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
5605 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5606 DWC_WARN("Wrong value for dma_enable\n");
5607 DWC_WARN("dma_desc_enable must be 0 or 1\n");
5608 return -DWC_E_INVALID;
5612 && ((dwc_otg_get_param_dma_enable(core_if) == 0)
5613 || (core_if->hwcfg4.b.desc_dma == 0))) {
5614 if (dwc_otg_param_initialized
5615 (core_if->core_params->dma_desc_enable)) {
5617 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5621 retval = -DWC_E_INVALID;
5623 core_if->core_params->dma_desc_enable = val;
5627 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
5629 return core_if->core_params->dma_desc_enable;
5632 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
5635 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5636 DWC_WARN("Wrong value for host_support_fs_low_power\n");
5637 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
5638 return -DWC_E_INVALID;
5640 core_if->core_params->host_support_fs_ls_low_power = val;
5644 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
5647 return core_if->core_params->host_support_fs_ls_low_power;
5650 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
5654 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5655 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
5656 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
5657 return -DWC_E_INVALID;
5660 if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
5661 if (dwc_otg_param_initialized
5662 (core_if->core_params->enable_dynamic_fifo)) {
5664 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
5668 retval = -DWC_E_INVALID;
5670 core_if->core_params->enable_dynamic_fifo = val;
5674 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
5676 return core_if->core_params->enable_dynamic_fifo;
5679 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5682 if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
5683 DWC_WARN("Wrong value for data_fifo_size\n");
5684 DWC_WARN("data_fifo_size must be 32-32768\n");
5685 return -DWC_E_INVALID;
5688 if (val > core_if->hwcfg3.b.dfifo_depth) {
5689 if (dwc_otg_param_initialized
5690 (core_if->core_params->data_fifo_size)) {
5692 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
5695 val = core_if->hwcfg3.b.dfifo_depth;
5696 retval = -DWC_E_INVALID;
5699 core_if->core_params->data_fifo_size = val;
5703 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
5705 return core_if->core_params->data_fifo_size;
5708 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5711 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5712 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
5713 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
5714 return -DWC_E_INVALID;
5717 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5718 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
5719 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
5721 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5722 retval = -DWC_E_INVALID;
5725 core_if->core_params->dev_rx_fifo_size = val;
5729 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
5731 return core_if->core_params->dev_rx_fifo_size;
5734 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5739 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5740 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
5741 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
5742 return -DWC_E_INVALID;
5745 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5746 if (dwc_otg_param_initialized
5747 (core_if->core_params->dev_nperio_tx_fifo_size)) {
5749 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
5753 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5755 retval = -DWC_E_INVALID;
5758 core_if->core_params->dev_nperio_tx_fifo_size = val;
5762 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5764 return core_if->core_params->dev_nperio_tx_fifo_size;
5767 int dwc_otg_set_param_host_rx_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_rx_fifo_size\n");
5774 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
5775 return -DWC_E_INVALID;
5778 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5779 if (dwc_otg_param_initialized
5780 (core_if->core_params->host_rx_fifo_size)) {
5782 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
5785 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5786 retval = -DWC_E_INVALID;
5789 core_if->core_params->host_rx_fifo_size = val;
5794 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
5796 return core_if->core_params->host_rx_fifo_size;
5799 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5804 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5805 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
5806 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
5807 return -DWC_E_INVALID;
5810 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5811 if (dwc_otg_param_initialized
5812 (core_if->core_params->host_nperio_tx_fifo_size)) {
5814 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
5818 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5820 retval = -DWC_E_INVALID;
5823 core_if->core_params->host_nperio_tx_fifo_size = val;
5827 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5829 return core_if->core_params->host_nperio_tx_fifo_size;
5832 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5836 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5837 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
5838 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
5839 return -DWC_E_INVALID;
5842 if (val > ((core_if->hptxfsiz.d32) >> 16)) {
5843 if (dwc_otg_param_initialized
5844 (core_if->core_params->host_perio_tx_fifo_size)) {
5846 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
5849 val = (core_if->hptxfsiz.d32) >> 16;
5850 retval = -DWC_E_INVALID;
5853 core_if->core_params->host_perio_tx_fifo_size = val;
5857 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5859 return core_if->core_params->host_perio_tx_fifo_size;
5862 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
5867 if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
5868 DWC_WARN("Wrong value for max_transfer_size\n");
5869 DWC_WARN("max_transfer_size must be 2047-524288\n");
5870 return -DWC_E_INVALID;
5873 if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
5874 if (dwc_otg_param_initialized
5875 (core_if->core_params->max_transfer_size)) {
5877 ("%d invalid for max_transfer_size. Check HW configuration.\n",
5881 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
5883 retval = -DWC_E_INVALID;
5886 core_if->core_params->max_transfer_size = val;
5890 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
5892 return core_if->core_params->max_transfer_size;
5895 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
5899 if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
5900 DWC_WARN("Wrong value for max_packet_count\n");
5901 DWC_WARN("max_packet_count must be 15-511\n");
5902 return -DWC_E_INVALID;
5905 if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
5906 if (dwc_otg_param_initialized
5907 (core_if->core_params->max_packet_count)) {
5909 ("%d invalid for max_packet_count. Check HW configuration.\n",
5913 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
5914 retval = -DWC_E_INVALID;
5917 core_if->core_params->max_packet_count = val;
5921 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
5923 return core_if->core_params->max_packet_count;
5926 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
5930 if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
5931 DWC_WARN("Wrong value for host_channels\n");
5932 DWC_WARN("host_channels must be 1-16\n");
5933 return -DWC_E_INVALID;
5936 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
5937 if (dwc_otg_param_initialized
5938 (core_if->core_params->host_channels)) {
5940 ("%d invalid for host_channels. Check HW configurations.\n",
5943 val = (core_if->hwcfg2.b.num_host_chan + 1);
5944 retval = -DWC_E_INVALID;
5947 core_if->core_params->host_channels = val;
5951 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
5953 return core_if->core_params->host_channels;
5956 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
5960 if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
5961 DWC_WARN("Wrong value for dev_endpoints\n");
5962 DWC_WARN("dev_endpoints must be 1-15\n");
5963 return -DWC_E_INVALID;
5966 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
5967 if (dwc_otg_param_initialized
5968 (core_if->core_params->dev_endpoints)) {
5970 ("%d invalid for dev_endpoints. Check HW configurations.\n",
5973 val = core_if->hwcfg2.b.num_dev_ep;
5974 retval = -DWC_E_INVALID;
5977 core_if->core_params->dev_endpoints = val;
5981 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
5983 return core_if->core_params->dev_endpoints;
5986 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
5991 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5992 DWC_WARN("Wrong value for phy_type\n");
5993 DWC_WARN("phy_type must be 0,1 or 2\n");
5994 return -DWC_E_INVALID;
5996 #ifndef NO_FS_PHY_HW_CHECKS
5997 if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
5998 ((core_if->hwcfg2.b.hs_phy_type == 1) ||
5999 (core_if->hwcfg2.b.hs_phy_type == 3))) {
6001 } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
6002 ((core_if->hwcfg2.b.hs_phy_type == 2) ||
6003 (core_if->hwcfg2.b.hs_phy_type == 3))) {
6005 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
6006 (core_if->hwcfg2.b.fs_phy_type == 1)) {
6010 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
6012 ("%d invalid for phy_type. Check HW configurations.\n",
6015 if (core_if->hwcfg2.b.hs_phy_type) {
6016 if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
6017 (core_if->hwcfg2.b.hs_phy_type == 1)) {
6018 val = DWC_PHY_TYPE_PARAM_UTMI;
6020 val = DWC_PHY_TYPE_PARAM_ULPI;
6023 retval = -DWC_E_INVALID;
6026 core_if->core_params->phy_type = val;
6030 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
6032 return core_if->core_params->phy_type;
6035 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
6038 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6039 DWC_WARN("Wrong value for speed parameter\n");
6040 DWC_WARN("max_speed parameter must be 0 or 1\n");
6041 return -DWC_E_INVALID;
6044 && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
6045 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
6047 ("%d invalid for speed paremter. Check HW configuration.\n",
6051 (dwc_otg_get_param_phy_type(core_if) ==
6052 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
6053 retval = -DWC_E_INVALID;
6055 core_if->core_params->speed = val;
6059 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
6061 return core_if->core_params->speed;
6064 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
6069 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6071 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
6072 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
6073 return -DWC_E_INVALID;
6076 if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
6077 && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
6078 if (dwc_otg_param_initialized
6079 (core_if->core_params->host_ls_low_power_phy_clk)) {
6081 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6085 (dwc_otg_get_param_phy_type(core_if) ==
6086 DWC_PHY_TYPE_PARAM_FS) ?
6087 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
6088 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
6089 retval = -DWC_E_INVALID;
6092 core_if->core_params->host_ls_low_power_phy_clk = val;
6096 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
6098 return core_if->core_params->host_ls_low_power_phy_clk;
6101 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
6103 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6104 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
6105 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
6106 return -DWC_E_INVALID;
6109 core_if->core_params->phy_ulpi_ddr = val;
6113 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
6115 return core_if->core_params->phy_ulpi_ddr;
6118 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
6121 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6122 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
6123 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
6124 return -DWC_E_INVALID;
6127 core_if->core_params->phy_ulpi_ext_vbus = val;
6131 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
6133 return core_if->core_params->phy_ulpi_ext_vbus;
6136 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
6138 if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
6139 DWC_WARN("Wrong valaue for phy_utmi_width\n");
6140 DWC_WARN("phy_utmi_width must be 8 or 16\n");
6141 return -DWC_E_INVALID;
6144 core_if->core_params->phy_utmi_width = val;
6148 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
6150 return core_if->core_params->phy_utmi_width;
6153 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
6155 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6156 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
6157 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
6158 return -DWC_E_INVALID;
6161 core_if->core_params->ulpi_fs_ls = val;
6165 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
6167 return core_if->core_params->ulpi_fs_ls;
6170 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
6172 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6173 DWC_WARN("Wrong valaue for ts_dline\n");
6174 DWC_WARN("ts_dline must be 0 or 1\n");
6175 return -DWC_E_INVALID;
6178 core_if->core_params->ts_dline = val;
6182 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
6184 return core_if->core_params->ts_dline;
6187 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
6190 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6191 DWC_WARN("Wrong valaue for i2c_enable\n");
6192 DWC_WARN("i2c_enable must be 0 or 1\n");
6193 return -DWC_E_INVALID;
6195 #ifndef NO_FS_PHY_HW_CHECK
6196 if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
6197 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
6199 ("%d invalid for i2c_enable. Check HW configuration.\n",
6203 retval = -DWC_E_INVALID;
6207 core_if->core_params->i2c_enable = val;
6211 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
6213 return core_if->core_params->i2c_enable;
6216 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6217 int32_t val, int fifo_num)
6220 gintsts_data_t gintsts;
6221 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6223 if (core_if->hwcfg4.b.ded_fifo_en == 0){
6224 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
6225 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
6226 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
6227 return -DWC_E_INVALID;
6230 if (val > (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16)) {
6231 printk("%d ",DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6232 printk("val = %d fifo_num = %d\n",val,fifo_num);
6233 DWC_WARN("Value is larger then power-on FIFO size\n");
6234 if (dwc_otg_param_initialized
6235 (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
6237 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6240 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6241 retval = -DWC_E_INVALID;
6244 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
6249 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6252 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
6255 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
6259 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6260 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
6261 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
6262 return -DWC_E_INVALID;
6265 if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
6266 if (dwc_otg_param_initialized
6267 (core_if->core_params->en_multiple_tx_fifo)) {
6269 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6273 retval = -DWC_E_INVALID;
6276 core_if->core_params->en_multiple_tx_fifo = val;
6280 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
6282 return core_if->core_params->en_multiple_tx_fifo;
6285 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
6289 fifosize_data_t txfifosize;
6290 txfifosize.d32 = DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]);
6292 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6293 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
6294 DWC_WARN("dev_tx_fifo_size must be 16-32768\n");
6295 return -DWC_E_INVALID;
6298 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
6302 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
6305 return core_if->core_params->dev_tx_fifo_size[fifo_num];
6308 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6312 if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
6313 DWC_WARN("Wrong value for thr_ctl\n");
6314 DWC_WARN("thr_ctl must be 0-7\n");
6315 return -DWC_E_INVALID;
6319 (!dwc_otg_get_param_dma_enable(core_if) ||
6320 !core_if->hwcfg4.b.ded_fifo_en)) {
6321 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
6323 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6327 retval = -DWC_E_INVALID;
6330 core_if->core_params->thr_ctl = val;
6334 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
6336 return core_if->core_params->thr_ctl;
6339 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
6343 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6344 DWC_WARN("Wrong value for lpm_enable\n");
6345 DWC_WARN("lpm_enable must be 0 or 1\n");
6346 return -DWC_E_INVALID;
6349 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
6350 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
6352 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6356 retval = -DWC_E_INVALID;
6359 core_if->core_params->lpm_enable = val;
6363 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
6365 return core_if->core_params->lpm_enable;
6368 int dwc_otg_set_param_besl_enable(dwc_otg_core_if_t * core_if, int32_t val)
6372 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6373 DWC_WARN("Wrong value for besl_enable\n");
6374 DWC_WARN("besl_enable must be 0 or 1\n");
6375 return -DWC_E_INVALID;
6378 core_if->core_params->besl_enable = val;
6382 retval += dwc_otg_set_param_lpm_enable(core_if,val);
6388 int32_t dwc_otg_get_param_besl_enable(dwc_otg_core_if_t * core_if)
6390 return core_if->core_params->besl_enable;
6393 int dwc_otg_set_param_baseline_besl(dwc_otg_core_if_t * core_if, int32_t val)
6397 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6398 DWC_WARN("Wrong value for baseline_besl\n");
6399 DWC_WARN("baseline_besl must be 0-15\n");
6400 return -DWC_E_INVALID;
6403 core_if->core_params->baseline_besl = val;
6407 int32_t dwc_otg_get_param_baseline_besl(dwc_otg_core_if_t * core_if)
6409 return core_if->core_params->baseline_besl;
6412 int dwc_otg_set_param_deep_besl(dwc_otg_core_if_t * core_if, int32_t val)
6416 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6417 DWC_WARN("Wrong value for deep_besl\n");
6418 DWC_WARN("deep_besl must be 0-15\n");
6419 return -DWC_E_INVALID;
6422 core_if->core_params->deep_besl = val;
6426 int32_t dwc_otg_get_param_deep_besl(dwc_otg_core_if_t * core_if)
6428 return core_if->core_params->deep_besl;
6431 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6433 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6434 DWC_WARN("Wrong valaue for tx_thr_length\n");
6435 DWC_WARN("tx_thr_length must be 8 - 128\n");
6436 return -DWC_E_INVALID;
6439 core_if->core_params->tx_thr_length = val;
6443 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
6445 return core_if->core_params->tx_thr_length;
6448 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6450 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6451 DWC_WARN("Wrong valaue for rx_thr_length\n");
6452 DWC_WARN("rx_thr_length must be 8 - 128\n");
6453 return -DWC_E_INVALID;
6456 core_if->core_params->rx_thr_length = val;
6460 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
6462 return core_if->core_params->rx_thr_length;
6465 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
6467 if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
6468 DWC_OTG_PARAM_TEST(val, 4, 4) &&
6469 DWC_OTG_PARAM_TEST(val, 8, 8) &&
6470 DWC_OTG_PARAM_TEST(val, 16, 16) &&
6471 DWC_OTG_PARAM_TEST(val, 32, 32) &&
6472 DWC_OTG_PARAM_TEST(val, 64, 64) &&
6473 DWC_OTG_PARAM_TEST(val, 128, 128) &&
6474 DWC_OTG_PARAM_TEST(val, 256, 256)) {
6475 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
6476 return -DWC_E_INVALID;
6478 core_if->core_params->dma_burst_size = val;
6482 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
6484 return core_if->core_params->dma_burst_size;
6487 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
6490 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6491 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
6492 return -DWC_E_INVALID;
6494 if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
6495 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
6497 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6500 retval = -DWC_E_INVALID;
6503 core_if->core_params->pti_enable = val;
6507 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
6509 return core_if->core_params->pti_enable;
6512 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
6515 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6516 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
6517 return -DWC_E_INVALID;
6519 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
6520 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
6522 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6525 retval = -DWC_E_INVALID;
6528 core_if->core_params->mpi_enable = val;
6532 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
6534 return core_if->core_params->mpi_enable;
6537 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
6540 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6541 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
6542 return -DWC_E_INVALID;
6544 if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
6545 if (dwc_otg_param_initialized
6546 (core_if->core_params->adp_supp_enable)) {
6548 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6551 retval = -DWC_E_INVALID;
6554 core_if->core_params->adp_supp_enable = val;
6555 /* Set OTG version 2.0 in case of enabling ADP */
6557 dwc_otg_set_param_otg_ver(core_if, 1);
6562 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
6564 return core_if->core_params->adp_supp_enable;
6567 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
6570 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6571 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
6572 DWC_WARN("ic_usb_cap must be 0 or 1\n");
6573 return -DWC_E_INVALID;
6576 if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
6577 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
6579 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6582 retval = -DWC_E_INVALID;
6585 core_if->core_params->ic_usb_cap = val;
6589 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
6591 return core_if->core_params->ic_usb_cap;
6594 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
6599 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6600 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
6601 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
6602 return -DWC_E_INVALID;
6606 && (core_if->snpsid < OTG_CORE_REV_2_81a
6607 || !dwc_otg_get_param_thr_ctl(core_if))) {
6610 && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
6615 if (dwc_otg_param_initialized
6616 (core_if->core_params->ahb_thr_ratio)) {
6618 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6621 retval = -DWC_E_INVALID;
6625 core_if->core_params->ahb_thr_ratio = val;
6629 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
6631 return core_if->core_params->ahb_thr_ratio;
6634 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
6638 hwcfg4_data_t hwcfg4 = {.d32 = 0 };
6639 hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
6641 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6642 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
6643 DWC_WARN("power_down must be 0 - 2\n");
6644 return -DWC_E_INVALID;
6647 if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
6651 && ((core_if->snpsid < OTG_CORE_REV_3_00a)
6652 || (hwcfg4.b.xhiber == 0))) {
6656 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
6658 ("%d invalid for parameter power_down. Check HW configuration.\n",
6661 retval = -DWC_E_INVALID;
6664 core_if->core_params->power_down = val;
6668 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
6670 return core_if->core_params->power_down;
6673 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6678 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6679 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
6680 DWC_WARN("reload_ctl must be 0 or 1\n");
6681 return -DWC_E_INVALID;
6684 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
6688 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
6689 DWC_ERROR("%d invalid for parameter reload_ctl."
6690 "Check HW configuration.\n", val);
6692 retval = -DWC_E_INVALID;
6695 core_if->core_params->reload_ctl = val;
6699 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
6701 return core_if->core_params->reload_ctl;
6704 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
6709 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6710 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
6711 DWC_WARN("dev_out_nak must be 0 or 1\n");
6712 return -DWC_E_INVALID;
6715 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
6716 !(core_if->core_params->dma_desc_enable))) {
6720 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
6721 DWC_ERROR("%d invalid for parameter dev_out_nak."
6722 "Check HW configuration.\n", val);
6724 retval = -DWC_E_INVALID;
6727 core_if->core_params->dev_out_nak = val;
6731 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
6733 return core_if->core_params->dev_out_nak;
6736 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
6741 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6742 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
6743 DWC_WARN("cont_on_bna must be 0 or 1\n");
6744 return -DWC_E_INVALID;
6747 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
6748 !(core_if->core_params->dma_desc_enable))) {
6752 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
6753 DWC_ERROR("%d invalid for parameter cont_on_bna."
6754 "Check HW configuration.\n", val);
6756 retval = -DWC_E_INVALID;
6759 core_if->core_params->cont_on_bna = val;
6763 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
6765 return core_if->core_params->cont_on_bna;
6768 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
6773 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6774 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
6775 DWC_WARN("ahb_single must be 0 or 1\n");
6776 return -DWC_E_INVALID;
6779 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
6783 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
6784 DWC_ERROR("%d invalid for parameter ahb_single."
6785 "Check HW configuration.\n", val);
6787 retval = -DWC_E_INVALID;
6790 core_if->core_params->ahb_single = val;
6794 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
6796 return core_if->core_params->ahb_single;
6799 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
6803 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6804 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
6806 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
6807 return -DWC_E_INVALID;
6810 core_if->core_params->otg_ver = val;
6814 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
6816 return core_if->core_params->otg_ver;
6819 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
6821 gotgctl_data_t otgctl;
6822 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6823 return otgctl.b.hstnegscs;
6826 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
6828 gotgctl_data_t otgctl;
6829 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6830 return otgctl.b.sesreqscs;
6833 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
6835 if(core_if->otg_ver == 0) {
6836 gotgctl_data_t otgctl;
6837 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6838 otgctl.b.hnpreq = val;
6839 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
6841 core_if->otg_sts = val;
6845 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
6847 return core_if->snpsid;
6850 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
6852 gintsts_data_t gintsts;
6853 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6854 return gintsts.b.curmode;
6857 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
6859 gusbcfg_data_t usbcfg;
6860 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6861 return usbcfg.b.hnpcap;
6864 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6866 gusbcfg_data_t usbcfg;
6867 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6868 usbcfg.b.hnpcap = val;
6869 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6872 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
6874 gusbcfg_data_t usbcfg;
6875 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6876 return usbcfg.b.srpcap;
6879 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6881 gusbcfg_data_t usbcfg;
6882 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6883 usbcfg.b.srpcap = val;
6884 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6887 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
6890 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6891 return dcfg.b.devspd;
6894 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
6897 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6898 dcfg.b.devspd = val;
6899 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
6902 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
6905 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6906 return hprt0.b.prtconnsts;
6909 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
6912 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
6913 return dsts.b.enumspd;
6916 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
6919 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6920 return hprt0.b.prtpwr;
6924 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
6926 return core_if->hibernation_suspend;
6929 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
6932 hprt0.d32 = dwc_otg_read_hprt0(core_if);
6933 hprt0.b.prtpwr = val;
6934 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6937 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
6940 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6941 return hprt0.b.prtsusp;
6945 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
6948 hprt0.d32 = dwc_otg_read_hprt0(core_if);
6949 hprt0.b.prtsusp = val;
6950 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6953 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
6956 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6957 return hfir.b.frint;
6961 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
6965 fram_int = calc_frame_interval(core_if);
6966 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6967 if (!core_if->core_params->reload_ctl) {
6968 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
6969 "not set to 1.\nShould load driver with reload_ctl=1"
6970 " module parameter\n");
6975 if ((val < 3350) || (val > 4150)) {
6976 DWC_WARN("HFIR interval for HS core and 30 MHz"
6977 "clock freq should be from 3350 to 4150\n");
6982 if ((val < 26820) || (val > 33180)) {
6983 DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
6984 "clock freq should be from 26820 to 33180\n");
6989 if ((val < 5360) || (val > 6640)) {
6990 DWC_WARN("HFIR interval for HS core and 48 MHz"
6991 "clock freq should be from 5360 to 6640\n");
6996 if ((val < 42912) || (val > 53088)) {
6997 DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
6998 "clock freq should be from 42912 to 53088\n");
7003 if ((val < 6700) || (val > 8300)) {
7004 DWC_WARN("HFIR interval for HS core and 60 MHz"
7005 "clock freq should be from 6700 to 8300\n");
7010 if ((val < 53640) || (val > 65536)) {
7011 DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
7012 "clock freq should be from 53640 to 65536\n");
7017 DWC_WARN("Unknown frame interval\n");
7023 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
7026 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
7029 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7030 return hcfg.b.modechtimen;
7034 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
7037 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7038 hcfg.b.modechtimen = val;
7039 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
7042 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
7045 hprt0.d32 = dwc_otg_read_hprt0(core_if);
7046 hprt0.b.prtres = val;
7047 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
7050 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
7053 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7054 return dctl.b.rmtwkupsig;
7057 uint32_t dwc_otg_get_beslreject(dwc_otg_core_if_t * core_if)
7060 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7061 return dctl.b.besl_reject;
7064 void dwc_otg_set_beslreject(dwc_otg_core_if_t * core_if, uint32_t val)
7067 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7068 dctl.b.besl_reject = val;
7069 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
7071 uint32_t dwc_otg_get_hirdthresh(dwc_otg_core_if_t * core_if)
7073 glpmcfg_data_t lpmcfg;
7074 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7075 return lpmcfg.b.hird_thres;
7078 void dwc_otg_set_hirdthresh(dwc_otg_core_if_t * core_if, uint32_t val)
7080 glpmcfg_data_t lpmcfg;
7082 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
7083 DWC_WARN("Wrong valaue for hird_thres\n");
7084 DWC_WARN("hird_thres must be 0-f\n");
7088 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7089 lpmcfg.b.hird_thres |= val;
7090 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7093 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
7095 glpmcfg_data_t lpmcfg;
7096 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7099 ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
7100 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
7101 core_if->lx_state, lpmcfg.b.prt_sleep_sts);
7103 return lpmcfg.b.prt_sleep_sts;
7106 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
7108 glpmcfg_data_t lpmcfg;
7109 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7110 return lpmcfg.b.rem_wkup_en;
7113 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
7115 glpmcfg_data_t lpmcfg;
7116 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7117 return lpmcfg.b.appl_resp;
7120 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
7122 glpmcfg_data_t lpmcfg;
7123 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7124 lpmcfg.b.appl_resp = val;
7125 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7128 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
7130 glpmcfg_data_t lpmcfg;
7131 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7132 return lpmcfg.b.hsic_connect;
7135 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
7137 glpmcfg_data_t lpmcfg;
7138 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7139 lpmcfg.b.hsic_connect = val;
7140 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7143 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
7145 glpmcfg_data_t lpmcfg;
7146 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7147 return lpmcfg.b.inv_sel_hsic;
7151 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
7153 glpmcfg_data_t lpmcfg;
7154 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7155 lpmcfg.b.inv_sel_hsic = val;
7156 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7159 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
7161 return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7164 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
7166 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
7169 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
7171 return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7174 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
7176 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
7179 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
7181 return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
7184 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7186 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
7189 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
7191 return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
7194 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7196 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
7199 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
7201 return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
7204 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
7206 DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
7209 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
7211 return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
7214 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
7216 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
7219 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
7221 return DWC_READ_REG32(core_if->host_if->hprt0);
7225 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
7227 DWC_WRITE_REG32(core_if->host_if->hprt0, val);
7230 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
7232 return DWC_READ_REG32(&core_if->core_global_regs->guid);
7235 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
7237 DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
7240 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
7242 return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
7245 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
7247 return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7251 * Start the SRP timer to detect when the SRP does not complete within
7254 * @param core_if the pointer to core_if strucure.
7256 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
7258 core_if->srp_timer_started = 1;
7259 DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
7262 void dwc_otg_initiate_srp(void * p)
7264 dwc_otg_core_if_t * core_if = p;
7265 uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
7269 val.d32 = DWC_READ_REG32(addr);
7271 DWC_ERROR("Session Request Already active!\n");
7275 DWC_INFO("Session Request Initated\n"); //NOTICE
7276 mem.d32 = DWC_READ_REG32(addr);
7278 DWC_WRITE_REG32(addr, mem.d32);
7280 /* Start the SRP timer */
7281 dwc_otg_pcd_start_srp_timer(core_if);
7285 int dwc_otg_check_haps_status(dwc_otg_core_if_t * core_if)
7289 if(DWC_READ_REG32(&core_if->core_global_regs->gsnpsid) == 0xffffffff)