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 /* do not get HPTXFSIZ here, it's unused.
189 * set global_regs->hptxfsiz in dwc_otg_core_host_init.
190 * for 3.10a version, host20 FIFO can't be configed,
191 * because host20 hwcfg2.b.dynamic_fifo = 0.
194 /* Force host mode to get HPTXFSIZ exact power on value */
196 gusbcfg_data_t gusbcfg = {.d32 = 0 };
197 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
198 gusbcfg.b.force_host_mode = 1;
199 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
201 core_if->hptxfsiz.d32 =
202 DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
203 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
204 gusbcfg.b.force_host_mode = 0;
205 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
210 DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
211 DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
212 DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
213 DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
216 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
218 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
220 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
221 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
223 DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
224 DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
225 DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
226 DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
227 core_if->hwcfg2.b.num_host_chan);
228 DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
229 core_if->hwcfg2.b.nonperio_tx_q_depth);
230 DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
231 core_if->hwcfg2.b.host_perio_tx_q_depth);
232 DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
233 core_if->hwcfg2.b.dev_token_q_depth);
235 DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
236 core_if->hwcfg3.b.dfifo_depth);
237 DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
238 core_if->hwcfg3.b.xfer_size_cntr_width);
241 * Set the SRP sucess bit for FS-I2c
243 core_if->srp_success = 0;
244 core_if->srp_timer_started = 0;
247 * Create new workqueue and init works
249 core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
250 if (core_if->wq_otg == 0) {
251 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
258 core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
259 DWC_PRINTF("%p\n",&core_if->core_global_regs->gsnpsid);
260 DWC_PRINTF("Core Release: %x.%x%x%x\n",
261 (core_if->snpsid >> 12 & 0xF),
262 (core_if->snpsid >> 8 & 0xF),
263 (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
265 core_if->wkp_tasklet = DWC_TASK_ALLOC("wkp_tasklet", w_wakeup_detected, core_if);
267 if (dwc_otg_setup_params(core_if)) {
268 DWC_WARN("Error while setting core params\n");
271 core_if->hibernation_suspend = 0;
272 if (core_if->otg_ver)
273 core_if->test_mode = 0;
275 /** ADP initialization */
276 dwc_otg_adp_init(core_if);
282 * This function frees the structures allocated by dwc_otg_cil_init().
284 * @param core_if The core interface pointer returned from
285 * dwc_otg_cil_init().
288 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
290 dctl_data_t dctl = {.d32 = 0 };
291 /* Disable all interrupts */
292 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
293 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
295 dctl.b.sftdiscon = 1;
296 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
297 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0,
301 if (core_if->wq_otg) {
302 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
303 DWC_WORKQ_FREE(core_if->wq_otg);
305 if (core_if->dev_if) {
306 DWC_FREE(core_if->dev_if);
308 if (core_if->host_if) {
309 DWC_FREE(core_if->host_if);
312 /** Remove ADP Stuff */
313 dwc_otg_adp_remove(core_if);
314 if (core_if->core_params) {
315 DWC_FREE(core_if->core_params);
317 if (core_if->wkp_tasklet){
318 DWC_TASK_FREE(core_if->wkp_tasklet);
320 if (core_if->srp_timer) {
321 DWC_TIMER_FREE(core_if->srp_timer);
327 * This function enables the controller's Global Interrupt in the AHB Config
330 * @param core_if Programming view of DWC_otg controller.
332 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
334 gahbcfg_data_t ahbcfg = {.d32 = 0 };
335 ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
336 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
340 * This function disables the controller's Global Interrupt in the AHB Config
343 * @param core_if Programming view of DWC_otg controller.
345 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
347 gahbcfg_data_t ahbcfg = {.d32 = 0 };
348 ahbcfg.b.glblintrmsk = 1; /* Disable interrupts */
349 DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
353 * This function initializes the commmon interrupts, used in both
354 * device and host modes.
356 * @param core_if Programming view of the DWC_otg controller
359 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
361 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
362 gintmsk_data_t intr_mask = {.d32 = 0 };
364 /* Clear any pending OTG Interrupts */
365 DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
367 /* Clear any pending interrupts */
368 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
371 * Enable the interrupts in the GINTMSK.
373 intr_mask.b.modemismatch = 1;
374 intr_mask.b.otgintr = 1;
376 if (!core_if->dma_enable) {
377 intr_mask.b.rxstsqlvl = 1;
380 intr_mask.b.conidstschng = 1;
381 intr_mask.b.wkupintr = 1;
382 intr_mask.b.disconnect = 0;
383 intr_mask.b.usbsuspend = 1;
384 //intr_mask.b.sessreqintr = 1;
385 #ifdef CONFIG_USB_DWC_OTG_LPM
386 if (core_if->core_params->lpm_enable) {
387 intr_mask.b.lpmtranrcvd = 1;
390 DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
394 * The restore operation is modified to support Synopsys Emulated Powerdown and
395 * Hibernation. This function is for exiting from Device mode hibernation by
396 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
397 * @param core_if Programming view of DWC_otg controller.
398 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
399 * @param reset - indicates whether resume is initiated by Reset.
401 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
402 int rem_wakeup, int reset)
404 gpwrdn_data_t gpwrdn = {.d32 = 0 };
405 pcgcctl_data_t pcgcctl = {.d32 = 0 };
406 dctl_data_t dctl = {.d32 = 0 };
410 if (!core_if->hibernation_suspend) {
411 DWC_PRINTF("Already exited from Hibernation\n");
415 DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
416 /* Switch-on voltage to the core */
417 gpwrdn.b.pwrdnswtch = 1;
418 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
423 gpwrdn.b.pwrdnrstn = 1;
424 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
427 /* Assert Restore signal */
429 gpwrdn.b.restore = 1;
430 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
433 /* Disable power clamps */
435 gpwrdn.b.pwrdnclmp = 1;
436 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
442 /* Deassert Reset core */
444 gpwrdn.b.pwrdnrstn = 1;
445 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
448 /* Disable PMU interrupt */
450 gpwrdn.b.pmuintsel = 1;
451 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
453 /* Mask interrupts from gpwrdn */
455 gpwrdn.b.connect_det_msk = 1;
456 gpwrdn.b.srp_det_msk = 1;
457 gpwrdn.b.disconn_det_msk = 1;
458 gpwrdn.b.rst_det_msk = 1;
459 gpwrdn.b.lnstchng_msk = 1;
460 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
462 /* Indicates that we are going out from hibernation */
463 core_if->hibernation_suspend = 0;
466 * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
467 * indicates restore from remote_wakeup
469 restore_essential_regs(core_if, rem_wakeup, 0);
472 * Wait a little for seeing new value of variable hibernation_suspend if
473 * Restore done interrupt received before polling
477 if (core_if->hibernation_suspend == 0) {
479 * Wait For Restore_done Interrupt. This mechanism of polling the
480 * interrupt is introduced to avoid any possible race conditions
483 gintsts_data_t gintsts;
485 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
486 if (gintsts.b.restoredone) {
488 gintsts.b.restoredone = 1;
489 DWC_WRITE_REG32(&core_if->core_global_regs->
490 gintsts, gintsts.d32);
491 DWC_PRINTF("Restore Done Interrupt seen\n");
497 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
500 /* Clear all pending interupts */
501 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
503 /* De-assert Restore */
505 gpwrdn.b.restore = 1;
506 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
511 pcgcctl.b.rstpdwnmodule = 1;
512 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
515 /* Restore GUSBCFG and DCFG */
516 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
517 core_if->gr_backup->gusbcfg_local);
518 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
519 core_if->dr_backup->dcfg);
521 /* De-assert Wakeup Logic */
523 gpwrdn.b.pmuactv = 1;
524 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
528 /* Set Device programming done bit */
529 dctl.b.pwronprgdone = 1;
530 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
532 /* Start Remote Wakeup Signaling */
533 dctl.d32 = core_if->dr_backup->dctl;
534 dctl.b.rmtwkupsig = 1;
535 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
539 /* Clear all pending interupts */
540 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
542 /* Restore global registers */
543 dwc_otg_restore_global_regs(core_if);
544 /* Restore device global registers */
545 dwc_otg_restore_dev_regs(core_if, rem_wakeup);
550 dctl.b.rmtwkupsig = 1;
551 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
554 core_if->hibernation_suspend = 0;
555 /* The core will be in ON STATE */
556 core_if->lx_state = DWC_OTG_L0;
557 DWC_PRINTF("Hibernation recovery completes here\n");
563 * The restore operation is modified to support Synopsys Emulated Powerdown and
564 * Hibernation. This function is for exiting from Host mode hibernation by
565 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
566 * @param core_if Programming view of DWC_otg controller.
567 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
568 * @param reset - indicates whether resume is initiated by Reset.
570 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
571 int rem_wakeup, int reset)
573 gpwrdn_data_t gpwrdn = {.d32 = 0 };
574 hprt0_data_t hprt0 = {.d32 = 0 };
578 DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
579 /* Switch-on voltage to the core */
580 gpwrdn.b.pwrdnswtch = 1;
581 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
586 gpwrdn.b.pwrdnrstn = 1;
587 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
590 /* Assert Restore signal */
592 gpwrdn.b.restore = 1;
593 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
596 /* Disable power clamps */
598 gpwrdn.b.pwrdnclmp = 1;
599 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
605 /* Deassert Reset core */
607 gpwrdn.b.pwrdnrstn = 1;
608 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
611 /* Disable PMU interrupt */
613 gpwrdn.b.pmuintsel = 1;
614 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
617 gpwrdn.b.connect_det_msk = 1;
618 gpwrdn.b.srp_det_msk = 1;
619 gpwrdn.b.disconn_det_msk = 1;
620 gpwrdn.b.rst_det_msk = 1;
621 gpwrdn.b.lnstchng_msk = 1;
622 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
624 /* Indicates that we are going out from hibernation */
625 core_if->hibernation_suspend = 0;
627 /* Set Restore Essential Regs bit in PCGCCTL register */
628 restore_essential_regs(core_if, rem_wakeup, 1);
630 /* Wait a little for seeing new value of variable hibernation_suspend if
631 * Restore done interrupt received before polling */
634 if (core_if->hibernation_suspend == 0) {
635 /* Wait For Restore_done Interrupt. This mechanism of polling the
636 * interrupt is introduced to avoid any possible race conditions
639 gintsts_data_t gintsts;
640 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
641 if (gintsts.b.restoredone) {
643 gintsts.b.restoredone = 1;
644 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
645 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");
651 DWC_WARN("Restore Done interrupt wasn't generated\n");
655 /* Set the flag's value to 0 again after receiving restore done interrupt */
656 core_if->hibernation_suspend = 0;
658 /* This step is not described in functional spec but if not wait for this
659 * delay, mismatch interrupts occurred because just after restore core is
660 * in Device mode(gintsts.curmode == 0) */
663 /* Clear all pending interrupts */
664 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
666 /* De-assert Restore */
668 gpwrdn.b.restore = 1;
669 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
672 /* Restore GUSBCFG and HCFG */
673 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
674 core_if->gr_backup->gusbcfg_local);
675 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
676 core_if->hr_backup->hcfg_local);
678 /* De-assert Wakeup Logic */
680 gpwrdn.b.pmuactv = 1;
681 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
684 /* Start the Resume operation by programming HPRT0 */
685 hprt0.d32 = core_if->hr_backup->hprt0_local;
689 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
691 DWC_PRINTF("Resume Starts Now\n");
692 if (!reset) { // Indicates it is Resume Operation
693 hprt0.d32 = core_if->hr_backup->hprt0_local;
698 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
702 /* Wait for Resume time and then program HPRT again */
704 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
706 } else { // Indicates it is Reset Operation
707 hprt0.d32 = core_if->hr_backup->hprt0_local;
712 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
713 /* Wait for Reset time and then program HPRT again */
716 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
718 /* Clear all interrupt status */
719 hprt0.d32 = dwc_otg_read_hprt0(core_if);
720 hprt0.b.prtconndet = 1;
721 hprt0.b.prtenchng = 1;
722 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
724 /* Clear all pending interupts */
725 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
727 /* Restore global registers */
728 dwc_otg_restore_global_regs(core_if);
729 /* Restore host global registers */
730 dwc_otg_restore_host_regs(core_if, reset);
732 /* The core will be in ON STATE */
733 core_if->lx_state = DWC_OTG_L0;
734 DWC_PRINTF("Hibernation recovery is complete here\n");
738 /** Saves some register values into system memory. */
739 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
741 struct dwc_otg_global_regs_backup *gr;
744 gr = core_if->gr_backup;
746 gr = DWC_ALLOC(sizeof(*gr));
748 return -DWC_E_NO_MEMORY;
750 core_if->gr_backup = gr;
753 gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
754 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
755 gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
756 gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
757 gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
758 gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
759 gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
760 #ifdef CONFIG_USB_DWC_OTG_LPM
761 gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
763 gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
764 gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
765 gr->gdfifocfg_local =
766 DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
767 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
768 gr->dtxfsiz_local[i] =
769 DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
772 DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
773 DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl = %08x\n", gr->gotgctl_local);
774 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
775 DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg = %08x\n", gr->gahbcfg_local);
776 DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg = %08x\n", gr->gusbcfg_local);
777 DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz = %08x\n", gr->grxfsiz_local);
778 DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
779 gr->gnptxfsiz_local);
780 DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz = %08x\n",
782 #ifdef CONFIG_USB_DWC_OTG_LPM
783 DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local);
785 DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl = %08x\n", gr->gi2cctl_local);
786 DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl = %08x\n", gr->pcgcctl_local);
787 DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg = %08x\n",gr->gdfifocfg_local);
792 /** Saves GINTMSK register before setting the msk bits. */
793 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
795 struct dwc_otg_global_regs_backup *gr;
797 gr = core_if->gr_backup;
799 gr = DWC_ALLOC(sizeof(*gr));
801 return -DWC_E_NO_MEMORY;
803 core_if->gr_backup = gr;
806 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
808 DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
809 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
814 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
816 struct dwc_otg_dev_regs_backup *dr;
819 dr = core_if->dr_backup;
821 dr = DWC_ALLOC(sizeof(*dr));
823 return -DWC_E_NO_MEMORY;
825 core_if->dr_backup = dr;
828 dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
829 dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
831 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
833 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
835 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
837 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
839 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
841 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
843 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
847 "=============Backing Host registers==============\n");
848 DWC_DEBUGPL(DBG_ANY, "Backed up dcfg = %08x\n", dr->dcfg);
849 DWC_DEBUGPL(DBG_ANY, "Backed up dctl = %08x\n", dr->dctl);
850 DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk = %08x\n",
852 DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk = %08x\n", dr->diepmsk);
853 DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk = %08x\n", dr->doepmsk);
854 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
855 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d] = %08x\n", i,
857 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n",
859 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i,
866 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
868 struct dwc_otg_host_regs_backup *hr;
871 hr = core_if->hr_backup;
873 hr = DWC_ALLOC(sizeof(*hr));
875 return -DWC_E_NO_MEMORY;
877 core_if->hr_backup = hr;
881 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
883 DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
884 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
885 hr->hcintmsk_local[i] =
886 DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
888 hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
890 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
893 "=============Backing Host registers===============\n");
894 DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n",
896 DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
897 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
898 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
899 hr->hcintmsk_local[i]);
901 DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n",
903 DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n",
909 int dwc_otg_restore_global_regs(dwc_otg_core_if_t * core_if)
911 struct dwc_otg_global_regs_backup *gr;
914 gr = core_if->gr_backup;
916 return -DWC_E_INVALID;
919 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
920 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
921 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
922 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
923 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
924 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
925 gr->gnptxfsiz_local);
926 DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
928 DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
929 gr->gdfifocfg_local);
930 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
931 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
932 gr->dtxfsiz_local[i]);
935 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
936 DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
937 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
938 (gr->gahbcfg_local));
942 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
944 struct dwc_otg_dev_regs_backup *dr;
947 dr = core_if->dr_backup;
950 return -DWC_E_INVALID;
954 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
958 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
959 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
960 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
962 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
963 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
964 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
965 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
971 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
973 struct dwc_otg_host_regs_backup *hr;
975 hr = core_if->hr_backup;
978 return -DWC_E_INVALID;
981 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
984 // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
987 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
989 for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
990 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
991 hr->hcintmsk_local[i]);
997 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
999 struct dwc_otg_global_regs_backup *gr;
1001 gr = core_if->gr_backup;
1003 /* Restore values for LPM and I2C */
1004 #ifdef CONFIG_USB_DWC_OTG_LPM
1005 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
1007 DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
1012 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
1014 struct dwc_otg_global_regs_backup *gr;
1015 pcgcctl_data_t pcgcctl = {.d32 = 0 };
1016 gahbcfg_data_t gahbcfg = {.d32 = 0 };
1017 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1018 gintmsk_data_t gintmsk = {.d32 = 0 };
1020 /* Restore LPM and I2C registers */
1021 restore_lpm_i2c_regs(core_if);
1023 /* Set PCGCCTL to 0 */
1024 DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
1026 gr = core_if->gr_backup;
1027 /* Load restore values for [31:14] bits */
1028 DWC_WRITE_REG32(core_if->pcgcctl,
1029 ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
1031 /* Umnask global Interrupt in GAHBCFG and restore it */
1032 gahbcfg.d32 = gr->gahbcfg_local;
1033 gahbcfg.b.glblintrmsk = 1;
1034 DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
1036 /* Clear all pending interupts */
1037 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
1039 /* Unmask restore done interrupt */
1040 gintmsk.b.restoredone = 1;
1041 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1043 /* Restore GUSBCFG and HCFG/DCFG */
1044 gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
1045 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
1048 hcfg_data_t hcfg = {.d32 = 0 };
1049 hcfg.d32 = core_if->hr_backup->hcfg_local;
1050 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
1053 /* Load restore values for [31:14] bits */
1054 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1055 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1058 pcgcctl.b.restoremode = 1;
1059 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1062 /* Load restore values for [31:14] bits and set EssRegRestored bit */
1063 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
1064 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1065 pcgcctl.b.ess_reg_restored = 1;
1067 pcgcctl.b.restoremode = 1;
1068 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1070 dcfg_data_t dcfg = {.d32 = 0 };
1071 dcfg.d32 = core_if->dr_backup->dcfg;
1072 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1074 /* Load restore values for [31:14] bits */
1075 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1076 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1078 pcgcctl.d32 |= 0x208;
1080 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1083 /* Load restore values for [31:14] bits */
1084 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1085 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1086 pcgcctl.b.ess_reg_restored = 1;
1088 pcgcctl.d32 |= 0x208;
1089 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1096 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1099 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
1104 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1105 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1106 (core_if->core_params->ulpi_fs_ls)) ||
1107 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1108 /* Full speed PHY */
1109 val = DWC_HCFG_48_MHZ;
1111 /* High speed PHY running at full speed or high speed */
1112 val = DWC_HCFG_30_60_MHZ;
1115 DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1116 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
1117 hcfg.b.fslspclksel = val;
1118 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1122 * Initializes the DevSpd field of the DCFG register depending on the PHY type
1123 * and the enumeration speed of the device.
1125 static void init_devspd(dwc_otg_core_if_t * core_if)
1130 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1131 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1132 (core_if->core_params->ulpi_fs_ls)) ||
1133 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1134 /* Full speed PHY */
1136 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1137 /* High speed PHY running at full speed */
1140 /* High speed PHY running at high speed */
1144 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1146 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
1147 dcfg.b.devspd = val;
1148 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1152 * This function calculates the number of IN EPS
1153 * using GHWCFG1 and GHWCFG2 registers values
1155 * @param core_if Programming view of the DWC_otg controller
1157 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
1159 uint32_t num_in_eps = 0;
1160 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1161 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
1162 uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
1165 for (i = 0; i < num_eps; ++i) {
1166 if (!(hwcfg1 & 0x1))
1172 if (core_if->hwcfg4.b.ded_fifo_en) {
1174 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1181 * This function calculates the number of OUT EPS
1182 * using GHWCFG1 and GHWCFG2 registers values
1184 * @param core_if Programming view of the DWC_otg controller
1186 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
1188 uint32_t num_out_eps = 0;
1189 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1190 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
1193 for (i = 0; i < num_eps; ++i) {
1194 if (!(hwcfg1 & 0x1))
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);
1212 /* Common Initialization */
1213 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1215 /* Program the ULPI External VBUS bit if needed */
1216 usbcfg.b.ulpi_ext_vbus_drv =
1217 (core_if->core_params->phy_ulpi_ext_vbus ==
1218 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1220 /* Set external TS Dline pulsing */
1221 usbcfg.b.term_sel_dl_pulse =
1222 (core_if->core_params->ts_dline == 1) ? 1 : 0;
1223 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1225 /* Reset the Controller */
1226 dwc_otg_core_reset(core_if);
1228 core_if->adp_enable = core_if->core_params->adp_supp_enable;
1229 core_if->power_down = core_if->core_params->power_down;
1231 /* Initialize parameters from Hardware configuration registers. */
1232 dev_if->num_in_eps = calc_num_in_eps(core_if);
1233 dev_if->num_out_eps = calc_num_out_eps(core_if);
1235 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1236 core_if->hwcfg4.b.num_dev_perio_in_ep);
1238 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1239 dev_if->perio_tx_fifo_size[i] =
1240 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1241 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1242 i, dev_if->perio_tx_fifo_size[i]);
1245 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1246 dev_if->tx_fifo_size[i] =
1247 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1248 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1249 i, dev_if->tx_fifo_size[i]);
1252 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1253 core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
1254 core_if->nperio_tx_fifo_size =
1255 DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
1257 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1258 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1259 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
1260 core_if->nperio_tx_fifo_size);
1262 /* This programming sequence needs to happen in FS mode before any other
1263 * programming occurs */
1264 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1265 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1266 /* If FS mode with FS PHY */
1268 /* core_init() is now called on every switch so only call the
1269 * following for the first time through. */
1270 if (!core_if->phy_init_done) {
1271 core_if->phy_init_done = 1;
1272 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1273 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1274 usbcfg.b.physel = 1;
1275 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1277 /* Reset after a PHY select */
1278 dwc_otg_core_reset(core_if);
1281 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1282 * do this on HNP Dev/Host mode switches (done in dev_init and
1284 if (dwc_otg_is_host_mode(core_if)) {
1285 init_fslspclksel(core_if);
1287 init_devspd(core_if);
1290 if (core_if->core_params->i2c_enable) {
1291 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1292 /* Program GUSBCFG.OtgUtmifsSel to I2C */
1293 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1294 usbcfg.b.otgutmifssel = 1;
1295 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1297 /* Program GI2CCTL.I2CEn */
1298 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1299 i2cctl.b.i2cdevaddr = 1;
1301 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1303 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1306 } /* endif speed == DWC_SPEED_PARAM_FULL */
1308 /* High speed PHY. */
1309 if (!core_if->phy_init_done) {
1310 core_if->phy_init_done = 1;
1311 /* HS PHY parameters. These parameters are preserved
1312 * during soft reset so only program the first time. Do
1313 * a soft reset immediately after setting phyif. */
1315 if (core_if->core_params->phy_type == 2) {
1316 /* ULPI interface */
1317 usbcfg.b.ulpi_utmi_sel = 1;
1320 core_if->core_params->phy_ulpi_ddr;
1321 } else if (core_if->core_params->phy_type == 1) {
1322 /* UTMI+ interface */
1323 usbcfg.b.ulpi_utmi_sel = 0;
1324 if (core_if->core_params->phy_utmi_width == 16) {
1331 DWC_ERROR("FS PHY TYPE\n");
1333 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1334 /* Reset after setting the PHY parameters */
1335 dwc_otg_core_reset(core_if);
1339 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1340 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1341 (core_if->core_params->ulpi_fs_ls)) {
1342 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1343 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1344 usbcfg.b.ulpi_fsls = 1;
1345 usbcfg.b.ulpi_clk_sus_m = 1;
1346 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1348 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1349 usbcfg.b.ulpi_fsls = 0;
1350 usbcfg.b.ulpi_clk_sus_m = 0;
1351 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1354 /* Program the GAHBCFG Register. */
1355 switch (core_if->hwcfg2.b.architecture) {
1357 case DWC_SLAVE_ONLY_ARCH:
1358 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1359 ahbcfg.b.nptxfemplvl_txfemplvl =
1360 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1361 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1362 core_if->dma_enable = 0;
1363 core_if->dma_desc_enable = 0;
1366 case DWC_EXT_DMA_ARCH:
1367 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1369 uint8_t brst_sz = core_if->core_params->dma_burst_size;
1370 ahbcfg.b.hburstlen = 0;
1371 while (brst_sz > 1) {
1372 ahbcfg.b.hburstlen++;
1376 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1377 core_if->dma_desc_enable =
1378 (core_if->core_params->dma_desc_enable != 0);
1381 case DWC_INT_DMA_ARCH:
1382 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1383 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
1384 Host mode ISOC in issue fix - vahrama */
1385 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1386 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1387 core_if->dma_desc_enable =
1388 (core_if->core_params->dma_desc_enable != 0);
1392 if (core_if->dma_enable) {
1393 if (core_if->dma_desc_enable) {
1394 DWC_PRINTF("Using Descriptor DMA mode\n");
1396 DWC_PRINTF("Using Buffer DMA mode\n");
1399 DWC_PRINTF("Using Slave mode\n");
1400 core_if->dma_desc_enable = 0;
1403 if (core_if->core_params->ahb_single) {
1404 ahbcfg.b.ahbsingle = 1;
1407 ahbcfg.b.dmaenable = core_if->dma_enable;
1408 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1410 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1412 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1413 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1414 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1415 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
1416 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1417 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
1420 * Program the GUSBCFG register.
1422 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1424 switch (core_if->hwcfg2.b.op_mode) {
1425 case DWC_MODE_HNP_SRP_CAPABLE:
1426 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1427 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1428 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1429 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1432 case DWC_MODE_SRP_ONLY_CAPABLE:
1433 usbcfg.b.hnpcap = 0;
1434 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1435 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1438 case DWC_MODE_NO_HNP_SRP_CAPABLE:
1439 usbcfg.b.hnpcap = 0;
1440 usbcfg.b.srpcap = 0;
1443 case DWC_MODE_SRP_CAPABLE_DEVICE:
1444 usbcfg.b.hnpcap = 0;
1445 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1446 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1449 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1450 usbcfg.b.hnpcap = 0;
1451 usbcfg.b.srpcap = 0;
1454 case DWC_MODE_SRP_CAPABLE_HOST:
1455 usbcfg.b.hnpcap = 0;
1456 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1457 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1460 case DWC_MODE_NO_SRP_CAPABLE_HOST:
1461 usbcfg.b.hnpcap = 0;
1462 usbcfg.b.srpcap = 0;
1466 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1468 #ifdef CONFIG_USB_DWC_OTG_LPM
1469 if (core_if->core_params->lpm_enable) {
1470 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1472 /* To enable LPM support set lpm_cap_en bit */
1473 lpmcfg.b.lpm_cap_en = 1;
1475 /* Make AppL1Res ACK */
1476 lpmcfg.b.appl_resp = 1;
1479 lpmcfg.b.retry_count = 3;
1481 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1486 if (core_if->core_params->ic_usb_cap) {
1487 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1488 gusbcfg.b.ic_usb_cap = 1;
1489 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
1493 gotgctl_data_t gotgctl = {.d32 = 0 };
1494 gotgctl.b.otgver = core_if->core_params->otg_ver;
1495 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
1497 /* Set OTG version supported */
1498 core_if->otg_ver = core_if->core_params->otg_ver;
1499 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1500 core_if->core_params->otg_ver, core_if->otg_ver);
1503 /* Enable common interrupts */
1504 dwc_otg_enable_common_interrupts(core_if);
1506 /* Do device or host intialization based on mode during PCD
1507 * and HCD initialization */
1508 if (dwc_otg_is_host_mode(core_if)) {
1509 DWC_PRINTF("^^^^^^^^^^^^^^^^^^Host Mode\n" );
1510 core_if->op_state = A_HOST;
1512 DWC_PRINTF("^^^^^^^^^^^^^^^^^Device Mode\n" );
1513 core_if->op_state = B_PERIPHERAL;
1514 #ifdef DWC_DEVICE_ONLY
1515 dwc_otg_core_dev_init(core_if);
1520 * This function initializes the DWC_otg controller registers and
1521 * prepares the core for device mode or host mode operation.
1523 * @param core_if Programming view of the DWC_otg controller
1526 void dwc_otg_core_init_no_reset(dwc_otg_core_if_t * core_if)
1529 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1530 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1531 gahbcfg_data_t ahbcfg = {.d32 = 0 };
1532 gusbcfg_data_t usbcfg = {.d32 = 0 };
1533 gi2cctl_data_t i2cctl = {.d32 = 0 };
1535 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
1536 /* Common Initialization */
1537 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1539 /* Program the ULPI External VBUS bit if needed */
1540 usbcfg.b.ulpi_ext_vbus_drv =
1541 (core_if->core_params->phy_ulpi_ext_vbus ==
1542 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1544 /* Set external TS Dline pulsing */
1545 usbcfg.b.term_sel_dl_pulse =
1546 (core_if->core_params->ts_dline == 1) ? 1 : 0;
1547 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1549 /* Reset the Controller */
1550 // dwc_otg_core_reset(core_if);
1552 core_if->adp_enable = core_if->core_params->adp_supp_enable;
1553 core_if->power_down = core_if->core_params->power_down;
1555 /* Initialize parameters from Hardware configuration registers. */
1556 dev_if->num_in_eps = calc_num_in_eps(core_if);
1557 dev_if->num_out_eps = calc_num_out_eps(core_if);
1559 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1560 core_if->hwcfg4.b.num_dev_perio_in_ep);
1562 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1563 dev_if->perio_tx_fifo_size[i] =
1564 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1565 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1566 i, dev_if->perio_tx_fifo_size[i]);
1569 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1570 dev_if->tx_fifo_size[i] =
1571 DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1572 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1573 i, dev_if->tx_fifo_size[i]);
1576 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1577 core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
1578 core_if->nperio_tx_fifo_size =
1579 DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
1581 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1582 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1583 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
1584 core_if->nperio_tx_fifo_size);
1586 /* This programming sequence needs to happen in FS mode before any other
1587 * programming occurs */
1588 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1589 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1590 /* If FS mode with FS PHY */
1592 /* core_init() is now called on every switch so only call the
1593 * following for the first time through. */
1594 if (!core_if->phy_init_done) {
1595 core_if->phy_init_done = 1;
1596 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1597 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1598 usbcfg.b.physel = 1;
1599 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1601 /* Reset after a PHY select */
1602 // dwc_otg_core_reset(core_if);
1605 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1606 * do this on HNP Dev/Host mode switches (done in dev_init and
1608 if (dwc_otg_is_host_mode(core_if)) {
1609 init_fslspclksel(core_if);
1611 init_devspd(core_if);
1614 if (core_if->core_params->i2c_enable) {
1615 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1616 /* Program GUSBCFG.OtgUtmifsSel to I2C */
1617 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1618 usbcfg.b.otgutmifssel = 1;
1619 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1621 /* Program GI2CCTL.I2CEn */
1622 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1623 i2cctl.b.i2cdevaddr = 1;
1625 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1627 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1630 } /* endif speed == DWC_SPEED_PARAM_FULL */
1632 /* High speed PHY. */
1633 if (!core_if->phy_init_done) {
1634 core_if->phy_init_done = 1;
1635 /* HS PHY parameters. These parameters are preserved
1636 * during soft reset so only program the first time. Do
1637 * a soft reset immediately after setting phyif. */
1639 if (core_if->core_params->phy_type == 2) {
1640 /* ULPI interface */
1641 usbcfg.b.ulpi_utmi_sel = 1;
1644 core_if->core_params->phy_ulpi_ddr;
1645 } else if (core_if->core_params->phy_type == 1) {
1646 /* UTMI+ interface */
1647 usbcfg.b.ulpi_utmi_sel = 0;
1648 if (core_if->core_params->phy_utmi_width == 16) {
1655 DWC_ERROR("FS PHY TYPE\n");
1657 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1658 /* Reset after setting the PHY parameters */
1659 // dwc_otg_core_reset(core_if);
1663 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1664 (core_if->hwcfg2.b.fs_phy_type == 1) &&
1665 (core_if->core_params->ulpi_fs_ls)) {
1666 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1667 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1668 usbcfg.b.ulpi_fsls = 1;
1669 usbcfg.b.ulpi_clk_sus_m = 1;
1670 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1672 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1673 usbcfg.b.ulpi_fsls = 0;
1674 usbcfg.b.ulpi_clk_sus_m = 0;
1675 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1678 /* Program the GAHBCFG Register. */
1679 switch (core_if->hwcfg2.b.architecture) {
1681 case DWC_SLAVE_ONLY_ARCH:
1682 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1683 ahbcfg.b.nptxfemplvl_txfemplvl =
1684 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1685 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1686 core_if->dma_enable = 0;
1687 core_if->dma_desc_enable = 0;
1690 case DWC_EXT_DMA_ARCH:
1691 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1693 uint8_t brst_sz = core_if->core_params->dma_burst_size;
1694 ahbcfg.b.hburstlen = 0;
1695 while (brst_sz > 1) {
1696 ahbcfg.b.hburstlen++;
1700 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1701 core_if->dma_desc_enable =
1702 (core_if->core_params->dma_desc_enable != 0);
1705 case DWC_INT_DMA_ARCH:
1706 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1707 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
1708 Host mode ISOC in issue fix - vahrama */
1709 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1710 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1711 core_if->dma_desc_enable =
1712 (core_if->core_params->dma_desc_enable != 0);
1716 if (core_if->dma_enable) {
1717 if (core_if->dma_desc_enable) {
1718 DWC_PRINTF("Using Descriptor DMA mode\n");
1720 DWC_PRINTF("Using Buffer DMA mode\n");
1723 DWC_PRINTF("Using Slave mode\n");
1724 core_if->dma_desc_enable = 0;
1727 if (core_if->core_params->ahb_single) {
1728 ahbcfg.b.ahbsingle = 1;
1731 ahbcfg.b.dmaenable = core_if->dma_enable;
1732 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1734 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1736 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1737 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1738 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1739 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
1740 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1741 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
1744 * Program the GUSBCFG register.
1746 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1748 switch (core_if->hwcfg2.b.op_mode) {
1749 case DWC_MODE_HNP_SRP_CAPABLE:
1750 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1751 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1752 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1753 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1756 case DWC_MODE_SRP_ONLY_CAPABLE:
1757 usbcfg.b.hnpcap = 0;
1758 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1759 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1762 case DWC_MODE_NO_HNP_SRP_CAPABLE:
1763 usbcfg.b.hnpcap = 0;
1764 usbcfg.b.srpcap = 0;
1767 case DWC_MODE_SRP_CAPABLE_DEVICE:
1768 usbcfg.b.hnpcap = 0;
1769 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1770 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1773 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1774 usbcfg.b.hnpcap = 0;
1775 usbcfg.b.srpcap = 0;
1778 case DWC_MODE_SRP_CAPABLE_HOST:
1779 usbcfg.b.hnpcap = 0;
1780 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1781 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1784 case DWC_MODE_NO_SRP_CAPABLE_HOST:
1785 usbcfg.b.hnpcap = 0;
1786 usbcfg.b.srpcap = 0;
1790 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1792 #ifdef CONFIG_USB_DWC_OTG_LPM
1793 if (core_if->core_params->lpm_enable) {
1794 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1796 /* To enable LPM support set lpm_cap_en bit */
1797 lpmcfg.b.lpm_cap_en = 1;
1799 /* Make AppL1Res ACK */
1800 lpmcfg.b.appl_resp = 1;
1803 lpmcfg.b.retry_count = 3;
1805 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1810 if (core_if->core_params->ic_usb_cap) {
1811 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1812 gusbcfg.b.ic_usb_cap = 1;
1813 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
1817 gotgctl_data_t gotgctl = {.d32 = 0 };
1818 gotgctl.b.otgver = core_if->core_params->otg_ver;
1819 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
1821 /* Set OTG version supported */
1822 core_if->otg_ver = core_if->core_params->otg_ver;
1823 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1824 core_if->core_params->otg_ver, core_if->otg_ver);
1827 /* Enable common interrupts */
1828 dwc_otg_enable_common_interrupts(core_if);
1830 /* Do device or host intialization based on mode during PCD
1831 * and HCD initialization */
1832 if (dwc_otg_is_host_mode(core_if)) {
1833 DWC_PRINTF("^^^^^^^^^^^^^^^^^^Host Mode\n" );
1834 core_if->op_state = A_HOST;
1836 DWC_PRINTF("^^^^^^^^^^^^^^^^^Device Mode\n" );
1837 core_if->op_state = B_PERIPHERAL;
1838 #ifdef DWC_DEVICE_ONLY
1839 dwc_otg_core_dev_init(core_if);
1845 * This function enables the Device mode interrupts.
1847 * @param core_if Programming view of DWC_otg controller
1849 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
1851 gintmsk_data_t intr_mask = {.d32 = 0 };
1852 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1854 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1856 /* Disable all interrupts. */
1857 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
1859 /* Clear any pending interrupts */
1860 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
1862 /* Enable the common interrupts */
1863 dwc_otg_enable_common_interrupts(core_if);
1865 /* Enable interrupts */
1866 intr_mask.b.usbreset = 1;
1867 intr_mask.b.enumdone = 1;
1868 /* Disable Disconnect interrupt in Device mode */
1869 intr_mask.b.disconnect = 0;
1871 if (!core_if->multiproc_int_enable) {
1872 intr_mask.b.inepintr = 1;
1873 intr_mask.b.outepintr = 1;
1876 intr_mask.b.erlysuspend = 1;
1878 if (core_if->en_multiple_tx_fifo == 0) {
1879 intr_mask.b.epmismatch = 1;
1882 //intr_mask.b.incomplisoout = 1;
1883 intr_mask.b.incomplisoin = 1;
1885 /* Enable the ignore frame number for ISOC xfers - MAS */
1886 /* Disable to support high bandwith ISOC transfers - manukz */
1888 #ifdef DWC_UTE_PER_IO
1889 if (core_if->dma_enable) {
1890 if (core_if->dma_desc_enable) {
1891 dctl_data_t dctl1 = {.d32 = 0 };
1892 dctl1.b.ifrmnum = 1;
1893 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
1894 dctl, 0, dctl1.d32);
1895 DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
1896 DWC_READ_REG32(&core_if->dev_if->
1897 dev_global_regs->dctl));
1903 if (core_if->dma_enable) {
1904 if (core_if->dma_desc_enable == 0) {
1905 if (core_if->pti_enh_enable) {
1906 dctl_data_t dctl = {.d32 = 0 };
1908 DWC_MODIFY_REG32(&core_if->
1909 dev_if->dev_global_regs->dctl,
1912 intr_mask.b.incomplisoin = 1;
1913 intr_mask.b.incomplisoout = 1;
1917 intr_mask.b.incomplisoin = 1;
1918 intr_mask.b.incomplisoout = 1;
1920 #endif /* DWC_EN_ISOC */
1922 /** @todo NGS: Should this be a module parameter? */
1923 #ifdef USE_PERIODIC_EP
1924 intr_mask.b.isooutdrop = 1;
1925 intr_mask.b.eopframe = 1;
1926 intr_mask.b.incomplisoin = 1;
1927 intr_mask.b.incomplisoout = 1;
1930 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1932 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1933 DWC_READ_REG32(&global_regs->gintmsk));
1937 * This function initializes the DWC_otg controller registers for
1940 * @param core_if Programming view of DWC_otg controller
1943 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
1946 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1947 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1948 dwc_otg_core_params_t *params = core_if->core_params;
1949 dcfg_data_t dcfg = {.d32 = 0 };
1950 depctl_data_t diepctl = {.d32 = 0 };
1951 grstctl_t resetctl = {.d32 = 0 };
1952 uint32_t rx_fifo_size;
1953 fifosize_data_t nptxfifosize;
1954 fifosize_data_t txfifosize;
1955 dthrctl_data_t dthrctl;
1956 fifosize_data_t ptxfifosize;
1957 // uint16_t rxfsiz, nptxfsiz;
1958 // gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
1959 // hwcfg3_data_t hwcfg3 = {.d32 = 0 };
1960 gotgctl_data_t gotgctl = {.d32 = 0 };
1961 gahbcfg_data_t gahbcfg = {.d32 = 0};
1963 /* Restart the Phy Clock */
1964 pcgcctl_data_t pcgcctl = {.d32 = 0 };
1965 /* Restart the Phy Clock */
1966 pcgcctl.b.stoppclk = 1;
1967 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
1970 gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1971 DWC_MODIFY_REG32(&global_regs->gahbcfg, 0 , gahbcfg.b.hburstlen);
1973 /* Device configuration register */
1974 init_devspd(core_if);
1975 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1976 dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
1977 dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1978 /* Enable Device OUT NAK in case of DDMA mode */
1979 if (core_if->core_params->dev_out_nak) {
1980 dcfg.b.endevoutnak = 1;
1983 if (core_if->core_params->cont_on_bna) {
1984 dctl_data_t dctl = {.d32 = 0 };
1985 dctl.b.encontonbna = 1;
1986 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1988 /** should be done before every reset */
1989 if (core_if->otg_ver) {
1990 core_if->otg_sts = 0;
1991 gotgctl.b.devhnpen = 1;
1992 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, gotgctl.d32, 0);
1995 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1997 /* Configure data FIFO sizes */
1999 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2001 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
2002 core_if->init_rxfsiz = params->dev_rx_fifo_size;
2004 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
2005 DWC_READ_REG32(&global_regs->grxfsiz));
2007 /** Set Periodic Tx FIFO Mask all bits 0 */
2008 core_if->p_tx_msk = 0;
2010 /** Set Tx FIFO Mask all bits 0 */
2011 core_if->tx_msk = 0;
2012 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
2013 * and ded_fifo_en is 1 in default*/
2014 if (core_if->en_multiple_tx_fifo == 0) {
2015 /* Non-periodic Tx FIFO */
2016 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2017 DWC_READ_REG32(&global_regs->gnptxfsiz));
2019 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
2020 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
2022 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
2025 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2026 DWC_READ_REG32(&global_regs->gnptxfsiz));
2028 /**@todo NGS: Fix Periodic FIFO Sizing! */
2030 * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
2031 * Indexes of the FIFO size module parameters in the
2032 * dev_perio_tx_fifo_size array and the FIFO size registers in
2033 * the dptxfsiz array run from 0 to 14.
2035 /** @todo Finish debug of this */
2036 ptxfifosize.b.startaddr =
2037 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2038 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
2039 ptxfifosize.b.depth =
2040 params->dev_perio_tx_fifo_size[i];
2041 DWC_DEBUGPL(DBG_CIL,
2042 "initial dtxfsiz[%d]=%08x\n", i,
2043 DWC_READ_REG32(&global_regs->dtxfsiz
2045 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
2047 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
2049 DWC_READ_REG32(&global_regs->dtxfsiz
2051 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
2055 * Tx FIFOs These FIFOs are numbered from 1 to 15.
2056 * Indexes of the FIFO size module parameters in the
2057 * dev_tx_fifo_size array and the FIFO size registers in
2058 * the dtxfsiz array run from 0 to 14.
2061 /* Non-periodic Tx FIFO */
2062 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2063 DWC_READ_REG32(&global_regs->gnptxfsiz));
2066 core_if->pwron_gnptxfsiz =
2067 (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2068 core_if->init_gnptxfsiz =
2069 params->dev_nperio_tx_fifo_size;
2071 rx_fifo_size = params->dev_rx_fifo_size;
2072 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
2073 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
2074 DWC_READ_REG32(&global_regs->grxfsiz));
2076 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
2077 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
2078 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
2081 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2082 DWC_READ_REG32(&global_regs->gnptxfsiz));
2084 txfifosize.b.startaddr =
2085 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2087 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
2089 txfifosize.b.depth =
2090 params->dev_tx_fifo_size[i];
2092 DWC_DEBUGPL(DBG_CIL,
2093 "initial dtxfsiz[%d]=%08x\n",
2095 DWC_READ_REG32(&global_regs->dtxfsiz
2099 core_if->pwron_txfsiz[i] =
2101 (&global_regs->dtxfsiz[i]) >> 16);
2102 core_if->init_txfsiz[i] =
2103 params->dev_tx_fifo_size[i];
2105 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
2108 DWC_DEBUGPL(DBG_CIL,
2109 "new dtxfsiz[%d]=%08x\n",
2111 DWC_READ_REG32(&global_regs->dtxfsiz
2114 txfifosize.b.startaddr += txfifosize.b.depth;
2117 /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO
2118 * Before 3.00a EpInfoBase was being configured in ep enable/disable
2119 * routine as well. Starting from 3.00a it will be set to the end of
2120 * allocated FIFO space here due to ep 0 OUT always keeping enabled
2122 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
2123 hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
2124 gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
2125 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2126 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
2127 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
2128 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2129 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
2131 gdfifocfg.b.epinfobase = txfifosize.b.startaddr;
2133 //DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2138 /* Flush the FIFOs */
2139 dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
2140 dwc_otg_flush_rx_fifo(core_if);
2142 /* Flush the Learning Queue. */
2143 resetctl.b.intknqflsh = 1;
2144 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
2146 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
2147 core_if->start_predict = 0;
2148 for (i = 0; i <= core_if->dev_if->num_in_eps; ++i) {
2149 core_if->nextep_seq[i] = 0xff; // 0xff - EP not active
2151 core_if->nextep_seq[0] = 0;
2152 core_if->first_in_nextep_seq = 0;
2153 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
2154 diepctl.b.nextep = 0;
2155 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
2157 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
2158 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
2160 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
2162 DWC_DEBUGPL(DBG_CILV,
2163 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
2164 __func__, core_if->first_in_nextep_seq);
2165 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
2166 DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]);
2168 DWC_DEBUGPL(DBG_CILV, "\n");
2171 /* Clear all pending Device Interrupts */
2172 /** @todo - if the condition needed to be checked
2173 * or in any case all pending interrutps should be cleared?
2175 if (core_if->multiproc_int_enable) {
2176 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
2177 DWC_WRITE_REG32(&dev_if->dev_global_regs->
2178 diepeachintmsk[i], 0);
2181 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
2182 DWC_WRITE_REG32(&dev_if->dev_global_regs->
2183 doepeachintmsk[i], 0);
2186 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
2187 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
2189 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
2190 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
2191 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
2192 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
2195 for (i = 0; i <= dev_if->num_in_eps; i++) {
2196 depctl_data_t depctl;
2197 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
2198 if (depctl.b.epena) {
2206 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
2208 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
2209 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
2210 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
2213 for (i = 1; i <= dev_if->num_out_eps; i++) {
2214 depctl_data_t depctl;
2215 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
2216 if (depctl.b.epena) {
2218 dctl_data_t dctl = {.d32 = 0 };
2219 gintmsk_data_t gintsts = {.d32 = 0 };
2220 doepint_data_t doepint = {.d32 = 0 };
2221 dctl.b.sgoutnak = 1;
2222 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
2226 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
2228 DWC_ERROR("SNAK as not set during 10s\n");
2231 } while (!gintsts.b.goutnakeff);
2233 gintsts.b.goutnakeff = 1;
2234 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
2240 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32);
2243 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
2244 out_ep_regs[i]->doepint);
2246 DWC_ERROR("EPDIS was not set during 10s\n");
2249 } while (!doepint.b.epdisabled);
2251 doepint.b.epdisabled = 1;
2252 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32);
2255 dctl.b.cgoutnak = 1;
2256 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
2261 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
2262 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
2263 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
2264 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
2267 if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
2268 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
2269 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
2270 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
2272 dev_if->rx_thr_length = params->rx_thr_length;
2273 dev_if->tx_thr_length = params->tx_thr_length;
2275 dev_if->setup_desc_index = 0;
2278 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
2279 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
2280 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
2281 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
2282 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
2283 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
2285 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
2288 DWC_DEBUGPL(DBG_CIL,
2289 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
2290 dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
2291 dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
2292 dthrctl.b.rx_thr_len);
2296 dwc_otg_enable_device_interrupts(core_if);
2299 diepmsk_data_t msk = {.d32 = 0 };
2300 msk.b.txfifoundrn = 1;
2301 if (core_if->multiproc_int_enable) {
2302 DWC_MODIFY_REG32(&dev_if->dev_global_regs->
2303 diepeachintmsk[0], msk.d32, msk.d32);
2305 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
2310 if (core_if->multiproc_int_enable) {
2311 /* Set NAK on Babble */
2312 dctl_data_t dctl = {.d32 = 0 };
2313 dctl.b.nakonbble = 1;
2314 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
2319 * This function enables the Host mode interrupts.
2321 * @param core_if Programming view of DWC_otg controller
2323 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
2325 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2326 gintmsk_data_t intr_mask = {.d32 = 0 };
2328 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
2330 /* Disable all interrupts. */
2331 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
2333 /* Clear any pending interrupts. */
2334 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
2336 /* Enable the common interrupts */
2337 dwc_otg_enable_common_interrupts(core_if);
2340 * Enable host mode interrupts without disturbing common
2344 intr_mask.b.disconnect = 1;
2345 intr_mask.b.portintr = 1;
2346 intr_mask.b.hcintr = 1;
2348 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2352 * This function disables the Host Mode interrupts.
2354 * @param core_if Programming view of DWC_otg controller
2356 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
2358 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2359 gintmsk_data_t intr_mask = {.d32 = 0 };
2361 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2364 * Disable host mode interrupts without disturbing common
2367 intr_mask.b.sofintr = 1;
2368 intr_mask.b.portintr = 1;
2369 intr_mask.b.hcintr = 1;
2370 intr_mask.b.ptxfempty = 1;
2371 intr_mask.b.nptxfempty = 1;
2373 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
2377 * This function initializes the DWC_otg controller registers for
2380 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2381 * request queues. Host channels are reset to ensure that they are ready for
2382 * performing transfers.
2384 * @param core_if Programming view of DWC_otg controller
2387 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
2389 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2390 dwc_otg_host_if_t *host_if = core_if->host_if;
2391 dwc_otg_core_params_t *params = core_if->core_params;
2392 hprt0_data_t hprt0 = {.d32 = 0 };
2393 fifosize_data_t nptxfifosize;
2394 fifosize_data_t ptxfifosize;
2395 // uint16_t rxfsiz, nptxfsiz, hptxfsiz;
2396 // gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
2398 hcchar_data_t hcchar;
2401 dwc_otg_hc_regs_t *hc_regs;
2403 gotgctl_data_t gotgctl = {.d32 = 0 };
2404 pcgcctl_data_t pcgcctl = {.d32 = 0 };
2405 struct dwc_otg_platform_data *pldata;
2406 pldata = core_if->otg_dev->pldata;
2410 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
2412 /* Restart the Phy Clock */
2413 pcgcctl.b.stoppclk = 1;
2414 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
2417 if ((core_if->otg_ver == 1) && (core_if->op_state == A_HOST)) {
2418 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
2419 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2420 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2421 if (hprt0.b.prtpwr == 0) {
2423 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2427 /* Initialize Host Configuration Register */
2428 init_fslspclksel(core_if);
2429 if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
2430 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2431 hcfg.b.fslssupp = 1;
2432 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2436 /* This bit allows dynamic reloading of the HFIR register
2437 * during runtime. This bit needs to be programmed during
2438 * initial configuration and its value must not be changed
2440 if (core_if->core_params->reload_ctl == 1) {
2441 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
2442 hfir.b.hfirrldctrl = 1;
2443 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
2446 if (core_if->core_params->dma_desc_enable) {
2447 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
2449 (core_if->hwcfg4.b.desc_dma
2450 && (core_if->snpsid >= OTG_CORE_REV_2_90a)
2451 && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
2452 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
2454 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
2455 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
2457 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
2459 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
2460 "Either core version is below 2.90a or "
2461 "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
2462 "To run the driver in Buffer DMA host mode set dma_desc_enable "
2463 "module parameter to 0.\n");
2466 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2468 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2471 /* Configure data FIFO sizes */
2472 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2473 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
2474 core_if->total_fifo_size);
2475 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
2476 params->host_rx_fifo_size);
2477 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
2478 params->host_nperio_tx_fifo_size);
2479 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
2480 params->host_perio_tx_fifo_size);
2483 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
2484 DWC_READ_REG32(&global_regs->grxfsiz));
2485 DWC_WRITE_REG32(&global_regs->grxfsiz, 0x0200);//params->host_rx_fifo_size);
2486 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
2487 DWC_READ_REG32(&global_regs->grxfsiz));
2489 /* Non-periodic Tx FIFO */
2490 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2491 DWC_READ_REG32(&global_regs->gnptxfsiz));
2492 nptxfifosize.b.depth = 0x0080;//params->host_nperio_tx_fifo_size;
2493 nptxfifosize.b.startaddr = 0x0200;//params->host_rx_fifo_size;
2494 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2495 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2496 DWC_READ_REG32(&global_regs->gnptxfsiz));
2498 /* Periodic Tx FIFO */
2499 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
2500 DWC_READ_REG32(&global_regs->hptxfsiz));
2501 ptxfifosize.b.depth = 0x0100;//params->host_perio_tx_fifo_size;
2502 ptxfifosize.b.startaddr = 0x0280;//nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2503 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
2504 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
2505 DWC_READ_REG32(&global_regs->hptxfsiz));
2507 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
2508 * and ded_fifo_en is 1 in default
2510 if (core_if->en_multiple_tx_fifo) {
2511 /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
2512 gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
2513 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
2514 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2515 hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
2516 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
2517 DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2522 /* TODO - check this */
2523 /* Clear Host Set HNP Enable in the OTG Control Register */
2524 gotgctl.b.hstsethnpen = 1;
2525 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2526 /* Make sure the FIFOs are flushed. */
2527 dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ );
2528 dwc_otg_flush_rx_fifo(core_if);
2530 /* Clear Host Set HNP Enable in the OTG Control Register */
2531 gotgctl.b.hstsethnpen = 1;
2532 DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2534 if (!core_if->core_params->dma_desc_enable) {
2535 /* Flush out any leftover queued requests. */
2536 num_channels = core_if->core_params->host_channels;
2538 for (i = 0; i < num_channels; i++) {
2539 hc_regs = core_if->host_if->hc_regs[i];
2540 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2544 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2547 /* Halt all channels to put them into a known state. */
2548 for (i = 0; i < num_channels; i++) {
2550 hc_regs = core_if->host_if->hc_regs[i];
2551 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2555 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2556 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
2558 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2559 if (++count > 1000) {
2561 ("%s: Unable to clear halt on channel %d\n",
2566 } while (hcchar.b.chen);
2570 /* Turn on the vbus power. */
2571 if ((core_if->otg_ver == 0) && (core_if->op_state == A_HOST)) {
2572 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2573 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2574 if (hprt0.b.prtpwr == 0) {
2576 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2578 if(pldata->power_enable)
2579 pldata->power_enable(1);
2582 dwc_otg_enable_host_interrupts(core_if);
2586 * Prepares a host channel for transferring packets to/from a specific
2587 * endpoint. The HCCHARn register is set up with the characteristics specified
2588 * in _hc. Host channel interrupts that may need to be serviced while this
2589 * transfer is in progress are enabled.
2591 * @param core_if Programming view of DWC_otg controller
2592 * @param hc Information needed to initialize the host channel
2594 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2596 uint32_t intr_enable;
2597 hcintmsk_data_t hc_intr_mask;
2598 gintmsk_data_t gintmsk = {.d32 = 0 };
2599 hcchar_data_t hcchar;
2600 hcsplt_data_t hcsplt;
2602 uint8_t hc_num = hc->hc_num;
2603 dwc_otg_host_if_t *host_if = core_if->host_if;
2604 dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2606 /* Clear old interrupt conditions for this host channel. */
2607 hc_intr_mask.d32 = 0xFFFFFFFF;
2608 hc_intr_mask.b.reserved14_31 = 0;
2609 DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
2611 /* Enable channel interrupts required for this transfer. */
2612 hc_intr_mask.d32 = 0;
2613 hc_intr_mask.b.chhltd = 1;
2614 if (core_if->dma_enable) {
2615 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
2616 if (!core_if->dma_desc_enable)
2617 hc_intr_mask.b.ahberr = 1;
2619 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2620 hc_intr_mask.b.xfercompl = 1;
2623 if (hc->error_state && !hc->do_split &&
2624 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2625 hc_intr_mask.b.ack = 1;
2627 hc_intr_mask.b.datatglerr = 1;
2628 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2629 hc_intr_mask.b.nak = 1;
2634 switch (hc->ep_type) {
2635 case DWC_OTG_EP_TYPE_CONTROL:
2636 case DWC_OTG_EP_TYPE_BULK:
2637 hc_intr_mask.b.xfercompl = 1;
2638 hc_intr_mask.b.stall = 1;
2639 hc_intr_mask.b.xacterr = 1;
2640 hc_intr_mask.b.datatglerr = 1;
2642 hc_intr_mask.b.bblerr = 1;
2644 hc_intr_mask.b.nak = 1;
2645 hc_intr_mask.b.nyet = 1;
2647 hc_intr_mask.b.ack = 1;
2652 hc_intr_mask.b.nak = 1;
2653 if (hc->complete_split) {
2654 hc_intr_mask.b.nyet = 1;
2656 hc_intr_mask.b.ack = 1;
2660 if (hc->error_state) {
2661 hc_intr_mask.b.ack = 1;
2664 case DWC_OTG_EP_TYPE_INTR:
2665 hc_intr_mask.b.xfercompl = 1;
2666 hc_intr_mask.b.nak = 1;
2667 hc_intr_mask.b.stall = 1;
2668 hc_intr_mask.b.xacterr = 1;
2669 hc_intr_mask.b.datatglerr = 1;
2670 hc_intr_mask.b.frmovrun = 1;
2673 hc_intr_mask.b.bblerr = 1;
2675 if (hc->error_state) {
2676 hc_intr_mask.b.ack = 1;
2679 if (hc->complete_split) {
2680 hc_intr_mask.b.nyet = 1;
2682 hc_intr_mask.b.ack = 1;
2686 case DWC_OTG_EP_TYPE_ISOC:
2687 hc_intr_mask.b.xfercompl = 1;
2688 hc_intr_mask.b.frmovrun = 1;
2689 hc_intr_mask.b.ack = 1;
2692 hc_intr_mask.b.xacterr = 1;
2693 hc_intr_mask.b.bblerr = 1;
2698 DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2700 /* Enable the top level host channel interrupt. */
2701 intr_enable = (1 << hc_num);
2702 DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
2704 /* Make sure host channel interrupts are enabled. */
2705 gintmsk.b.hcintr = 1;
2706 DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
2709 * Program the HCCHARn register with the endpoint characteristics for
2710 * the current transfer.
2713 hcchar.b.devaddr = hc->dev_addr;
2714 hcchar.b.epnum = hc->ep_num;
2715 hcchar.b.epdir = hc->ep_is_in;
2716 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2717 hcchar.b.eptype = hc->ep_type;
2718 hcchar.b.mps = hc->max_packet;
2720 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2722 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2723 DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
2724 DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
2725 DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
2726 DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
2727 DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
2728 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2729 DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
2732 * Program the HCSPLIT register for SPLITs
2736 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
2738 hc->complete_split ? "CSPLIT" : "SSPLIT");
2739 hcsplt.b.compsplt = hc->complete_split;
2740 hcsplt.b.xactpos = hc->xact_pos;
2741 hcsplt.b.hubaddr = hc->hub_addr;
2742 hcsplt.b.prtaddr = hc->port_addr;
2743 DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
2744 DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
2745 DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
2746 DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
2747 DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
2748 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
2749 DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
2751 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2756 * Attempts to halt a host channel. This function should only be called in
2757 * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2758 * normal circumstances in DMA mode, the controller halts the channel when the
2759 * transfer is complete or a condition occurs that requires application
2762 * In slave mode, checks for a free request queue entry, then sets the Channel
2763 * Enable and Channel Disable bits of the Host Channel Characteristics
2764 * register of the specified channel to intiate the halt. If there is no free
2765 * request queue entry, sets only the Channel Disable bit of the HCCHARn
2766 * register to flush requests for this channel. In the latter case, sets a
2767 * flag to indicate that the host channel needs to be halted when a request
2768 * queue slot is open.
2770 * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2771 * HCCHARn register. The controller ensures there is space in the request
2772 * queue before submitting the halt request.
2774 * Some time may elapse before the core flushes any posted requests for this
2775 * host channel and halts. The Channel Halted interrupt handler completes the
2776 * deactivation of the host channel.
2778 * @param core_if Controller register interface.
2779 * @param hc Host channel to halt.
2780 * @param halt_status Reason for halting the channel.
2782 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
2783 dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
2785 gnptxsts_data_t nptxsts;
2786 hptxsts_data_t hptxsts;
2787 hcchar_data_t hcchar;
2788 dwc_otg_hc_regs_t *hc_regs;
2789 dwc_otg_core_global_regs_t *global_regs;
2790 dwc_otg_host_global_regs_t *host_global_regs;
2792 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2793 global_regs = core_if->core_global_regs;
2794 host_global_regs = core_if->host_if->host_global_regs;
2796 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
2797 "halt_status = %d\n", halt_status);
2799 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2800 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2802 * Disable all channel interrupts except Ch Halted. The QTD
2803 * and QH state associated with this transfer has been cleared
2804 * (in the case of URB_DEQUEUE), so the channel needs to be
2805 * shut down carefully to prevent crashes.
2807 hcintmsk_data_t hcintmsk;
2809 hcintmsk.b.chhltd = 1;
2810 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
2813 * Make sure no other interrupts besides halt are currently
2814 * pending. Handling another interrupt could cause a crash due
2815 * to the QTD and QH state.
2817 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
2820 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2821 * even if the channel was already halted for some other
2824 hc->halt_status = halt_status;
2826 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2827 if (hcchar.b.chen == 0) {
2829 * The channel is either already halted or it hasn't
2830 * started yet. In DMA mode, the transfer may halt if
2831 * it finishes normally or a condition occurs that
2832 * requires driver intervention. Don't want to halt
2833 * the channel again. In either Slave or DMA mode,
2834 * it's possible that the transfer has been assigned
2835 * to a channel, but not started yet when an URB is
2836 * dequeued. Don't want to halt a channel that hasn't
2842 if (hc->halt_pending) {
2844 * A halt has already been issued for this channel. This might
2845 * happen when a transfer is aborted by a higher level in
2850 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2851 __func__, hc->hc_num);
2857 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2859 /* No need to set the bit in DDMA for disabling the channel */
2860 //TODO check it everywhere channel is disabled
2861 if (!core_if->core_params->dma_desc_enable)
2865 if (!core_if->dma_enable) {
2866 /* Check for space in the request queue to issue the halt. */
2867 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2868 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2869 nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
2870 if (nptxsts.b.nptxqspcavail == 0) {
2875 DWC_READ_REG32(&host_global_regs->hptxsts);
2876 if ((hptxsts.b.ptxqspcavail == 0)
2877 || (core_if->queuing_high_bandwidth)) {
2882 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2884 hc->halt_status = halt_status;
2886 if (hcchar.b.chen) {
2887 hc->halt_pending = 1;
2888 hc->halt_on_queue = 0;
2890 hc->halt_on_queue = 1;
2893 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2894 DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
2895 DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
2896 DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
2897 DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
2903 * Clears the transfer state for a host channel. This function is normally
2904 * called after a transfer is done and the host channel is being released.
2906 * @param core_if Programming view of DWC_otg controller.
2907 * @param hc Identifies the host channel to clean up.
2909 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2911 dwc_otg_hc_regs_t *hc_regs;
2913 hc->xfer_started = 0;
2916 * Clear channel interrupt enables and any unhandled channel interrupt
2919 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2920 DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
2921 DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
2923 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
2928 * Sets the channel property that indicates in which frame a periodic transfer
2929 * should occur. This is always set to the _next_ frame. This function has no
2930 * effect on non-periodic transfers.
2932 * @param core_if Programming view of DWC_otg controller.
2933 * @param hc Identifies the host channel to set up and its properties.
2934 * @param hcchar Current value of the HCCHAR register for the specified host
2937 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
2938 dwc_hc_t * hc, hcchar_data_t * hcchar)
2940 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2941 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2944 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
2946 /* 1 if _next_ frame is odd, 0 if it's even */
2947 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2949 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
2950 && !hc->complete_split) {
2951 switch (hfnum.b.frnum & 0x7) {
2953 core_if->hfnum_7_samples++;
2954 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2957 core_if->hfnum_0_samples++;
2958 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2961 core_if->hfnum_other_samples++;
2962 core_if->hfnum_other_frrem_accum +=
2972 void hc_xfer_timeout(void *ptr)
2974 hc_xfer_info_t *xfer_info = NULL;
2978 xfer_info = (hc_xfer_info_t *) ptr;
2980 if (!xfer_info->hc) {
2981 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
2985 hc_num = xfer_info->hc->hc_num;
2986 DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2987 DWC_WARN(" start_hcchar_val 0x%08x\n",
2988 xfer_info->core_if->start_hcchar_val[hc_num]);
2992 void ep_xfer_timeout(void *ptr)
2994 ep_xfer_info_t *xfer_info = NULL;
2996 dctl_data_t dctl = {.d32 = 0 };
2997 gintsts_data_t gintsts = {.d32 = 0 };
2998 gintmsk_data_t gintmsk = {.d32 = 0 };
3001 xfer_info = (ep_xfer_info_t *) ptr;
3003 if (!xfer_info->ep) {
3004 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
3008 ep_num = xfer_info->ep->num;
3009 DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
3010 /* Put the sate to 2 as it was time outed */
3011 xfer_info->state = 2;
3014 DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl);
3016 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts);
3018 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk);
3020 if (!gintmsk.b.goutnakeff) {
3022 gintmsk.b.goutnakeff = 1;
3023 DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk,
3028 if (!gintsts.b.goutnakeff) {
3029 dctl.b.sgoutnak = 1;
3031 DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl,
3036 void set_pid_isoc(dwc_hc_t * hc)
3038 /* Set up the initial PID for the transfer. */
3039 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
3041 if (hc->multi_count == 1) {
3042 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
3043 } else if (hc->multi_count == 2) {
3044 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
3046 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
3049 if (hc->multi_count == 1) {
3050 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
3052 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
3056 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
3061 * This function does the setup for a data transfer for a host channel and
3062 * starts the transfer. May be called in either Slave mode or DMA mode. In
3063 * Slave mode, the caller must ensure that there is sufficient space in the
3064 * request queue and Tx Data FIFO.
3066 * For an OUT transfer in Slave mode, it loads a data packet into the
3067 * appropriate FIFO. If necessary, additional data packets will be loaded in
3070 * For an IN transfer in Slave mode, a data packet is requested. The data
3071 * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
3072 * additional data packets are requested in the Host ISR.
3074 * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
3075 * register along with a packet count of 1 and the channel is enabled. This
3076 * causes a single PING transaction to occur. Other fields in HCTSIZ are
3077 * simply set to 0 since no data transfer occurs in this case.
3079 * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
3080 * all the information required to perform the subsequent data transfer. In
3081 * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
3082 * controller performs the entire PING protocol, then starts the data
3085 * @param core_if Programming view of DWC_otg controller.
3086 * @param hc Information needed to initialize the host channel. The xfer_len
3087 * value may be reduced to accommodate the max widths of the XferSize and
3088 * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
3089 * to reflect the final xfer_len value.
3091 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3093 hcchar_data_t hcchar;
3094 hctsiz_data_t hctsiz;
3095 uint16_t num_packets;
3096 uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
3097 uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
3098 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3103 if (!core_if->dma_enable) {
3104 dwc_otg_hc_do_ping(core_if, hc);
3105 hc->xfer_started = 1;
3115 if (hc->complete_split && !hc->ep_is_in) {
3116 /* For CSPLIT OUT Transfer, set the size to 0 so the
3117 * core doesn't expect any data written to the FIFO */
3119 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
3120 hc->xfer_len = hc->max_packet;
3121 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
3125 hctsiz.b.xfersize = hc->xfer_len;
3128 * Ensure that the transfer length and packet count will fit
3129 * in the widths allocated for them in the HCTSIZn register.
3131 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3132 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3134 * Make sure the transfer size is no larger than one
3135 * (micro)frame's worth of data. (A check was done
3136 * when the periodic transfer was accepted to ensure
3137 * that a (micro)frame's worth of data can be
3138 * programmed into a channel.)
3140 uint32_t max_periodic_len =
3141 hc->multi_count * hc->max_packet;
3142 if (hc->xfer_len > max_periodic_len) {
3143 hc->xfer_len = max_periodic_len;
3146 } else if (hc->xfer_len > max_hc_xfer_size) {
3147 /* Make sure that xfer_len is a multiple of max packet size. */
3148 hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
3151 if (hc->xfer_len > 0) {
3153 (hc->xfer_len + hc->max_packet -
3154 1) / hc->max_packet;
3155 if (num_packets > max_hc_pkt_count) {
3156 num_packets = max_hc_pkt_count;
3157 hc->xfer_len = num_packets * hc->max_packet;
3160 /* Need 1 packet for transfer length of 0. */
3165 /* Always program an integral # of max packets for IN transfers. */
3166 hc->xfer_len = num_packets * hc->max_packet;
3169 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3170 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3172 * Make sure that the multi_count field matches the
3173 * actual transfer length.
3175 hc->multi_count = num_packets;
3178 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
3181 hctsiz.b.xfersize = hc->xfer_len;
3184 hc->start_pkt_count = num_packets;
3185 hctsiz.b.pktcnt = num_packets;
3186 hctsiz.b.pid = hc->data_pid_start;
3187 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3189 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3190 DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
3191 DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
3192 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
3194 if (core_if->dma_enable) {
3196 if (hc->align_buff) {
3197 dma_addr = hc->align_buff;
3199 dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
3201 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
3204 /* Start the split */
3206 hcsplt_data_t hcsplt;
3207 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
3208 hcsplt.b.spltena = 1;
3209 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
3212 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3213 hcchar.b.multicnt = hc->multi_count;
3214 hc_set_even_odd_frame(core_if, hc, &hcchar);
3216 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
3217 if (hcchar.b.chdis) {
3218 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
3219 __func__, hc->hc_num, hcchar.d32);
3223 /* Set host channel enable after all other setup is complete. */
3226 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3228 hc->xfer_started = 1;
3231 if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
3232 /* Load OUT packet into the appropriate Tx FIFO. */
3233 dwc_otg_hc_write_packet(core_if, hc);
3236 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
3237 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
3238 core_if->hc_xfer_info[hc->hc_num].hc = hc;
3240 /* Start a timer for this transfer. */
3241 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
3247 * This function does the setup for a data transfer for a host channel
3248 * and starts the transfer in Descriptor DMA mode.
3250 * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set.
3251 * Sets PID and NTD values. For periodic transfers
3252 * initializes SCHED_INFO field with micro-frame bitmap.
3254 * Initializes HCDMA register with descriptor list address and CTD value
3255 * then starts the transfer via enabling the channel.
3257 * @param core_if Programming view of DWC_otg controller.
3258 * @param hc Information needed to initialize the host channel.
3260 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3262 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3263 hcchar_data_t hcchar;
3264 hctsiz_data_t hctsiz;
3270 hctsiz.b_ddma.dopng = 1;
3272 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
3275 /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
3276 hctsiz.b_ddma.pid = hc->data_pid_start;
3277 hctsiz.b_ddma.ntd = hc->ntd - 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
3278 hctsiz.b_ddma.schinfo = hc->schinfo; /* Non-zero only for high-speed interrupt endpoints */
3280 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3281 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
3282 DWC_DEBUGPL(DBG_HCDV, " NTD: %d\n", hctsiz.b_ddma.ntd);
3284 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3287 hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
3289 /* Always start from first descriptor. */
3291 DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
3293 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3294 hcchar.b.multicnt = hc->multi_count;
3297 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
3298 if (hcchar.b.chdis) {
3299 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
3300 __func__, hc->hc_num, hcchar.d32);
3304 /* Set host channel enable after all other setup is complete. */
3308 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3310 hc->xfer_started = 1;
3314 if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
3315 && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
3316 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
3317 core_if->hc_xfer_info[hc->hc_num].hc = hc;
3318 /* Start a timer for this transfer. */
3319 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
3326 * This function continues a data transfer that was started by previous call
3327 * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
3328 * sufficient space in the request queue and Tx Data FIFO. This function
3329 * should only be called in Slave mode. In DMA mode, the controller acts
3330 * autonomously to complete transfers programmed to a host channel.
3332 * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
3333 * if there is any data remaining to be queued. For an IN transfer, another
3334 * data packet is always requested. For the SETUP phase of a control transfer,
3335 * this function does nothing.
3337 * @return 1 if a new request is queued, 0 if no more requests are required
3338 * for this transfer.
3340 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3342 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3345 /* SPLITs always queue just once per channel */
3347 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
3348 /* SETUPs are queued only once since they can't be NAKed. */
3350 } else if (hc->ep_is_in) {
3352 * Always queue another request for other IN transfers. If
3353 * back-to-back INs are issued and NAKs are received for both,
3354 * the driver may still be processing the first NAK when the
3355 * second NAK is received. When the interrupt handler clears
3356 * the NAK interrupt for the first NAK, the second NAK will
3357 * not be seen. So we can't depend on the NAK interrupt
3358 * handler to requeue a NAKed request. Instead, IN requests
3359 * are issued each time this function is called. When the
3360 * transfer completes, the extra requests for the channel will
3363 hcchar_data_t hcchar;
3364 dwc_otg_hc_regs_t *hc_regs =
3365 core_if->host_if->hc_regs[hc->hc_num];
3367 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3368 hc_set_even_odd_frame(core_if, hc, &hcchar);
3371 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
3373 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3377 /* OUT transfers. */
3378 if (hc->xfer_count < hc->xfer_len) {
3379 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3380 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3381 hcchar_data_t hcchar;
3382 dwc_otg_hc_regs_t *hc_regs;
3383 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3384 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3385 hc_set_even_odd_frame(core_if, hc, &hcchar);
3388 /* Load OUT packet into the appropriate Tx FIFO. */
3389 dwc_otg_hc_write_packet(core_if, hc);
3399 * Starts a PING transfer. This function should only be called in Slave mode.
3400 * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
3402 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3404 hcchar_data_t hcchar;
3405 hctsiz_data_t hctsiz;
3406 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3408 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3412 hctsiz.b.pktcnt = 1;
3413 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3415 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3418 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3422 * This function writes a packet into the Tx FIFO associated with the Host
3423 * Channel. For a channel associated with a non-periodic EP, the non-periodic
3424 * Tx FIFO is written. For a channel associated with a periodic EP, the
3425 * periodic Tx FIFO is written. This function should only be called in Slave
3428 * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
3429 * then number of bytes written to the Tx FIFO.
3431 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3434 uint32_t remaining_count;
3435 uint32_t byte_count;
3436 uint32_t dword_count;
3438 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
3439 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
3441 remaining_count = hc->xfer_len - hc->xfer_count;
3442 if (remaining_count > hc->max_packet) {
3443 byte_count = hc->max_packet;
3445 byte_count = remaining_count;
3448 dword_count = (byte_count + 3) / 4;
3450 if ((((unsigned long)data_buff) & 0x3) == 0) {
3451 /* xfer_buff is DWORD aligned. */
3452 for (i = 0; i < dword_count; i++, data_buff++) {
3453 DWC_WRITE_REG32(data_fifo, *data_buff);
3456 /* xfer_buff is not DWORD aligned. */
3457 for (i = 0; i < dword_count; i++, data_buff++) {
3460 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
3461 16 | data_buff[3] << 24);
3462 DWC_WRITE_REG32(data_fifo, data);
3466 hc->xfer_count += byte_count;
3467 hc->xfer_buff += byte_count;
3471 * Gets the current USB frame number. This is the frame number from the last
3474 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
3477 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
3479 /* read current frame/microframe number from DSTS register */
3480 return dsts.b.soffn;
3484 * Calculates and gets the frame Interval value of HFIR register according PHY
3485 * type and speed.The application can modify a value of HFIR register only after
3486 * the Port Enable bit of the Host Port Control and Status register
3487 * (HPRT.PrtEnaPort) has been set.
3490 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
3492 gusbcfg_data_t usbcfg;
3493 hwcfg2_data_t hwcfg2;
3495 int clock = 60; // default value
3496 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
3497 hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
3498 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
3499 if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3501 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
3503 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3504 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3506 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3507 !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3509 if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3510 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3512 if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
3514 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
3516 if (hprt0.b.prtspd == 0)
3517 /* High speed case */
3521 return 1000 * clock;
3525 * This function reads a setup packet from the Rx FIFO into the destination
3526 * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3527 * Interrupt routine when a SETUP packet has been received in Slave mode.
3529 * @param core_if Programming view of DWC_otg controller.
3530 * @param dest Destination buffer for packet data.
3532 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
3534 device_grxsts_data_t status;
3535 /* Get the 8 bytes of a setup transaction data */
3537 /* Pop 2 DWORDS off the receive data FIFO into memory */
3538 dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
3539 dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
3540 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
3542 DWC_READ_REG32(&core_if->core_global_regs->grxstsp);
3543 DWC_DEBUGPL(DBG_ANY,
3544 "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n",
3545 status.b.epnum, status.b.bcnt, status.b.pktsts,
3546 status.b.fn, status.b.fn);
3551 * This function enables EP0 OUT to receive SETUP packets and configures EP0
3552 * IN for transmitting packets. It is normally called when the
3553 * "Enumeration Done" interrupt occurs.
3555 * @param core_if Programming view of DWC_otg controller.
3556 * @param ep The EP0 data.
3558 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3560 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3562 depctl_data_t diepctl;
3563 depctl_data_t doepctl;
3564 dctl_data_t dctl = {.d32 = 0 };
3566 ep->stp_rollover = 0;
3567 /* Read the Device Status and Endpoint 0 Control registers */
3568 dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
3569 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
3570 doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
3572 /* Set the MPS of the IN EP based on the enumeration speed */
3573 switch (dsts.b.enumspd) {
3574 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
3575 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
3576 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
3577 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
3579 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3580 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3584 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3586 /* Enable OUT EP for receive */
3587 if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
3588 doepctl.b.epena = 1;
3589 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
3592 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
3593 DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
3594 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
3595 DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
3597 dctl.b.cgnpinnak = 1;
3599 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3600 DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
3601 DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
3606 * This function activates an EP. The Device EP control register for
3607 * the EP is configured as defined in the ep structure. Note: This
3608 * function is not used for EP0.
3610 * @param core_if Programming view of DWC_otg controller.
3611 * @param ep The EP to activate.
3613 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3615 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3616 depctl_data_t depctl;
3617 volatile uint32_t *addr;
3618 daint_data_t daintmsk = {.d32 = 0 };
3622 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3623 (ep->is_in ? "IN" : "OUT"));
3625 #ifdef DWC_UTE_PER_IO
3626 ep->xiso_frame_num = 0xFFFFFFFF;
3627 ep->xiso_active_xfers = 0;
3628 ep->xiso_queued_xfers = 0;
3630 /* Read DEPCTLn register */
3631 if (ep->is_in == 1) {
3632 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
3633 daintmsk.ep.in = 1 << ep->num;
3635 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3636 daintmsk.ep.out = 1 << ep->num;
3639 /* If the EP is already active don't change the EP Control
3641 depctl.d32 = DWC_READ_REG32(addr);
3642 if (!depctl.b.usbactep) {
3643 depctl.b.mps = ep->maxpacket;
3644 depctl.b.eptype = ep->type;
3645 depctl.b.txfnum = ep->tx_fifo_num;
3647 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3648 depctl.b.setd0pid = 1; // ???
3650 depctl.b.setd0pid = 1;
3652 depctl.b.usbactep = 1;
3654 /* Update nextep_seq array and EPMSCNT in DCFG */
3655 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) { // NP IN EP
3656 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3657 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
3660 core_if->nextep_seq[i] = ep->num;
3661 core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
3662 depctl.b.nextep = core_if->nextep_seq[ep->num];
3663 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
3665 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3667 DWC_DEBUGPL(DBG_PCDV,
3668 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3669 __func__, core_if->first_in_nextep_seq);
3670 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3671 DWC_DEBUGPL(DBG_PCDV, "%2d\n",
3672 core_if->nextep_seq[i]);
3678 DWC_WRITE_REG32(addr, depctl.d32);
3679 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
3682 /* Enable the Interrupt for this EP */
3683 if (core_if->multiproc_int_enable) {
3684 if (ep->is_in == 1) {
3685 diepmsk_data_t diepmsk = {.d32 = 0 };
3686 diepmsk.b.xfercompl = 1;
3687 diepmsk.b.timeout = 1;
3688 diepmsk.b.epdisabled = 1;
3689 diepmsk.b.ahberr = 1;
3690 diepmsk.b.intknepmis = 1;
3691 if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
3692 diepmsk.b.intknepmis = 0;
3693 diepmsk.b.txfifoundrn = 1; //?????
3694 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3699 if (core_if->dma_desc_enable) {
3704 if (core_if->dma_enable) {
3708 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3709 diepeachintmsk[ep->num], diepmsk.d32);
3712 doepmsk_data_t doepmsk = {.d32 = 0 };
3713 doepmsk.b.xfercompl = 1;
3714 doepmsk.b.ahberr = 1;
3715 doepmsk.b.epdisabled = 1;
3716 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3717 doepmsk.b.outtknepdis = 1;
3721 if (core_if->dma_desc_enable) {
3726 doepmsk.b.babble = 1;
3730 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3731 doepeachintmsk[ep->num], doepmsk.d32);
3733 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
3736 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3738 diepmsk_data_t diepmsk = {.d32 = 0 };
3740 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
3742 doepmsk_data_t doepmsk = {.d32 = 0 };
3743 doepmsk.b.outtknepdis = 1;
3744 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
3747 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
3751 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
3752 DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
3754 ep->stall_clear_flag = 0;
3760 * This function deactivates an EP. This is done by clearing the USB Active
3761 * EP bit in the Device EP control register. Note: This function is not used
3762 * for EP0. EP0 cannot be deactivated.
3764 * @param core_if Programming view of DWC_otg controller.
3765 * @param ep The EP to deactivate.
3767 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3769 depctl_data_t depctl = {.d32 = 0 };
3770 volatile uint32_t *addr;
3771 daint_data_t daintmsk = {.d32 = 0 };
3775 #ifdef DWC_UTE_PER_IO
3776 ep->xiso_frame_num = 0xFFFFFFFF;
3777 ep->xiso_active_xfers = 0;
3778 ep->xiso_queued_xfers = 0;
3781 /* Read DEPCTLn register */
3782 if (ep->is_in == 1) {
3783 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3784 daintmsk.ep.in = 1 << ep->num;
3786 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3787 daintmsk.ep.out = 1 << ep->num;
3790 depctl.d32 = DWC_READ_REG32(addr);
3792 depctl.b.usbactep = 0;
3794 /* Update nextep_seq array and EPMSCNT in DCFG */
3795 if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN
3796 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3797 if (core_if->nextep_seq[i] == ep->num)
3800 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];
3801 if (core_if->first_in_nextep_seq == ep->num)
3802 core_if->first_in_nextep_seq = i;
3803 core_if->nextep_seq[ep->num] = 0xff;
3804 depctl.b.nextep = 0;
3806 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
3808 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
3811 DWC_DEBUGPL(DBG_PCDV,
3812 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3813 __func__, core_if->first_in_nextep_seq);
3814 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3815 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
3820 depctl.b.txfnum = 0;
3822 if (core_if->dma_desc_enable)
3825 DWC_WRITE_REG32(addr, depctl.d32);
3826 depctl.d32 = DWC_READ_REG32(addr);
3827 if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC
3828 && depctl.b.epena) {
3829 depctl_data_t depctl = {.d32 = 0 };
3831 diepint_data_t diepint = {.d32 = 0 };
3834 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3835 diepctl, depctl.d32);
3839 DWC_READ_REG32(&core_if->
3840 dev_if->in_ep_regs[ep->num]->
3842 } while (!diepint.b.inepnakeff);
3843 diepint.b.inepnakeff = 1;
3844 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3845 diepint, diepint.d32);
3848 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3849 diepctl, depctl.d32);
3853 DWC_READ_REG32(&core_if->
3854 dev_if->in_ep_regs[ep->num]->
3856 } while (!diepint.b.epdisabled);
3857 diepint.b.epdisabled = 1;
3858 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3859 diepint, diepint.d32);
3861 dctl_data_t dctl = {.d32 = 0};
3862 gintmsk_data_t gintsts = {.d32 = 0};
3863 doepint_data_t doepint = {.d32 = 0};
3864 dctl.b.sgoutnak = 1;
3865 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3869 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
3870 } while (!gintsts.b.goutnakeff);
3872 gintsts.b.goutnakeff = 1;
3873 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
3878 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
3882 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
3883 out_ep_regs[ep->num]->doepint);
3884 } while (!doepint.b.epdisabled);
3886 doepint.b.epdisabled = 1;
3887 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
3890 dctl.b.cgoutnak = 1;
3891 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
3895 /* Disable the Interrupt for this EP */
3896 if (core_if->multiproc_int_enable) {
3897 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
3900 if (ep->is_in == 1) {
3901 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3902 diepeachintmsk[ep->num], 0);
3904 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3905 doepeachintmsk[ep->num], 0);
3908 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
3915 * This function initializes dma descriptor chain.
3917 * @param core_if Programming view of DWC_otg controller.
3918 * @param ep The EP to start the transfer on.
3920 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3922 dwc_otg_dev_dma_desc_t *dma_desc;
3926 unsigned maxxfer_local, total_len;
3928 if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR &&
3929 (ep->maxpacket % 4)) {
3930 maxxfer_local = ep->maxpacket;
3931 total_len = ep->xfer_len;
3933 maxxfer_local = ep->maxxfer;
3934 total_len = ep->total_len;
3937 ep->desc_cnt = (total_len / maxxfer_local) +
3938 ((total_len % maxxfer_local) ? 1 : 0);
3943 if (ep->desc_cnt > MAX_DMA_DESC_CNT)
3944 ep->desc_cnt = MAX_DMA_DESC_CNT;
3946 dma_desc = ep->desc_addr;
3947 if (maxxfer_local == ep->maxpacket) {
3948 if ((total_len % maxxfer_local) &&
3949 (total_len / maxxfer_local < MAX_DMA_DESC_CNT)) {
3950 xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
3951 (total_len % maxxfer_local);
3953 xfer_est = ep->desc_cnt * maxxfer_local;
3955 xfer_est = total_len;
3957 for (i = 0; i < ep->desc_cnt; ++i) {
3958 /** DMA Descriptor Setup */
3959 if (xfer_est > maxxfer_local) {
3960 dma_desc->status.b.bs = BS_HOST_BUSY;
3961 dma_desc->status.b.l = 0;
3962 dma_desc->status.b.ioc = 0;
3963 dma_desc->status.b.sp = 0;
3964 dma_desc->status.b.bytes = maxxfer_local;
3965 dma_desc->buf = ep->dma_addr + offset;
3966 dma_desc->status.b.sts = 0;
3967 dma_desc->status.b.bs = BS_HOST_READY;
3969 xfer_est -= maxxfer_local;
3970 offset += maxxfer_local;
3972 dma_desc->status.b.bs = BS_HOST_BUSY;
3973 dma_desc->status.b.l = 1;
3974 dma_desc->status.b.ioc = 1;
3976 dma_desc->status.b.sp =
3978 ep->maxpacket) ? 1 : ((ep->
3980 dma_desc->status.b.bytes = xfer_est;
3982 if (maxxfer_local == ep->maxpacket)
3983 dma_desc->status.b.bytes = xfer_est;
3985 dma_desc->status.b.bytes =
3986 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
3989 dma_desc->buf = ep->dma_addr + offset;
3990 dma_desc->status.b.sts = 0;
3991 dma_desc->status.b.bs = BS_HOST_READY;
3998 * This function is called when to write ISOC data into appropriate dedicated
4001 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
4003 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
4004 dwc_otg_dev_in_ep_regs_t *ep_regs;
4005 dtxfsts_data_t txstatus = {.d32 = 0 };
4007 int epnum = dwc_ep->num;
4010 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
4012 ep_regs = core_if->dev_if->in_ep_regs[epnum];
4014 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
4016 if (len > dwc_ep->maxpacket) {
4017 len = dwc_ep->maxpacket;
4020 dwords = (len + 3) / 4;
4022 /* While there is space in the queue and space in the FIFO and
4023 * More data to tranfer, Write packets to the Tx FIFO */
4024 txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
4025 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
4027 while (txstatus.b.txfspcavail > dwords &&
4028 dwc_ep->xfer_count < dwc_ep->xfer_len && dwc_ep->xfer_len != 0) {
4029 /* Write the FIFO */
4030 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
4032 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
4033 if (len > dwc_ep->maxpacket) {
4034 len = dwc_ep->maxpacket;
4037 dwords = (len + 3) / 4;
4039 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
4040 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
4044 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
4045 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
4051 * This function does the setup for a data transfer for an EP and
4052 * starts the transfer. For an IN transfer, the packets will be
4053 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
4054 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
4056 * @param core_if Programming view of DWC_otg controller.
4057 * @param ep The EP to start the transfer on.
4060 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4062 depctl_data_t depctl;
4063 deptsiz_data_t deptsiz;
4064 gintmsk_data_t intr_mask = {.d32 = 0 };
4066 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4067 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4068 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
4069 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
4070 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
4073 if (ep->is_in == 1) {
4074 dwc_otg_dev_in_ep_regs_t *in_regs =
4075 core_if->dev_if->in_ep_regs[ep->num];
4077 gnptxsts_data_t gtxstatus;
4080 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4082 if (core_if->en_multiple_tx_fifo == 0
4083 && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) {
4085 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
4090 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4091 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4093 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
4094 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
4095 ep->maxxfer : (ep->total_len - ep->xfer_len);
4097 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
4098 MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
4101 /* Zero Length Packet? */
4102 if ((ep->xfer_len - ep->xfer_count) == 0) {
4103 deptsiz.b.xfersize = 0;
4104 deptsiz.b.pktcnt = 1;
4106 /* Program the transfer size and packet count
4107 * as follows: xfersize = N * maxpacket +
4108 * short_packet pktcnt = N + (short_packet
4111 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
4113 (ep->xfer_len - ep->xfer_count - 1 +
4114 ep->maxpacket) / ep->maxpacket;
4115 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
4116 deptsiz.b.pktcnt = MAX_PKT_CNT;
4117 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
4119 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
4120 deptsiz.b.mc = deptsiz.b.pktcnt;
4123 /* Write the DMA register */
4124 if (core_if->dma_enable) {
4125 if (core_if->dma_desc_enable == 0) {
4126 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
4128 DWC_WRITE_REG32(&in_regs->dieptsiz,
4130 DWC_WRITE_REG32(&(in_regs->diepdma),
4131 (uint32_t) ep->dma_addr);
4134 /* The descriptor chain should be already initialized by now */
4135 if (ep->buff_mode != BM_STANDARD) {
4136 DWC_WRITE_REG32(&in_regs->diepdma,
4137 ep->descs_dma_addr);
4140 init_dma_desc_chain(core_if, ep);
4141 /** DIEPDMAn Register write */
4142 DWC_WRITE_REG32(&in_regs->diepdma,
4149 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4150 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
4152 * Enable the Non-Periodic Tx FIFO empty interrupt,
4153 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4154 * the data will be written into the fifo by the ISR.
4156 if (core_if->en_multiple_tx_fifo == 0) {
4157 intr_mask.b.nptxfempty = 1;
4159 (&core_if->core_global_regs->gintmsk,
4160 intr_mask.d32, intr_mask.d32);
4162 /* Enable the Tx FIFO Empty Interrupt for this EP */
4163 if (ep->xfer_len > 0) {
4164 uint32_t fifoemptymsk = 0;
4165 fifoemptymsk = 1 << ep->num;
4167 (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4173 write_isoc_tx_fifo(core_if, ep);
4176 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4177 depctl.b.nextep = core_if->nextep_seq[ep->num];
4179 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
4180 dsts_data_t dsts = {.d32 = 0 };
4181 if (ep->bInterval == 1) {
4183 DWC_READ_REG32(&core_if->dev_if->
4184 dev_global_regs->dsts);
4185 ep->frame_num = dsts.b.soffn + ep->bInterval;
4186 if (ep->frame_num > 0x3FFF) {
4187 ep->frm_overrun = 1;
4188 ep->frame_num &= 0x3FFF;
4190 ep->frm_overrun = 0;
4191 if (ep->frame_num & 0x1) {
4192 depctl.b.setd1pid = 1;
4194 depctl.b.setd0pid = 1;
4198 /* EP enable, IN data in FIFO */
4201 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4205 dwc_otg_dev_out_ep_regs_t *out_regs =
4206 core_if->dev_if->out_ep_regs[ep->num];
4208 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4209 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4211 if (!core_if->dma_desc_enable) {
4212 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
4213 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
4214 ep->maxxfer : (ep->total_len - ep->xfer_len);
4216 ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len
4217 - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
4220 /* Program the transfer size and packet count as follows:
4223 * xfersize = N * maxpacket
4225 if ((ep->xfer_len - ep->xfer_count) == 0) {
4226 /* Zero Length Packet */
4227 deptsiz.b.xfersize = ep->maxpacket;
4228 deptsiz.b.pktcnt = 1;
4231 (ep->xfer_len - ep->xfer_count +
4232 (ep->maxpacket - 1)) / ep->maxpacket;
4233 if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
4234 deptsiz.b.pktcnt = MAX_PKT_CNT;
4236 if (!core_if->dma_desc_enable) {
4238 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
4240 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
4243 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
4244 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4246 if (core_if->dma_enable) {
4247 if (!core_if->dma_desc_enable) {
4248 DWC_WRITE_REG32(&out_regs->doeptsiz,
4251 DWC_WRITE_REG32(&(out_regs->doepdma),
4252 (uint32_t) ep->dma_addr);
4255 /* The descriptor chain should be already initialized by now */
4256 if (ep->buff_mode != BM_STANDARD) {
4257 DWC_WRITE_REG32(&out_regs->doepdma,
4258 ep->descs_dma_addr);
4261 /** This is used for interrupt out transfers*/
4263 ep->xfer_len = ep->total_len;
4264 init_dma_desc_chain(core_if, ep);
4266 if (core_if->core_params->dev_out_nak) {
4267 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
4268 deptsiz.b.pktcnt = (ep->total_len +
4269 (ep->maxpacket - 1)) / ep->maxpacket;
4270 deptsiz.b.xfersize = ep->total_len;
4271 /* Remember initial value of doeptsiz */
4272 core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
4273 DWC_WRITE_REG32(&out_regs->doeptsiz,
4277 /** DOEPDMAn Register write */
4278 DWC_WRITE_REG32(&out_regs->doepdma,
4285 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4288 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
4289 dsts_data_t dsts = {.d32 = 0 };
4290 if (ep->bInterval == 1) {
4292 DWC_READ_REG32(&core_if->dev_if->
4293 dev_global_regs->dsts);
4294 ep->frame_num = dsts.b.soffn + ep->bInterval;
4295 if (ep->frame_num > 0x3FFF) {
4296 ep->frm_overrun = 1;
4297 ep->frame_num &= 0x3FFF;
4299 ep->frm_overrun = 0;
4301 if (ep->frame_num & 0x1) {
4302 depctl.b.setd1pid = 1;
4304 depctl.b.setd0pid = 1;
4313 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4315 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
4316 DWC_READ_REG32(&out_regs->doepctl),
4317 DWC_READ_REG32(&out_regs->doeptsiz));
4318 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
4319 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->
4321 DWC_READ_REG32(&core_if->core_global_regs->
4324 /* Timer is scheduling only for out bulk transfers for
4325 * "Device DDMA OUT NAK Enhancement" feature to inform user
4326 * about received data payload in case of timeout
4328 if (core_if->core_params->dev_out_nak) {
4329 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
4330 core_if->ep_xfer_info[ep->num].core_if = core_if;
4331 core_if->ep_xfer_info[ep->num].ep = ep;
4332 core_if->ep_xfer_info[ep->num].state = 1;
4334 /* Start a timer for this transfer. */
4335 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
4342 * This function setup a zero length transfer in Buffer DMA and
4343 * Slave modes for usb requests with zero field set
4345 * @param core_if Programming view of DWC_otg controller.
4346 * @param ep The EP to start the transfer on.
4349 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4352 depctl_data_t depctl;
4353 deptsiz_data_t deptsiz;
4354 gintmsk_data_t intr_mask = {.d32 = 0 };
4356 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4357 DWC_PRINTF("zero length transfer is called\n");
4360 if (ep->is_in == 1) {
4361 dwc_otg_dev_in_ep_regs_t *in_regs =
4362 core_if->dev_if->in_ep_regs[ep->num];
4364 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4365 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4367 deptsiz.b.xfersize = 0;
4368 deptsiz.b.pktcnt = 1;
4370 /* Write the DMA register */
4371 if (core_if->dma_enable) {
4372 if (core_if->dma_desc_enable == 0) {
4374 DWC_WRITE_REG32(&in_regs->dieptsiz,
4376 DWC_WRITE_REG32(&(in_regs->diepdma),
4377 (uint32_t) ep->dma_addr);
4380 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4382 * Enable the Non-Periodic Tx FIFO empty interrupt,
4383 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4384 * the data will be written into the fifo by the ISR.
4386 if (core_if->en_multiple_tx_fifo == 0) {
4387 intr_mask.b.nptxfempty = 1;
4388 DWC_MODIFY_REG32(&core_if->
4389 core_global_regs->gintmsk,
4390 intr_mask.d32, intr_mask.d32);
4392 /* Enable the Tx FIFO Empty Interrupt for this EP */
4393 if (ep->xfer_len > 0) {
4394 uint32_t fifoemptymsk = 0;
4395 fifoemptymsk = 1 << ep->num;
4396 DWC_MODIFY_REG32(&core_if->
4397 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4403 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4404 depctl.b.nextep = core_if->nextep_seq[ep->num];
4405 /* EP enable, IN data in FIFO */
4408 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4412 dwc_otg_dev_out_ep_regs_t *out_regs =
4413 core_if->dev_if->out_ep_regs[ep->num];
4415 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4416 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4418 /* Zero Length Packet */
4419 deptsiz.b.xfersize = ep->maxpacket;
4420 deptsiz.b.pktcnt = 1;
4422 if (core_if->dma_enable) {
4423 if (!core_if->dma_desc_enable) {
4424 DWC_WRITE_REG32(&out_regs->doeptsiz,
4427 DWC_WRITE_REG32(&(out_regs->doepdma),
4428 (uint32_t) ep->dma_addr);
4431 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4438 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4444 * This function does the setup for a data transfer for EP0 and starts
4445 * the transfer. For an IN transfer, the packets will be loaded into
4446 * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
4447 * unloaded from the Rx FIFO in the ISR.
4449 * @param core_if Programming view of DWC_otg controller.
4450 * @param ep The EP0 data.
4452 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4454 depctl_data_t depctl;
4455 deptsiz0_data_t deptsiz;
4456 gintmsk_data_t intr_mask = {.d32 = 0 };
4457 dwc_otg_dev_dma_desc_t *dma_desc;
4459 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4460 "xfer_buff=%p start_xfer_buff=%p \n",
4461 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
4462 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
4464 ep->total_len = ep->xfer_len;
4467 if (ep->is_in == 1) {
4468 dwc_otg_dev_in_ep_regs_t *in_regs =
4469 core_if->dev_if->in_ep_regs[0];
4471 gnptxsts_data_t gtxstatus;
4473 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4474 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4480 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4482 /* If dedicated FIFO every time flush fifo before enable ep*/
4483 if (core_if->en_multiple_tx_fifo && core_if->snpsid >= OTG_CORE_REV_3_00a)
4484 dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
4486 if (core_if->en_multiple_tx_fifo == 0
4487 && gtxstatus.b.nptxqspcavail == 0
4488 && !core_if->dma_enable) {
4490 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4491 DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
4492 DWC_READ_REG32(&in_regs->diepctl));
4493 DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
4495 deptsiz.b.xfersize, deptsiz.b.pktcnt);
4496 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4502 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4503 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4505 /* Zero Length Packet? */
4506 if (ep->xfer_len == 0) {
4507 deptsiz.b.xfersize = 0;
4508 deptsiz.b.pktcnt = 1;
4510 /* Program the transfer size and packet count
4511 * as follows: xfersize = N * maxpacket +
4512 * short_packet pktcnt = N + (short_packet
4515 if (ep->xfer_len > ep->maxpacket) {
4516 ep->xfer_len = ep->maxpacket;
4517 deptsiz.b.xfersize = ep->maxpacket;
4519 deptsiz.b.xfersize = ep->xfer_len;
4521 deptsiz.b.pktcnt = 1;
4524 DWC_DEBUGPL(DBG_PCDV,
4525 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4526 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4529 /* Write the DMA register */
4530 if (core_if->dma_enable) {
4531 if (core_if->dma_desc_enable == 0) {
4532 DWC_WRITE_REG32(&in_regs->dieptsiz,
4535 DWC_WRITE_REG32(&(in_regs->diepdma),
4536 (uint32_t) ep->dma_addr);
4538 dma_desc = core_if->dev_if->in_desc_addr;
4540 /** DMA Descriptor Setup */
4541 dma_desc->status.b.bs = BS_HOST_BUSY;
4542 dma_desc->status.b.l = 1;
4543 dma_desc->status.b.ioc = 1;
4544 dma_desc->status.b.sp =
4545 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4546 dma_desc->status.b.bytes = ep->xfer_len;
4547 dma_desc->buf = ep->dma_addr;
4548 dma_desc->status.b.sts = 0;
4549 dma_desc->status.b.bs = BS_HOST_READY;
4551 /** DIEPDMA0 Register write */
4552 DWC_WRITE_REG32(&in_regs->diepdma,
4554 dev_if->dma_in_desc_addr);
4557 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4560 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4561 depctl.b.nextep = core_if->nextep_seq[ep->num];
4562 /* EP enable, IN data in FIFO */
4565 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4568 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4569 * data will be written into the fifo by the ISR.
4571 if (!core_if->dma_enable) {
4572 if (core_if->en_multiple_tx_fifo == 0) {
4573 intr_mask.b.nptxfempty = 1;
4574 DWC_MODIFY_REG32(&core_if->
4575 core_global_regs->gintmsk,
4576 intr_mask.d32, intr_mask.d32);
4578 /* Enable the Tx FIFO Empty Interrupt for this EP */
4579 if (ep->xfer_len > 0) {
4580 uint32_t fifoemptymsk = 0;
4581 fifoemptymsk |= 1 << ep->num;
4582 DWC_MODIFY_REG32(&core_if->
4583 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4590 dwc_otg_dev_out_ep_regs_t *out_regs =
4591 core_if->dev_if->out_ep_regs[0];
4593 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4594 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4596 /* Program the transfer size and packet count as follows:
4597 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4599 /* Zero Length Packet */
4600 deptsiz.b.xfersize = ep->maxpacket;
4601 deptsiz.b.pktcnt = 1;
4602 if (core_if->snpsid >= OTG_CORE_REV_3_00a)
4603 deptsiz.b.supcnt = 3;
4605 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
4606 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4608 if (core_if->dma_enable) {
4609 if (!core_if->dma_desc_enable) {
4610 DWC_WRITE_REG32(&out_regs->doeptsiz,
4613 DWC_WRITE_REG32(&(out_regs->doepdma),
4614 (uint32_t) ep->dma_addr);
4616 dma_desc = core_if->dev_if->out_desc_addr;
4618 /** DMA Descriptor Setup */
4619 dma_desc->status.b.bs = BS_HOST_BUSY;
4620 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4621 dma_desc->status.b.mtrf = 0;
4622 dma_desc->status.b.sr = 0;
4624 dma_desc->status.b.l = 1;
4625 dma_desc->status.b.ioc = 1;
4626 dma_desc->status.b.bytes = ep->maxpacket;
4627 dma_desc->buf = ep->dma_addr;
4628 dma_desc->status.b.sts = 0;
4629 dma_desc->status.b.bs = BS_HOST_READY;
4631 /** DOEPDMA0 Register write */
4632 DWC_WRITE_REG32(&out_regs->doepdma,
4637 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4643 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
4648 * This function continues control IN transfers started by
4649 * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
4650 * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
4651 * bit for the packet count.
4653 * @param core_if Programming view of DWC_otg controller.
4654 * @param ep The EP0 data.
4656 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4658 depctl_data_t depctl;
4659 deptsiz0_data_t deptsiz;
4660 gintmsk_data_t intr_mask = {.d32 = 0 };
4661 dwc_otg_dev_dma_desc_t *dma_desc;
4663 if (ep->is_in == 1) {
4664 dwc_otg_dev_in_ep_regs_t *in_regs =
4665 core_if->dev_if->in_ep_regs[0];
4666 gnptxsts_data_t tx_status = {.d32 = 0 };
4669 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4670 /** @todo Should there be check for room in the Tx
4671 * Status Queue. If not remove the code above this comment. */
4673 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4674 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4676 /* Program the transfer size and packet count
4677 * as follows: xfersize = N * maxpacket +
4678 * short_packet pktcnt = N + (short_packet
4682 if (core_if->dma_desc_enable == 0) {
4683 deptsiz.b.xfersize =
4684 (ep->total_len - ep->xfer_count) >
4685 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4687 deptsiz.b.pktcnt = 1;
4688 if (core_if->dma_enable == 0) {
4689 ep->xfer_len += deptsiz.b.xfersize;
4691 ep->xfer_len = deptsiz.b.xfersize;
4693 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4696 (ep->total_len - ep->xfer_count) >
4697 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4700 dma_desc = core_if->dev_if->in_desc_addr;
4702 /** DMA Descriptor Setup */
4703 dma_desc->status.b.bs = BS_HOST_BUSY;
4704 dma_desc->status.b.l = 1;
4705 dma_desc->status.b.ioc = 1;
4706 dma_desc->status.b.sp =
4707 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4708 dma_desc->status.b.bytes = ep->xfer_len;
4709 dma_desc->buf = ep->dma_addr;
4710 dma_desc->status.b.sts = 0;
4711 dma_desc->status.b.bs = BS_HOST_READY;
4713 /** DIEPDMA0 Register write */
4714 DWC_WRITE_REG32(&in_regs->diepdma,
4715 core_if->dev_if->dma_in_desc_addr);
4718 DWC_DEBUGPL(DBG_PCDV,
4719 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4720 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4723 /* Write the DMA register */
4724 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4725 if (core_if->dma_desc_enable == 0)
4726 DWC_WRITE_REG32(&(in_regs->diepdma),
4727 (uint32_t) ep->dma_addr);
4729 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4730 depctl.b.nextep = core_if->nextep_seq[ep->num];
4731 /* EP enable, IN data in FIFO */
4734 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4737 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4738 * data will be written into the fifo by the ISR.
4740 if (!core_if->dma_enable) {
4741 if (core_if->en_multiple_tx_fifo == 0) {
4742 /* First clear it from GINTSTS */
4743 intr_mask.b.nptxfempty = 1;
4744 DWC_MODIFY_REG32(&core_if->
4745 core_global_regs->gintmsk,
4746 intr_mask.d32, intr_mask.d32);
4749 /* Enable the Tx FIFO Empty Interrupt for this EP */
4750 if (ep->xfer_len > 0) {
4751 uint32_t fifoemptymsk = 0;
4752 fifoemptymsk |= 1 << ep->num;
4753 DWC_MODIFY_REG32(&core_if->
4754 dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4760 dwc_otg_dev_out_ep_regs_t *out_regs =
4761 core_if->dev_if->out_ep_regs[0];
4763 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4764 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4766 /* Program the transfer size and packet count
4767 * as follows: xfersize = N * maxpacket +
4768 * short_packet pktcnt = N + (short_packet
4771 deptsiz.b.xfersize = ep->maxpacket;
4772 deptsiz.b.pktcnt = 1;
4774 if (core_if->dma_desc_enable == 0) {
4775 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4777 dma_desc = core_if->dev_if->out_desc_addr;
4779 /** DMA Descriptor Setup */
4780 dma_desc->status.b.bs = BS_HOST_BUSY;
4781 dma_desc->status.b.l = 1;
4782 dma_desc->status.b.ioc = 1;
4783 dma_desc->status.b.bytes = ep->maxpacket;
4784 dma_desc->buf = ep->dma_addr;
4785 dma_desc->status.b.sts = 0;
4786 dma_desc->status.b.bs = BS_HOST_READY;
4788 /** DOEPDMA0 Register write */
4789 DWC_WRITE_REG32(&out_regs->doepdma,
4790 core_if->dev_if->dma_out_desc_addr);
4793 DWC_DEBUGPL(DBG_PCDV,
4794 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4795 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4798 /* Write the DMA register */
4799 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4800 if (core_if->dma_desc_enable == 0)
4801 DWC_WRITE_REG32(&(out_regs->doepdma),
4802 (uint32_t) ep->dma_addr);
4806 /* EP enable, IN data in FIFO */
4809 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4815 void dump_msg(const u8 * buf, unsigned int length)
4817 unsigned int start, num, i;
4823 while (length > 0) {
4824 num = length < 16u ? length : 16u;
4826 for (i = 0; i < num; ++i) {
4829 DWC_SPRINTF(p, " %02x", buf[i]);
4833 DWC_PRINTF("%6x: %s\n", start, line);
4840 static inline void dump_msg(const u8 * buf, unsigned int length)
4846 * This function writes a packet into the Tx FIFO associated with the
4847 * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
4848 * periodic EPs the periodic Tx FIFO associated with the EP is written
4849 * with all packets for the next micro-frame.
4851 * @param core_if Programming view of DWC_otg controller.
4852 * @param ep The EP to write packet for.
4853 * @param dma Indicates if DMA is being used.
4855 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
4859 * The buffer is padded to DWORD on a per packet basis in
4860 * slave/dma mode if the MPS is not DWORD aligned. The last
4861 * packet, if short, is also padded to a multiple of DWORD.
4863 * ep->xfer_buff always starts DWORD aligned in memory and is a
4864 * multiple of DWORD in length
4866 * ep->xfer_len can be any number of bytes
4868 * ep->xfer_count is a multiple of ep->maxpacket until the last
4871 * FIFO access is DWORD */
4874 uint32_t byte_count;
4875 uint32_t dword_count;
4877 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
4879 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
4881 if (ep->xfer_count >= ep->xfer_len) {
4882 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4886 /* Find the byte length of the packet either short packet or MPS */
4887 if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
4888 byte_count = ep->xfer_len - ep->xfer_count;
4890 byte_count = ep->maxpacket;
4893 /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4894 * is not a multiple of DWORD */
4895 dword_count = (byte_count + 3) / 4;
4898 dump_msg(ep->xfer_buff, byte_count);
4901 /**@todo NGS Where are the Periodic Tx FIFO addresses
4902 * intialized? What should this be? */
4904 fifo = core_if->data_fifo[ep->num];
4906 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
4907 fifo, data_buff, *data_buff, byte_count);
4910 for (i = 0; i < dword_count; i++, data_buff++) {
4911 DWC_WRITE_REG32(fifo, *data_buff);
4915 ep->xfer_count += byte_count;
4916 ep->xfer_buff += byte_count;
4917 ep->dma_addr += byte_count;
4923 * @param core_if Programming view of DWC_otg controller.
4924 * @param ep The EP to set the stall on.
4926 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4928 depctl_data_t depctl;
4929 volatile uint32_t *depctl_addr;
4931 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4932 (ep->is_in ? "IN" : "OUT"));
4934 if (ep->is_in == 1) {
4935 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4936 depctl.d32 = DWC_READ_REG32(depctl_addr);
4938 /* set the disable and stall bits */
4939 if (depctl.b.epena) {
4943 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4945 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4946 depctl.d32 = DWC_READ_REG32(depctl_addr);
4948 /* set the stall bit */
4950 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4953 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4959 * Clear the EP STALL.
4961 * @param core_if Programming view of DWC_otg controller.
4962 * @param ep The EP to clear stall from.
4964 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4966 depctl_data_t depctl;
4967 volatile uint32_t *depctl_addr;
4969 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4970 (ep->is_in ? "IN" : "OUT"));
4972 if (ep->is_in == 1) {
4973 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4975 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4978 depctl.d32 = DWC_READ_REG32(depctl_addr);
4980 /* clear the stall bits */
4984 * USB Spec 9.4.5: For endpoints using data toggle, regardless
4985 * of whether an endpoint has the Halt feature set, a
4986 * ClearFeature(ENDPOINT_HALT) request always results in the
4987 * data toggle being reinitialized to DATA0.
4989 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4990 ep->type == DWC_OTG_EP_TYPE_BULK) {
4991 depctl.b.setd0pid = 1; /* DATA0 */
4994 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4995 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
5000 * This function reads a packet from the Rx FIFO into the destination
5001 * buffer. To read SETUP data use dwc_otg_read_setup_packet.
5003 * @param core_if Programming view of DWC_otg controller.
5004 * @param dest Destination buffer for the packet.
5005 * @param bytes Number of bytes to copy to the destination.
5007 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
5008 uint8_t * dest, uint16_t bytes)
5011 int word_count = (bytes + 3) / 4;
5013 volatile uint32_t *fifo = core_if->data_fifo[0];
5014 uint32_t *data_buff = (uint32_t *) dest;
5017 * @todo Account for the case where _dest is not dword aligned. This
5018 * requires reading data from the FIFO into a uint32_t temp buffer,
5019 * then moving it into the data buffer.
5022 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
5023 core_if, dest, bytes);
5025 for (i = 0; i < word_count; i++, data_buff++) {
5026 *data_buff = DWC_READ_REG32(fifo);
5033 * This functions reads the device registers and prints them
5035 * @param core_if Programming view of DWC_otg controller.
5037 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
5040 volatile uint32_t *addr;
5043 hwcfg1 = ~core_if->core_global_regs->ghwcfg1;
5045 DWC_PRINTF("Device Global Registers\n");
5046 addr = &core_if->dev_if->dev_global_regs->dcfg;
5047 DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n",
5048 (unsigned long)addr, DWC_READ_REG32(addr));
5049 addr = &core_if->dev_if->dev_global_regs->dctl;
5050 DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n",
5051 (unsigned long)addr, DWC_READ_REG32(addr));
5052 addr = &core_if->dev_if->dev_global_regs->dsts;
5053 DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n",
5054 (unsigned long)addr, DWC_READ_REG32(addr));
5055 addr = &core_if->dev_if->dev_global_regs->diepmsk;
5056 DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5057 DWC_READ_REG32(addr));
5058 addr = &core_if->dev_if->dev_global_regs->doepmsk;
5059 DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5060 DWC_READ_REG32(addr));
5061 addr = &core_if->dev_if->dev_global_regs->daint;
5062 DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
5063 DWC_READ_REG32(addr));
5064 addr = &core_if->dev_if->dev_global_regs->daintmsk;
5065 DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5066 DWC_READ_REG32(addr));
5067 addr = &core_if->dev_if->dev_global_regs->dtknqr1;
5068 DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5069 DWC_READ_REG32(addr));
5070 if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
5071 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
5072 DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n",
5073 (unsigned long)addr, DWC_READ_REG32(addr));
5076 addr = &core_if->dev_if->dev_global_regs->dvbusdis;
5077 DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
5078 DWC_READ_REG32(addr));
5080 addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
5081 DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n",
5082 (unsigned long)addr, DWC_READ_REG32(addr));
5084 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
5085 DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n",
5086 (unsigned long)addr, DWC_READ_REG32(addr));
5088 if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
5089 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
5090 DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n",
5091 (unsigned long)addr, DWC_READ_REG32(addr));
5094 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
5095 DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5096 DWC_READ_REG32(addr));
5098 if (core_if->hwcfg2.b.multi_proc_int) {
5100 addr = &core_if->dev_if->dev_global_regs->deachint;
5101 DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n",
5102 (unsigned long)addr, DWC_READ_REG32(addr));
5103 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
5104 DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n",
5105 (unsigned long)addr, DWC_READ_REG32(addr));
5107 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
5110 dev_global_regs->diepeachintmsk[i];
5111 DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
5112 i, (unsigned long)addr,
5113 DWC_READ_REG32(addr));
5116 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
5119 dev_global_regs->doepeachintmsk[i];
5120 DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
5121 i, (unsigned long)addr,
5122 DWC_READ_REG32(addr));
5126 for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
5127 if(hwcfg1 & (2<<(i<<1))){
5128 DWC_PRINTF("Device IN EP %d Registers\n", i);
5129 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
5130 DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n",
5131 (unsigned long)addr, DWC_READ_REG32(addr));
5132 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
5133 DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n",
5134 (unsigned long)addr, DWC_READ_REG32(addr));
5135 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
5136 DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n",
5137 (unsigned long)addr, DWC_READ_REG32(addr));
5138 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
5139 DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n",
5140 (unsigned long)addr, DWC_READ_REG32(addr));
5141 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
5142 DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n",
5143 (unsigned long)addr, DWC_READ_REG32(addr));
5144 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
5145 DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n",
5146 (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ );
5150 for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
5151 if(hwcfg1 & (1<<(i<<1))){
5152 DWC_PRINTF("Device OUT EP %d Registers\n", i);
5153 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
5154 DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n",
5155 (unsigned long)addr, DWC_READ_REG32(addr));
5156 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
5157 DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n",
5158 (unsigned long)addr, DWC_READ_REG32(addr));
5159 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
5160 DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n",
5161 (unsigned long)addr, DWC_READ_REG32(addr));
5162 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
5163 DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n",
5164 (unsigned long)addr, DWC_READ_REG32(addr));
5165 if (core_if->dma_enable) { /* Don't access this register in SLAVE mode */
5166 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
5167 DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n",
5168 (unsigned long)addr, DWC_READ_REG32(addr));
5176 * This functions reads the SPRAM and prints its content
5178 * @param core_if Programming view of DWC_otg controller.
5180 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
5182 volatile uint8_t *addr, *start_addr, *end_addr;
5184 DWC_PRINTF("SPRAM Data:\n");
5185 start_addr = (void *)core_if->core_global_regs;
5186 DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
5187 start_addr += 0x00028000;
5188 end_addr = (void *)core_if->core_global_regs;
5189 end_addr += 0x000280e0;
5191 for (addr = start_addr; addr < end_addr; addr += 16) {
5193 ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
5194 (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
5195 addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
5196 addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
5204 * This function reads the host registers and prints them
5206 * @param core_if Programming view of DWC_otg controller.
5208 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
5211 volatile uint32_t *addr;
5213 DWC_PRINTF("Host Global Registers\n");
5214 addr = &core_if->host_if->host_global_regs->hcfg;
5215 DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n",
5216 (unsigned long)addr, DWC_READ_REG32(addr));
5217 addr = &core_if->host_if->host_global_regs->hfir;
5218 DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n",
5219 (unsigned long)addr, DWC_READ_REG32(addr));
5220 addr = &core_if->host_if->host_global_regs->hfnum;
5221 DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr,
5222 DWC_READ_REG32(addr));
5223 addr = &core_if->host_if->host_global_regs->hptxsts;
5224 DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
5225 DWC_READ_REG32(addr));
5226 addr = &core_if->host_if->host_global_regs->haint;
5227 DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
5228 DWC_READ_REG32(addr));
5229 addr = &core_if->host_if->host_global_regs->haintmsk;
5230 DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5231 DWC_READ_REG32(addr));
5232 if (core_if->dma_desc_enable) {
5233 addr = &core_if->host_if->host_global_regs->hflbaddr;
5234 DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n",
5235 (unsigned long)addr, DWC_READ_REG32(addr));
5238 addr = core_if->host_if->hprt0;
5239 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5240 DWC_READ_REG32(addr));
5242 for (i = 0; i < core_if->core_params->host_channels; i++) {
5243 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
5244 addr = &core_if->host_if->hc_regs[i]->hcchar;
5245 DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n",
5246 (unsigned long)addr, DWC_READ_REG32(addr));
5247 addr = &core_if->host_if->hc_regs[i]->hcsplt;
5248 DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n",
5249 (unsigned long)addr, DWC_READ_REG32(addr));
5250 addr = &core_if->host_if->hc_regs[i]->hcint;
5251 DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n",
5252 (unsigned long)addr, DWC_READ_REG32(addr));
5253 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
5254 DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n",
5255 (unsigned long)addr, DWC_READ_REG32(addr));
5256 addr = &core_if->host_if->hc_regs[i]->hctsiz;
5257 DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n",
5258 (unsigned long)addr, DWC_READ_REG32(addr));
5259 addr = &core_if->host_if->hc_regs[i]->hcdma;
5260 DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n",
5261 (unsigned long)addr, DWC_READ_REG32(addr));
5262 if (core_if->dma_desc_enable) {
5263 addr = &core_if->host_if->hc_regs[i]->hcdmab;
5264 DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n",
5265 (unsigned long)addr, DWC_READ_REG32(addr));
5273 * This function reads the core global registers and prints them
5275 * @param core_if Programming view of DWC_otg controller.
5277 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
5280 volatile uint32_t *addr;
5283 DWC_PRINTF("Core Global Registers\n");
5284 addr = &core_if->core_global_regs->gotgctl;
5285 DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5286 DWC_READ_REG32(addr));
5287 addr = &core_if->core_global_regs->gotgint;
5288 DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr,
5289 DWC_READ_REG32(addr));
5290 addr = &core_if->core_global_regs->gahbcfg;
5291 DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5292 DWC_READ_REG32(addr));
5293 addr = &core_if->core_global_regs->gusbcfg;
5294 DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5295 DWC_READ_REG32(addr));
5296 addr = &core_if->core_global_regs->grstctl;
5297 DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5298 DWC_READ_REG32(addr));
5299 addr = &core_if->core_global_regs->gintsts;
5300 DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
5301 DWC_READ_REG32(addr));
5302 addr = &core_if->core_global_regs->gintmsk;
5303 DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr,
5304 DWC_READ_REG32(addr));
5305 addr = &core_if->core_global_regs->grxstsr;
5306 DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr,
5307 DWC_READ_REG32(addr));
5308 addr = &core_if->core_global_regs->grxfsiz;
5309 DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
5310 DWC_READ_REG32(addr));
5311 addr = &core_if->core_global_regs->gnptxfsiz;
5312 DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
5313 DWC_READ_REG32(addr));
5314 addr = &core_if->core_global_regs->gnptxsts;
5315 DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr,
5316 DWC_READ_REG32(addr));
5317 addr = &core_if->core_global_regs->gi2cctl;
5318 DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5319 DWC_READ_REG32(addr));
5320 addr = &core_if->core_global_regs->gpvndctl;
5321 DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5322 DWC_READ_REG32(addr));
5323 addr = &core_if->core_global_regs->ggpio;
5324 DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr,
5325 DWC_READ_REG32(addr));
5326 addr = &core_if->core_global_regs->guid;
5327 DWC_PRINTF("GUID @0x%08lX : 0x%08X\n",
5328 (unsigned long)addr, DWC_READ_REG32(addr));
5329 addr = &core_if->core_global_regs->gsnpsid;
5330 DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr,
5331 DWC_READ_REG32(addr));
5332 addr = &core_if->core_global_regs->ghwcfg1;
5333 DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5334 DWC_READ_REG32(addr));
5335 addr = &core_if->core_global_regs->ghwcfg2;
5336 DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5337 DWC_READ_REG32(addr));
5338 addr = &core_if->core_global_regs->ghwcfg3;
5339 DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5340 DWC_READ_REG32(addr));
5341 addr = &core_if->core_global_regs->ghwcfg4;
5342 DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr,
5343 DWC_READ_REG32(addr));
5344 addr = &core_if->core_global_regs->glpmcfg;
5345 DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5346 DWC_READ_REG32(addr));
5347 addr = &core_if->core_global_regs->gpwrdn;
5348 DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr,
5349 DWC_READ_REG32(addr));
5350 addr = &core_if->core_global_regs->gdfifocfg;
5351 DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr,
5352 DWC_READ_REG32(addr));
5353 addr = &core_if->core_global_regs->adpctl;
5354 DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5355 dwc_otg_adp_read_reg(core_if));
5356 addr = &core_if->core_global_regs->hptxfsiz;
5357 DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
5358 DWC_READ_REG32(addr));
5360 if (core_if->en_multiple_tx_fifo == 0) {
5361 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
5362 txfsiz = "DPTXFSIZ";
5364 ep_num = core_if->hwcfg4.b.num_in_eps;
5365 txfsiz = "DIENPTXF";
5367 for (i = 0; i < ep_num; i++) {
5368 addr = &core_if->core_global_regs->dtxfsiz[i];
5369 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
5370 (unsigned long)addr, DWC_READ_REG32(addr));
5372 addr = core_if->pcgcctl;
5373 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5374 DWC_READ_REG32(addr));
5380 * @param core_if Programming view of DWC_otg controller.
5381 * @param num Tx FIFO to flush.
5383 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
5385 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5386 volatile grstctl_t greset = {.d32 = 0 };
5389 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
5391 greset.b.txfflsh = 1;
5392 greset.b.txfnum = num;
5393 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5396 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5397 if (++count > 10000) {
5398 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5399 __func__, greset.d32,
5400 DWC_READ_REG32(&global_regs->gnptxsts));
5404 } while (greset.b.txfflsh == 1);
5406 /* Wait for 3 PHY Clocks */
5413 * @param core_if Programming view of DWC_otg controller.
5415 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
5417 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5418 volatile grstctl_t greset = {.d32 = 0 };
5421 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5425 greset.b.rxfflsh = 1;
5426 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5429 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5430 if (++count > 10000) {
5431 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5436 } while (greset.b.rxfflsh == 1);
5438 /* Wait for 3 PHY Clocks */
5443 * Do core a soft reset of the core. Be careful with this because it
5444 * resets all the internal state machines of the core.
5446 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
5448 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5449 volatile grstctl_t greset = {.d32 = 0 };
5450 volatile gusbcfg_data_t usbcfg = { .d32 = 0 };
5453 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5454 /* Wait for AHB master IDLE state. */
5457 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5458 if (++count > 100000) {
5459 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5464 while (greset.b.ahbidle == 0);
5466 /* Core Soft Reset */
5468 greset.b.csftrst = 1;
5469 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5471 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5472 if (++count > 10000) {
5473 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5474 __func__, greset.d32);
5479 while (greset.b.csftrst == 1);
5480 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
5481 if(core_if->usb_mode == USB_MODE_FORCE_HOST)
5483 usbcfg.b.force_host_mode = 1;
5484 usbcfg.b.force_dev_mode = 0;
5485 } else if(core_if->usb_mode == USB_MODE_FORCE_DEVICE)
5487 usbcfg.b.force_host_mode = 0;
5488 usbcfg.b.force_dev_mode = 1;
5491 usbcfg.b.force_host_mode = 0;
5492 usbcfg.b.force_dev_mode = 0;
5494 DWC_WRITE_REG32( &global_regs->gusbcfg, usbcfg.d32 );
5496 /* Wait for 3 PHY Clocks */
5501 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
5503 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5506 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
5508 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5512 * Register HCD callbacks. The callbacks are used to start and stop
5513 * the HCD for interrupt processing.
5515 * @param core_if Programming view of DWC_otg controller.
5516 * @param cb the HCD callback structure.
5517 * @param p pointer to be passed to callback function (usb_hcd*).
5519 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
5520 dwc_otg_cil_callbacks_t * cb, void *p)
5522 core_if->hcd_cb = cb;
5524 core_if->hcd_cb_p = p;
5528 * Register PCD callbacks. The callbacks are used to start and stop
5529 * the PCD for interrupt processing.
5531 * @param core_if Programming view of DWC_otg controller.
5532 * @param cb the PCD callback structure.
5533 * @param p pointer to be passed to callback function (pcd*).
5535 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
5536 dwc_otg_cil_callbacks_t * cb, void *p)
5538 core_if->pcd_cb = cb;
5545 * This function writes isoc data per 1 (micro)frame into tx fifo
5547 * @param core_if Programming view of DWC_otg controller.
5548 * @param ep The EP to start the transfer on.
5551 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
5553 dwc_otg_dev_in_ep_regs_t *ep_regs;
5554 dtxfsts_data_t txstatus = {.d32 = 0 };
5558 ep->xfer_len = ep->data_per_frame;
5561 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
5563 len = ep->xfer_len - ep->xfer_count;
5565 if (len > ep->maxpacket) {
5566 len = ep->maxpacket;
5569 dwords = (len + 3) / 4;
5571 /* While there is space in the queue and space in the FIFO and
5572 * More data to tranfer, Write packets to the Tx FIFO */
5574 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
5575 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
5577 while (txstatus.b.txfspcavail > dwords &&
5578 ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
5579 /* Write the FIFO */
5580 dwc_otg_ep_write_packet(core_if, ep, 0);
5582 len = ep->xfer_len - ep->xfer_count;
5583 if (len > ep->maxpacket) {
5584 len = ep->maxpacket;
5587 dwords = (len + 3) / 4;
5589 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
5591 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
5597 * This function initializes a descriptor chain for Isochronous transfer
5599 * @param core_if Programming view of DWC_otg controller.
5600 * @param ep The EP to start the transfer on.
5603 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
5606 deptsiz_data_t deptsiz = {.d32 = 0 };
5607 depctl_data_t depctl = {.d32 = 0 };
5608 dsts_data_t dsts = {.d32 = 0 };
5609 volatile uint32_t *addr;
5612 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5614 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5617 ep->xfer_len = ep->data_per_frame;
5619 ep->xfer_buff = ep->cur_pkt_addr;
5620 ep->dma_addr = ep->cur_pkt_dma_addr;
5623 /* Program the transfer size and packet count
5624 * as follows: xfersize = N * maxpacket +
5625 * short_packet pktcnt = N + (short_packet
5628 deptsiz.b.xfersize = ep->xfer_len;
5630 (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
5631 deptsiz.b.mc = deptsiz.b.pktcnt;
5632 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
5635 /* Write the DMA register */
5636 if (core_if->dma_enable) {
5638 (core_if->dev_if->in_ep_regs[ep->num]->
5639 diepdma), (uint32_t) ep->dma_addr);
5643 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
5644 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5646 DWC_WRITE_REG32(&core_if->dev_if->
5647 out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
5649 if (core_if->dma_enable) {
5652 out_ep_regs[ep->num]->doepdma),
5653 (uint32_t) ep->dma_addr);
5657 /** Enable endpoint, clear nak */
5660 if (ep->bInterval == 1) {
5662 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
5663 ep->next_frame = dsts.b.soffn + ep->bInterval;
5665 if (ep->next_frame & 0x1) {
5666 depctl.b.setd1pid = 1;
5668 depctl.b.setd0pid = 1;
5671 ep->next_frame += ep->bInterval;
5673 if (ep->next_frame & 0x1) {
5674 depctl.b.setd1pid = 1;
5676 depctl.b.setd0pid = 1;
5682 DWC_MODIFY_REG32(addr, 0, depctl.d32);
5683 depctl.d32 = DWC_READ_REG32(addr);
5685 if (ep->is_in && core_if->dma_enable == 0) {
5686 write_isoc_frame_data(core_if, ep);
5690 #endif /* DWC_EN_ISOC */
5692 static void dwc_otg_set_uninitialized(int32_t * p, int size)
5695 for (i = 0; i < size; i++) {
5700 static int dwc_otg_param_initialized(int32_t val)
5705 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
5707 gintsts_data_t gintsts;
5708 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
5710 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
5711 if (!core_if->core_params) {
5712 return -DWC_E_NO_MEMORY;
5714 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
5715 sizeof(*core_if->core_params) /
5717 DWC_PRINTF("Setting default values for core params\n");
5718 dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
5719 dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
5720 dwc_otg_set_param_dma_desc_enable(core_if,
5721 dwc_param_dma_desc_enable_default);
5722 dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
5723 dwc_otg_set_param_dma_burst_size(core_if,
5724 dwc_param_dma_burst_size_default);
5725 dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
5726 dwc_param_host_support_fs_ls_low_power_default);
5727 dwc_otg_set_param_enable_dynamic_fifo(core_if,
5728 dwc_param_enable_dynamic_fifo_default);
5729 dwc_otg_set_param_data_fifo_size(core_if,
5730 dwc_param_data_fifo_size_default);
5731 dwc_otg_set_param_dev_rx_fifo_size(core_if,
5732 dwc_param_dev_rx_fifo_size_default);
5733 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
5734 dwc_param_dev_nperio_tx_fifo_size_default);
5735 dwc_otg_set_param_host_rx_fifo_size(core_if,
5736 dwc_param_host_rx_fifo_size_default);
5737 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
5738 dwc_param_host_nperio_tx_fifo_size_default);
5739 dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
5740 dwc_param_host_perio_tx_fifo_size_default);
5741 dwc_otg_set_param_max_transfer_size(core_if,
5742 dwc_param_max_transfer_size_default);
5743 dwc_otg_set_param_max_packet_count(core_if,
5744 dwc_param_max_packet_count_default);
5745 dwc_otg_set_param_host_channels(core_if,
5746 dwc_param_host_channels_default);
5747 dwc_otg_set_param_dev_endpoints(core_if,
5748 dwc_param_dev_endpoints_default);
5749 dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
5750 dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
5751 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
5752 dwc_param_host_ls_low_power_phy_clk_default);
5753 dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
5754 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
5755 dwc_param_phy_ulpi_ext_vbus_default);
5756 dwc_otg_set_param_phy_utmi_width(core_if,
5757 dwc_param_phy_utmi_width_default);
5758 dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
5759 dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
5760 dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
5761 dwc_otg_set_param_en_multiple_tx_fifo(core_if,
5762 dwc_param_en_multiple_tx_fifo_default);
5764 /* do not set dev_perio_tx_fifo_size and dev_tx_fifo_size here
5765 * set validate parameter values in "set_parameters" later.
5768 if (gintsts.b.curmode) {
5769 /* Force device mode to get power-on values of device FIFOs */
5770 gusbcfg_data_t gusbcfg = {.d32 = 0 };
5771 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5772 gusbcfg.b.force_dev_mode = 1;
5773 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5775 for (i = 0; i < 15; i++) {
5776 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5777 dwc_param_dev_perio_tx_fifo_size_default, i);
5779 for (i = 0; i < 15; i++) {
5780 dwc_otg_set_param_dev_tx_fifo_size(core_if,
5781 dwc_param_dev_tx_fifo_size_default, i);
5783 gusbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5784 gusbcfg.b.force_dev_mode = 0;
5785 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5788 for (i = 0; i < 15; i++) {
5789 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5790 dwc_param_dev_perio_tx_fifo_size_default, i);
5792 for (i = 0; i < 15; i++) {
5793 dwc_otg_set_param_dev_tx_fifo_size(core_if,
5794 dwc_param_dev_tx_fifo_size_default, i);
5798 dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
5799 dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
5800 dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
5801 dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
5803 dwc_otg_set_param_besl_enable(core_if, dwc_param_besl_enable_default);
5804 dwc_otg_set_param_baseline_besl(core_if, dwc_param_baseline_besl_default);
5805 dwc_otg_set_param_deep_besl(core_if, dwc_param_deep_besl_default);
5807 dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
5808 dwc_otg_set_param_tx_thr_length(core_if,
5809 dwc_param_tx_thr_length_default);
5810 dwc_otg_set_param_rx_thr_length(core_if,
5811 dwc_param_rx_thr_length_default);
5812 dwc_otg_set_param_ahb_thr_ratio(core_if,
5813 dwc_param_ahb_thr_ratio_default);
5814 dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
5815 dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
5816 dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
5817 dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
5818 dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
5819 dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
5820 dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
5824 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
5826 return core_if->dma_enable;
5829 /* Checks if the parameter is outside of its valid range of values */
5830 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
5831 (((_param_) < (_low_)) || \
5832 ((_param_) > (_high_)))
5834 /* Parameter access functions */
5835 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
5839 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5840 DWC_WARN("Wrong value for otg_cap parameter\n");
5841 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
5842 retval = -DWC_E_INVALID;
5848 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
5849 if (core_if->hwcfg2.b.op_mode !=
5850 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5853 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
5854 if ((core_if->hwcfg2.b.op_mode !=
5855 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5856 && (core_if->hwcfg2.b.op_mode !=
5857 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5858 && (core_if->hwcfg2.b.op_mode !=
5859 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5860 && (core_if->hwcfg2.b.op_mode !=
5861 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
5865 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
5870 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
5872 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5876 (((core_if->hwcfg2.b.op_mode ==
5877 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5878 || (core_if->hwcfg2.b.op_mode ==
5879 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5880 || (core_if->hwcfg2.b.op_mode ==
5881 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5882 || (core_if->hwcfg2.b.op_mode ==
5883 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
5884 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
5885 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
5886 retval = -DWC_E_INVALID;
5889 core_if->core_params->otg_cap = val;
5894 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
5896 return core_if->core_params->otg_cap;
5899 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
5901 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5902 DWC_WARN("Wrong value for opt parameter\n");
5903 return -DWC_E_INVALID;
5905 core_if->core_params->opt = val;
5909 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
5911 return core_if->core_params->opt;
5914 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
5917 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5918 DWC_WARN("Wrong value for dma enable\n");
5919 return -DWC_E_INVALID;
5922 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
5923 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
5925 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5929 retval = -DWC_E_INVALID;
5932 core_if->core_params->dma_enable = val;
5934 dwc_otg_set_param_dma_desc_enable(core_if, 0);
5939 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
5941 return core_if->core_params->dma_enable;
5944 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
5947 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5948 DWC_WARN("Wrong value for dma_enable\n");
5949 DWC_WARN("dma_desc_enable must be 0 or 1\n");
5950 return -DWC_E_INVALID;
5954 && ((dwc_otg_get_param_dma_enable(core_if) == 0)
5955 || (core_if->hwcfg4.b.desc_dma == 0))) {
5956 if (dwc_otg_param_initialized
5957 (core_if->core_params->dma_desc_enable)) {
5959 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5963 retval = -DWC_E_INVALID;
5965 core_if->core_params->dma_desc_enable = val;
5969 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
5971 return core_if->core_params->dma_desc_enable;
5974 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
5977 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5978 DWC_WARN("Wrong value for host_support_fs_low_power\n");
5979 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
5980 return -DWC_E_INVALID;
5982 core_if->core_params->host_support_fs_ls_low_power = val;
5986 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
5989 return core_if->core_params->host_support_fs_ls_low_power;
5992 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
5996 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5997 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
5998 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
5999 return -DWC_E_INVALID;
6002 if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
6003 if (dwc_otg_param_initialized
6004 (core_if->core_params->enable_dynamic_fifo)) {
6006 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
6010 retval = -DWC_E_INVALID;
6012 core_if->core_params->enable_dynamic_fifo = val;
6016 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
6018 return core_if->core_params->enable_dynamic_fifo;
6021 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
6024 if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
6025 DWC_WARN("Wrong value for data_fifo_size\n");
6026 DWC_WARN("data_fifo_size must be 32-32768\n");
6027 return -DWC_E_INVALID;
6030 if (val > core_if->hwcfg3.b.dfifo_depth) {
6031 if (dwc_otg_param_initialized
6032 (core_if->core_params->data_fifo_size)) {
6034 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
6037 val = core_if->hwcfg3.b.dfifo_depth;
6038 retval = -DWC_E_INVALID;
6041 core_if->core_params->data_fifo_size = val;
6045 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
6047 return core_if->core_params->data_fifo_size;
6050 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
6053 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6054 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
6055 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
6056 return -DWC_E_INVALID;
6059 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
6060 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
6061 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
6063 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
6064 retval = -DWC_E_INVALID;
6067 core_if->core_params->dev_rx_fifo_size = val;
6071 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
6073 return core_if->core_params->dev_rx_fifo_size;
6076 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6081 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6082 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
6083 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
6084 return -DWC_E_INVALID;
6087 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
6088 if (dwc_otg_param_initialized
6089 (core_if->core_params->dev_nperio_tx_fifo_size)) {
6091 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
6095 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
6097 retval = -DWC_E_INVALID;
6100 core_if->core_params->dev_nperio_tx_fifo_size = val;
6104 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
6106 return core_if->core_params->dev_nperio_tx_fifo_size;
6109 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
6114 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6115 DWC_WARN("Wrong value for host_rx_fifo_size\n");
6116 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
6117 return -DWC_E_INVALID;
6120 if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
6121 if (dwc_otg_param_initialized
6122 (core_if->core_params->host_rx_fifo_size)) {
6124 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
6127 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
6128 retval = -DWC_E_INVALID;
6131 core_if->core_params->host_rx_fifo_size = val;
6136 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
6138 return core_if->core_params->host_rx_fifo_size;
6141 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6146 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6147 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
6148 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
6149 return -DWC_E_INVALID;
6152 if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
6153 if (dwc_otg_param_initialized
6154 (core_if->core_params->host_nperio_tx_fifo_size)) {
6156 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
6160 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
6162 retval = -DWC_E_INVALID;
6165 core_if->core_params->host_nperio_tx_fifo_size = val;
6169 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
6171 return core_if->core_params->host_nperio_tx_fifo_size;
6174 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6178 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6179 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
6180 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
6181 return -DWC_E_INVALID;
6184 if (val > ((core_if->hptxfsiz.d32) >> 16)) {
6185 if (dwc_otg_param_initialized
6186 (core_if->core_params->host_perio_tx_fifo_size)) {
6188 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
6191 val = (core_if->hptxfsiz.d32) >> 16;
6192 retval = -DWC_E_INVALID;
6195 core_if->core_params->host_perio_tx_fifo_size = val;
6199 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
6201 return core_if->core_params->host_perio_tx_fifo_size;
6204 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
6209 if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
6210 DWC_WARN("Wrong value for max_transfer_size\n");
6211 DWC_WARN("max_transfer_size must be 2047-524288\n");
6212 return -DWC_E_INVALID;
6215 if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
6216 if (dwc_otg_param_initialized
6217 (core_if->core_params->max_transfer_size)) {
6219 ("%d invalid for max_transfer_size. Check HW configuration.\n",
6223 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
6225 retval = -DWC_E_INVALID;
6228 core_if->core_params->max_transfer_size = val;
6232 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
6234 return core_if->core_params->max_transfer_size;
6237 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
6241 if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
6242 DWC_WARN("Wrong value for max_packet_count\n");
6243 DWC_WARN("max_packet_count must be 15-511\n");
6244 return -DWC_E_INVALID;
6247 if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
6248 if (dwc_otg_param_initialized
6249 (core_if->core_params->max_packet_count)) {
6251 ("%d invalid for max_packet_count. Check HW configuration.\n",
6255 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
6256 retval = -DWC_E_INVALID;
6259 core_if->core_params->max_packet_count = val;
6263 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
6265 return core_if->core_params->max_packet_count;
6268 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
6272 if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
6273 DWC_WARN("Wrong value for host_channels\n");
6274 DWC_WARN("host_channels must be 1-16\n");
6275 return -DWC_E_INVALID;
6278 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
6279 if (dwc_otg_param_initialized
6280 (core_if->core_params->host_channels)) {
6282 ("%d invalid for host_channels. Check HW configurations.\n",
6285 val = (core_if->hwcfg2.b.num_host_chan + 1);
6286 retval = -DWC_E_INVALID;
6289 core_if->core_params->host_channels = val;
6293 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
6295 return core_if->core_params->host_channels;
6298 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
6302 if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
6303 DWC_WARN("Wrong value for dev_endpoints\n");
6304 DWC_WARN("dev_endpoints must be 1-15\n");
6305 return -DWC_E_INVALID;
6308 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
6309 if (dwc_otg_param_initialized
6310 (core_if->core_params->dev_endpoints)) {
6312 ("%d invalid for dev_endpoints. Check HW configurations.\n",
6315 val = core_if->hwcfg2.b.num_dev_ep;
6316 retval = -DWC_E_INVALID;
6319 core_if->core_params->dev_endpoints = val;
6323 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
6325 return core_if->core_params->dev_endpoints;
6328 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
6333 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
6334 DWC_WARN("Wrong value for phy_type\n");
6335 DWC_WARN("phy_type must be 0,1 or 2\n");
6336 return -DWC_E_INVALID;
6338 #ifndef NO_FS_PHY_HW_CHECKS
6339 if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
6340 ((core_if->hwcfg2.b.hs_phy_type == 1) ||
6341 (core_if->hwcfg2.b.hs_phy_type == 3))) {
6343 } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
6344 ((core_if->hwcfg2.b.hs_phy_type == 2) ||
6345 (core_if->hwcfg2.b.hs_phy_type == 3))) {
6347 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
6348 (core_if->hwcfg2.b.fs_phy_type == 1)) {
6352 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
6354 ("%d invalid for phy_type. Check HW configurations.\n",
6357 if (core_if->hwcfg2.b.hs_phy_type) {
6358 if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
6359 (core_if->hwcfg2.b.hs_phy_type == 1)) {
6360 val = DWC_PHY_TYPE_PARAM_UTMI;
6362 val = DWC_PHY_TYPE_PARAM_ULPI;
6365 retval = -DWC_E_INVALID;
6368 core_if->core_params->phy_type = val;
6372 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
6374 return core_if->core_params->phy_type;
6377 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
6380 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6381 DWC_WARN("Wrong value for speed parameter\n");
6382 DWC_WARN("max_speed parameter must be 0 or 1\n");
6383 return -DWC_E_INVALID;
6386 && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
6387 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
6389 ("%d invalid for speed paremter. Check HW configuration.\n",
6393 (dwc_otg_get_param_phy_type(core_if) ==
6394 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
6395 retval = -DWC_E_INVALID;
6397 core_if->core_params->speed = val;
6401 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
6403 return core_if->core_params->speed;
6406 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
6411 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6413 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
6414 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
6415 return -DWC_E_INVALID;
6418 if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
6419 && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
6420 if (dwc_otg_param_initialized
6421 (core_if->core_params->host_ls_low_power_phy_clk)) {
6423 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6427 (dwc_otg_get_param_phy_type(core_if) ==
6428 DWC_PHY_TYPE_PARAM_FS) ?
6429 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
6430 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
6431 retval = -DWC_E_INVALID;
6434 core_if->core_params->host_ls_low_power_phy_clk = val;
6438 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
6440 return core_if->core_params->host_ls_low_power_phy_clk;
6443 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
6445 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6446 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
6447 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
6448 return -DWC_E_INVALID;
6451 core_if->core_params->phy_ulpi_ddr = val;
6455 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
6457 return core_if->core_params->phy_ulpi_ddr;
6460 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
6463 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6464 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
6465 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
6466 return -DWC_E_INVALID;
6469 core_if->core_params->phy_ulpi_ext_vbus = val;
6473 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
6475 return core_if->core_params->phy_ulpi_ext_vbus;
6478 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
6480 if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
6481 DWC_WARN("Wrong valaue for phy_utmi_width\n");
6482 DWC_WARN("phy_utmi_width must be 8 or 16\n");
6483 return -DWC_E_INVALID;
6486 core_if->core_params->phy_utmi_width = val;
6490 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
6492 return core_if->core_params->phy_utmi_width;
6495 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
6497 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6498 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
6499 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
6500 return -DWC_E_INVALID;
6503 core_if->core_params->ulpi_fs_ls = val;
6507 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
6509 return core_if->core_params->ulpi_fs_ls;
6512 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
6514 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6515 DWC_WARN("Wrong valaue for ts_dline\n");
6516 DWC_WARN("ts_dline must be 0 or 1\n");
6517 return -DWC_E_INVALID;
6520 core_if->core_params->ts_dline = val;
6524 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
6526 return core_if->core_params->ts_dline;
6529 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
6532 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6533 DWC_WARN("Wrong valaue for i2c_enable\n");
6534 DWC_WARN("i2c_enable must be 0 or 1\n");
6535 return -DWC_E_INVALID;
6537 #ifndef NO_FS_PHY_HW_CHECK
6538 if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
6539 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
6541 ("%d invalid for i2c_enable. Check HW configuration.\n",
6545 retval = -DWC_E_INVALID;
6549 core_if->core_params->i2c_enable = val;
6553 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
6555 return core_if->core_params->i2c_enable;
6558 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6559 int32_t val, int fifo_num)
6562 gintsts_data_t gintsts;
6563 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6565 if (core_if->hwcfg4.b.ded_fifo_en == 0){
6566 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
6567 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
6568 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
6569 return -DWC_E_INVALID;
6572 if (val > (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16)) {
6573 printk("%d ",DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6574 printk("val = %d fifo_num = %d\n",val,fifo_num);
6575 DWC_WARN("Value is larger then power-on FIFO size\n");
6576 if (dwc_otg_param_initialized
6577 (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
6579 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6582 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6583 retval = -DWC_E_INVALID;
6586 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
6591 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6594 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
6597 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
6601 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6602 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
6603 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
6604 return -DWC_E_INVALID;
6607 if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
6608 if (dwc_otg_param_initialized
6609 (core_if->core_params->en_multiple_tx_fifo)) {
6611 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6615 retval = -DWC_E_INVALID;
6618 core_if->core_params->en_multiple_tx_fifo = val;
6622 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
6624 return core_if->core_params->en_multiple_tx_fifo;
6627 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
6631 fifosize_data_t txfifosize;
6632 txfifosize.d32 = DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]);
6634 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6635 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
6636 DWC_WARN("dev_tx_fifo_size must be 16-32768\n");
6637 return -DWC_E_INVALID;
6640 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
6644 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
6647 return core_if->core_params->dev_tx_fifo_size[fifo_num];
6650 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6654 if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
6655 DWC_WARN("Wrong value for thr_ctl\n");
6656 DWC_WARN("thr_ctl must be 0-7\n");
6657 return -DWC_E_INVALID;
6661 (!dwc_otg_get_param_dma_enable(core_if) ||
6662 !core_if->hwcfg4.b.ded_fifo_en)) {
6663 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
6665 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6669 retval = -DWC_E_INVALID;
6672 core_if->core_params->thr_ctl = val;
6676 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
6678 return core_if->core_params->thr_ctl;
6681 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
6685 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6686 DWC_WARN("Wrong value for lpm_enable\n");
6687 DWC_WARN("lpm_enable must be 0 or 1\n");
6688 return -DWC_E_INVALID;
6691 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
6692 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
6694 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6698 retval = -DWC_E_INVALID;
6701 core_if->core_params->lpm_enable = val;
6705 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
6707 return core_if->core_params->lpm_enable;
6710 int dwc_otg_set_param_besl_enable(dwc_otg_core_if_t * core_if, int32_t val)
6714 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6715 DWC_WARN("Wrong value for besl_enable\n");
6716 DWC_WARN("besl_enable must be 0 or 1\n");
6717 return -DWC_E_INVALID;
6720 core_if->core_params->besl_enable = val;
6724 retval += dwc_otg_set_param_lpm_enable(core_if,val);
6730 int32_t dwc_otg_get_param_besl_enable(dwc_otg_core_if_t * core_if)
6732 return core_if->core_params->besl_enable;
6735 int dwc_otg_set_param_baseline_besl(dwc_otg_core_if_t * core_if, int32_t val)
6739 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6740 DWC_WARN("Wrong value for baseline_besl\n");
6741 DWC_WARN("baseline_besl must be 0-15\n");
6742 return -DWC_E_INVALID;
6745 core_if->core_params->baseline_besl = val;
6749 int32_t dwc_otg_get_param_baseline_besl(dwc_otg_core_if_t * core_if)
6751 return core_if->core_params->baseline_besl;
6754 int dwc_otg_set_param_deep_besl(dwc_otg_core_if_t * core_if, int32_t val)
6758 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6759 DWC_WARN("Wrong value for deep_besl\n");
6760 DWC_WARN("deep_besl must be 0-15\n");
6761 return -DWC_E_INVALID;
6764 core_if->core_params->deep_besl = val;
6768 int32_t dwc_otg_get_param_deep_besl(dwc_otg_core_if_t * core_if)
6770 return core_if->core_params->deep_besl;
6773 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6775 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6776 DWC_WARN("Wrong valaue for tx_thr_length\n");
6777 DWC_WARN("tx_thr_length must be 8 - 128\n");
6778 return -DWC_E_INVALID;
6781 core_if->core_params->tx_thr_length = val;
6785 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
6787 return core_if->core_params->tx_thr_length;
6790 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6792 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6793 DWC_WARN("Wrong valaue for rx_thr_length\n");
6794 DWC_WARN("rx_thr_length must be 8 - 128\n");
6795 return -DWC_E_INVALID;
6798 core_if->core_params->rx_thr_length = val;
6802 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
6804 return core_if->core_params->rx_thr_length;
6807 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
6809 if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
6810 DWC_OTG_PARAM_TEST(val, 4, 4) &&
6811 DWC_OTG_PARAM_TEST(val, 8, 8) &&
6812 DWC_OTG_PARAM_TEST(val, 16, 16) &&
6813 DWC_OTG_PARAM_TEST(val, 32, 32) &&
6814 DWC_OTG_PARAM_TEST(val, 64, 64) &&
6815 DWC_OTG_PARAM_TEST(val, 128, 128) &&
6816 DWC_OTG_PARAM_TEST(val, 256, 256)) {
6817 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
6818 return -DWC_E_INVALID;
6820 core_if->core_params->dma_burst_size = val;
6824 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
6826 return core_if->core_params->dma_burst_size;
6829 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
6832 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6833 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
6834 return -DWC_E_INVALID;
6836 if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
6837 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
6839 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6842 retval = -DWC_E_INVALID;
6845 core_if->core_params->pti_enable = val;
6849 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
6851 return core_if->core_params->pti_enable;
6854 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
6857 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6858 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
6859 return -DWC_E_INVALID;
6861 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
6862 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
6864 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6867 retval = -DWC_E_INVALID;
6870 core_if->core_params->mpi_enable = val;
6874 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
6876 return core_if->core_params->mpi_enable;
6879 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
6882 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6883 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
6884 return -DWC_E_INVALID;
6886 if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
6887 if (dwc_otg_param_initialized
6888 (core_if->core_params->adp_supp_enable)) {
6890 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6893 retval = -DWC_E_INVALID;
6896 core_if->core_params->adp_supp_enable = val;
6897 /* Set OTG version 2.0 in case of enabling ADP */
6899 dwc_otg_set_param_otg_ver(core_if, 1);
6904 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
6906 return core_if->core_params->adp_supp_enable;
6909 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
6912 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6913 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
6914 DWC_WARN("ic_usb_cap must be 0 or 1\n");
6915 return -DWC_E_INVALID;
6918 if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
6919 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
6921 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6924 retval = -DWC_E_INVALID;
6927 core_if->core_params->ic_usb_cap = val;
6931 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
6933 return core_if->core_params->ic_usb_cap;
6936 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
6941 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6942 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
6943 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
6944 return -DWC_E_INVALID;
6948 && (core_if->snpsid < OTG_CORE_REV_2_81a
6949 || !dwc_otg_get_param_thr_ctl(core_if))) {
6952 && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
6957 if (dwc_otg_param_initialized
6958 (core_if->core_params->ahb_thr_ratio)) {
6960 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6963 retval = -DWC_E_INVALID;
6967 core_if->core_params->ahb_thr_ratio = val;
6971 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
6973 return core_if->core_params->ahb_thr_ratio;
6976 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
6980 hwcfg4_data_t hwcfg4 = {.d32 = 0 };
6981 hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
6983 if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6984 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
6985 DWC_WARN("power_down must be 0 - 2\n");
6986 return -DWC_E_INVALID;
6989 if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
6993 && ((core_if->snpsid < OTG_CORE_REV_3_00a)
6994 || (hwcfg4.b.xhiber == 0))) {
6998 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
7000 ("%d invalid for parameter power_down. Check HW configuration.\n",
7003 retval = -DWC_E_INVALID;
7006 core_if->core_params->power_down = val;
7010 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
7012 return core_if->core_params->power_down;
7015 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
7020 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
7021 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
7022 DWC_WARN("reload_ctl must be 0 or 1\n");
7023 return -DWC_E_INVALID;
7026 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
7030 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
7031 DWC_ERROR("%d invalid for parameter reload_ctl."
7032 "Check HW configuration.\n", val);
7034 retval = -DWC_E_INVALID;
7037 core_if->core_params->reload_ctl = val;
7041 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
7043 return core_if->core_params->reload_ctl;
7046 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
7051 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
7052 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
7053 DWC_WARN("dev_out_nak must be 0 or 1\n");
7054 return -DWC_E_INVALID;
7057 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
7058 !(core_if->core_params->dma_desc_enable))) {
7062 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
7063 DWC_ERROR("%d invalid for parameter dev_out_nak."
7064 "Check HW configuration.\n", val);
7066 retval = -DWC_E_INVALID;
7069 core_if->core_params->dev_out_nak = val;
7073 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
7075 return core_if->core_params->dev_out_nak;
7078 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
7083 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
7084 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
7085 DWC_WARN("cont_on_bna must be 0 or 1\n");
7086 return -DWC_E_INVALID;
7089 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
7090 !(core_if->core_params->dma_desc_enable))) {
7094 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
7095 DWC_ERROR("%d invalid for parameter cont_on_bna."
7096 "Check HW configuration.\n", val);
7098 retval = -DWC_E_INVALID;
7101 core_if->core_params->cont_on_bna = val;
7105 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
7107 return core_if->core_params->cont_on_bna;
7110 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
7115 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
7116 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
7117 DWC_WARN("ahb_single must be 0 or 1\n");
7118 return -DWC_E_INVALID;
7121 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
7125 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
7126 DWC_ERROR("%d invalid for parameter ahb_single."
7127 "Check HW configuration.\n", val);
7129 retval = -DWC_E_INVALID;
7132 core_if->core_params->ahb_single = val;
7136 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
7138 return core_if->core_params->ahb_single;
7141 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
7145 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
7146 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
7148 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
7149 return -DWC_E_INVALID;
7152 core_if->core_params->otg_ver = val;
7156 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
7158 return core_if->core_params->otg_ver;
7161 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
7163 gotgctl_data_t otgctl;
7164 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7165 return otgctl.b.hstnegscs;
7168 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
7170 gotgctl_data_t otgctl;
7171 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7172 return otgctl.b.sesreqscs;
7175 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
7177 if(core_if->otg_ver == 0) {
7178 gotgctl_data_t otgctl;
7179 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7180 otgctl.b.hnpreq = val;
7181 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
7183 core_if->otg_sts = val;
7187 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
7189 return core_if->snpsid;
7192 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
7194 gintsts_data_t gintsts;
7195 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
7196 return gintsts.b.curmode;
7199 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
7201 gusbcfg_data_t usbcfg;
7202 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7203 return usbcfg.b.hnpcap;
7206 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
7208 gusbcfg_data_t usbcfg;
7209 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7210 usbcfg.b.hnpcap = val;
7211 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
7214 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
7216 gusbcfg_data_t usbcfg;
7217 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7218 return usbcfg.b.srpcap;
7221 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
7223 gusbcfg_data_t usbcfg;
7224 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7225 usbcfg.b.srpcap = val;
7226 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
7229 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
7232 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
7233 return dcfg.b.devspd;
7236 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
7239 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
7240 dcfg.b.devspd = val;
7241 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
7244 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
7247 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
7248 return hprt0.b.prtconnsts;
7251 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
7254 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
7255 return dsts.b.enumspd;
7258 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
7261 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
7262 return hprt0.b.prtpwr;
7266 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
7268 return core_if->hibernation_suspend;
7271 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
7274 hprt0.d32 = dwc_otg_read_hprt0(core_if);
7275 hprt0.b.prtpwr = val;
7276 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
7279 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
7282 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
7283 return hprt0.b.prtsusp;
7287 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
7290 hprt0.d32 = dwc_otg_read_hprt0(core_if);
7291 hprt0.b.prtsusp = val;
7292 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
7295 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
7298 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
7299 return hfir.b.frint;
7303 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
7307 fram_int = calc_frame_interval(core_if);
7308 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
7309 if (!core_if->core_params->reload_ctl) {
7310 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
7311 "not set to 1.\nShould load driver with reload_ctl=1"
7312 " module parameter\n");
7317 if ((val < 3350) || (val > 4150)) {
7318 DWC_WARN("HFIR interval for HS core and 30 MHz"
7319 "clock freq should be from 3350 to 4150\n");
7324 if ((val < 26820) || (val > 33180)) {
7325 DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
7326 "clock freq should be from 26820 to 33180\n");
7331 if ((val < 5360) || (val > 6640)) {
7332 DWC_WARN("HFIR interval for HS core and 48 MHz"
7333 "clock freq should be from 5360 to 6640\n");
7338 if ((val < 42912) || (val > 53088)) {
7339 DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
7340 "clock freq should be from 42912 to 53088\n");
7345 if ((val < 6700) || (val > 8300)) {
7346 DWC_WARN("HFIR interval for HS core and 60 MHz"
7347 "clock freq should be from 6700 to 8300\n");
7352 if ((val < 53640) || (val > 65536)) {
7353 DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
7354 "clock freq should be from 53640 to 65536\n");
7359 DWC_WARN("Unknown frame interval\n");
7365 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
7368 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
7371 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7372 return hcfg.b.modechtimen;
7376 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
7379 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7380 hcfg.b.modechtimen = val;
7381 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
7384 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
7387 hprt0.d32 = dwc_otg_read_hprt0(core_if);
7388 hprt0.b.prtres = val;
7389 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
7392 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
7395 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7396 return dctl.b.rmtwkupsig;
7399 uint32_t dwc_otg_get_beslreject(dwc_otg_core_if_t * core_if)
7402 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7403 return dctl.b.besl_reject;
7406 void dwc_otg_set_beslreject(dwc_otg_core_if_t * core_if, uint32_t val)
7409 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7410 dctl.b.besl_reject = val;
7411 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
7413 uint32_t dwc_otg_get_hirdthresh(dwc_otg_core_if_t * core_if)
7415 glpmcfg_data_t lpmcfg;
7416 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7417 return lpmcfg.b.hird_thres;
7420 void dwc_otg_set_hirdthresh(dwc_otg_core_if_t * core_if, uint32_t val)
7422 glpmcfg_data_t lpmcfg;
7424 if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
7425 DWC_WARN("Wrong valaue for hird_thres\n");
7426 DWC_WARN("hird_thres must be 0-f\n");
7430 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7431 lpmcfg.b.hird_thres |= val;
7432 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7435 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
7437 glpmcfg_data_t lpmcfg;
7438 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7441 ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
7442 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
7443 core_if->lx_state, lpmcfg.b.prt_sleep_sts);
7445 return lpmcfg.b.prt_sleep_sts;
7448 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
7450 glpmcfg_data_t lpmcfg;
7451 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7452 return lpmcfg.b.rem_wkup_en;
7455 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
7457 glpmcfg_data_t lpmcfg;
7458 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7459 return lpmcfg.b.appl_resp;
7462 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
7464 glpmcfg_data_t lpmcfg;
7465 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7466 lpmcfg.b.appl_resp = val;
7467 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7470 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
7472 glpmcfg_data_t lpmcfg;
7473 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7474 return lpmcfg.b.hsic_connect;
7477 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
7479 glpmcfg_data_t lpmcfg;
7480 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7481 lpmcfg.b.hsic_connect = val;
7482 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7485 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
7487 glpmcfg_data_t lpmcfg;
7488 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7489 return lpmcfg.b.inv_sel_hsic;
7493 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
7495 glpmcfg_data_t lpmcfg;
7496 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7497 lpmcfg.b.inv_sel_hsic = val;
7498 DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7501 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
7503 return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7506 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
7508 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
7511 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
7513 return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7516 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
7518 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
7521 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
7523 return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
7526 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7528 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
7531 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
7533 return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
7536 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7538 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
7541 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
7543 return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
7546 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
7548 DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
7551 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
7553 return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
7556 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
7558 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
7561 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
7563 return DWC_READ_REG32(core_if->host_if->hprt0);
7567 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
7569 DWC_WRITE_REG32(core_if->host_if->hprt0, val);
7572 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
7574 return DWC_READ_REG32(&core_if->core_global_regs->guid);
7577 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
7579 DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
7582 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
7584 return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
7587 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
7589 return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7593 * Start the SRP timer to detect when the SRP does not complete within
7596 * @param core_if the pointer to core_if strucure.
7598 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
7600 core_if->srp_timer_started = 1;
7601 DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
7604 void dwc_otg_initiate_srp(void * p)
7606 dwc_otg_core_if_t * core_if = p;
7607 uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
7611 val.d32 = DWC_READ_REG32(addr);
7613 DWC_ERROR("Session Request Already active!\n");
7617 DWC_INFO("Session Request Initated\n"); //NOTICE
7618 mem.d32 = DWC_READ_REG32(addr);
7620 DWC_WRITE_REG32(addr, mem.d32);
7622 /* Start the SRP timer */
7623 dwc_otg_pcd_start_srp_timer(core_if);
7627 int dwc_otg_check_haps_status(dwc_otg_core_if_t * core_if)
7631 if(DWC_READ_REG32(&core_if->core_global_regs->gsnpsid) == 0xffffffff)