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
59 #define VERBOSE //sword
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
64 static int in_calibration = 0;
65 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
67 void usb_in_cal(int flag)
76 * This function is called to initialize the DWC_otg CSR data
77 * structures. The register addresses in the device and host
78 * structures are initialized from the base address supplied by the
79 * caller. The calling function must make the OS calls to get the
80 * base address of the DWC_otg controller registers. The core_params
81 * argument holds the parameters that specify how the core should be
84 * @param[in] reg_base_addr Base address of DWC_otg core registers
87 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
89 dwc_otg_core_if_t *core_if = 0;
90 dwc_otg_dev_if_t *dev_if = 0;
91 dwc_otg_host_if_t *host_if = 0;
92 uint8_t *reg_base = (uint8_t *) reg_base_addr;
95 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
97 core_if = dwc_alloc(sizeof(dwc_otg_core_if_t));
101 "Allocation of dwc_otg_core_if_t failed\n");
104 core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
107 * Allocate the Device Mode structures.
109 dev_if = dwc_alloc(sizeof(dwc_otg_dev_if_t));
112 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
117 dev_if->dev_global_regs =
118 (dwc_otg_device_global_regs_t *) (reg_base +
119 DWC_DEV_GLOBAL_REG_OFFSET);
121 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
122 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
123 (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
124 (i * DWC_EP_REG_OFFSET));
126 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
127 (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
128 (i * DWC_EP_REG_OFFSET));
129 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
130 i, &dev_if->in_ep_regs[i]->diepctl);
131 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
132 i, &dev_if->out_ep_regs[i]->doepctl);
135 dev_if->speed = 0; // unknown
137 core_if->dev_if = dev_if;
140 * Allocate the Host Mode structures.
142 host_if = dwc_alloc(sizeof(dwc_otg_host_if_t));
146 "Allocation of dwc_otg_host_if_t failed\n");
152 host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
153 (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
156 (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
158 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
159 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
160 (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
161 (i * DWC_OTG_CHAN_REGS_OFFSET));
162 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
163 i, &host_if->hc_regs[i]->hcchar);
166 host_if->num_host_channels = MAX_EPS_CHANNELS;
167 core_if->host_if = host_if;
169 for (i = 0; i < MAX_EPS_CHANNELS; i++) {
170 core_if->data_fifo[i] =
171 (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
172 (i * DWC_OTG_DATA_FIFO_SIZE));
173 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
174 i, (unsigned)core_if->data_fifo[i]);
177 core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
179 /* Initiate lx_state to L3 disconnected state */
180 core_if->lx_state = DWC_OTG_L3;
182 * Store the contents of the hardware configuration registers here for
185 core_if->hwcfg1.d32 =
186 dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
187 core_if->hwcfg2.d32 =
188 dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
189 core_if->hwcfg3.d32 =
190 dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
191 core_if->hwcfg4.d32 =
192 dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
194 DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
195 DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
196 DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
197 DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
200 dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
202 dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
204 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
205 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
207 DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
208 DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
209 DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
210 DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
211 core_if->hwcfg2.b.num_host_chan);
212 DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
213 core_if->hwcfg2.b.nonperio_tx_q_depth);
214 DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
215 core_if->hwcfg2.b.host_perio_tx_q_depth);
216 DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
217 core_if->hwcfg2.b.dev_token_q_depth);
219 DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
220 core_if->hwcfg3.b.dfifo_depth);
221 DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
222 core_if->hwcfg3.b.xfer_size_cntr_width);
225 * Set the SRP sucess bit for FS-I2c
227 core_if->srp_success = 0;
228 core_if->srp_timer_started = 0;
232 * Create new workqueue and init works
234 core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
235 if (core_if->wq_otg == 0) {
236 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
243 core_if->snpsid = dwc_read_reg32(&core_if->core_global_regs->gsnpsid);
245 DWC_DEBUGPL(DBG_CIL,"Core Release: %x.%x%x%x\n",
246 (core_if->snpsid >> 12 & 0xF),
247 (core_if->snpsid >> 8 & 0xF),
248 (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
251 core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
252 w_wakeup_detected, core_if);
253 if (core_if->wkp_timer == 0) {
254 DWC_WARN("DWC_TIMER_ALLOC failed\n");
257 DWC_WORKQ_FREE(core_if->wq_otg);
262 if (dwc_otg_setup_params(core_if)) {
263 DWC_WARN("Error while setting core params\n");
270 * This function frees the structures allocated by dwc_otg_cil_init().
272 * @param[in] core_if The core interface pointer returned from
273 * dwc_otg_cil_init().
276 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
278 /* Disable all interrupts */
279 dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
280 dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
283 if (core_if->wq_otg) {
284 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
285 DWC_WORKQ_FREE(core_if->wq_otg);
288 if (core_if->dev_if) {
289 dwc_free(core_if->dev_if);
291 if (core_if->host_if) {
292 dwc_free(core_if->host_if);
294 DWC_TIMER_FREE(core_if->wkp_timer);
295 DWC_FREE(core_if->core_params);
300 * This function enables the controller's Global Interrupt in the AHB Config
303 * @param[in] core_if Programming view of DWC_otg controller.
305 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
307 gahbcfg_data_t ahbcfg = {.d32 = 0 };
308 ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
309 dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
313 * This function disables the controller's Global Interrupt in the AHB Config
316 * @param[in] core_if Programming view of DWC_otg controller.
318 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
320 gahbcfg_data_t ahbcfg = {.d32 = 0 };
321 ahbcfg.b.glblintrmsk = 1; /* Enable interrupts */
322 dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
326 * This function initializes the commmon interrupts, used in both
327 * device and host modes.
329 * @param[in] core_if Programming view of the DWC_otg controller
332 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
334 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
335 gintmsk_data_t intr_mask = {.d32 = 0 };
337 /* Clear any pending OTG Interrupts */
338 dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
340 /* Clear any pending interrupts */
341 dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
344 * Enable the interrupts in the GINTMSK.
346 intr_mask.b.modemismatch = 1;
347 intr_mask.b.otgintr = 1;
349 if (!core_if->dma_enable) {
350 intr_mask.b.rxstsqlvl = 1;
353 intr_mask.b.conidstschng = 1;
354 intr_mask.b.wkupintr = 1;
355 intr_mask.b.disconnect = 1;
356 intr_mask.b.usbsuspend = 1;
357 intr_mask.b.sessreqintr = 1;
358 #ifdef CONFIG_USB_DWC_OTG_LPM
359 if (core_if->core_params->lpm_enable) {
360 intr_mask.b.lpmtranrcvd = 1;
363 dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
367 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
370 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
375 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
376 (core_if->hwcfg2.b.fs_phy_type == 1) &&
377 (core_if->core_params->ulpi_fs_ls)) ||
378 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
380 val = DWC_HCFG_48_MHZ;
382 /* High speed PHY running at full speed or high speed */
383 val = DWC_HCFG_30_60_MHZ;
386 DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
387 hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
388 hcfg.b.fslspclksel = val;
389 dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
393 * Initializes the DevSpd field of the DCFG register depending on the PHY type
394 * and the enumeration speed of the device.
396 static void init_devspd(dwc_otg_core_if_t * core_if)
401 if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
402 (core_if->hwcfg2.b.fs_phy_type == 1) &&
403 (core_if->core_params->ulpi_fs_ls)) ||
404 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
407 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
408 /* High speed PHY running at full speed */
411 /* High speed PHY running at high speed */
415 if(in_calibration) //force full speed in calibration
418 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
420 dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
422 dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
426 * This function calculates the number of IN EPS
427 * using GHWCFG1 and GHWCFG2 registers values
429 * @param core_if Programming view of the DWC_otg controller
431 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
433 uint32_t num_in_eps = 0;
434 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
435 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
436 uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
439 for (i = 0; i < num_eps; ++i) {
447 * the dedicate fifo maybe less than number of IN eps, but our
448 * composite usb function normally won't use all dedicated fifo,
449 * so, just let allocate more the IN eps. Sword,
452 if (core_if->hwcfg4.b.ded_fifo_en) {
454 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
462 * This function calculates the number of OUT EPS
463 * using GHWCFG1 and GHWCFG2 registers values
465 * @param core_if Programming view of the DWC_otg controller
467 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
469 uint32_t num_out_eps = 0;
470 uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
471 uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
474 for (i = 0; i < num_eps; ++i) {
484 * This function initializes the DWC_otg controller registers and
485 * prepares the core for device mode or host mode operation.
487 * @param core_if Programming view of the DWC_otg controller
490 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
493 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
494 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
495 gahbcfg_data_t ahbcfg = {.d32 = 0 };
496 gusbcfg_data_t usbcfg = {.d32 = 0 };
497 gi2cctl_data_t i2cctl = {.d32 = 0 };
499 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
501 /* Common Initialization */
503 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
505 /* Program the ULPI External VBUS bit if needed */
506 usbcfg.b.ulpi_ext_vbus_drv =
507 (core_if->core_params->phy_ulpi_ext_vbus ==
508 DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
510 /* Set external TS Dline pulsing */
511 usbcfg.b.term_sel_dl_pulse =
512 (core_if->core_params->ts_dline == 1) ? 1 : 0;
513 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
515 /* Reset the Controller */
516 dwc_otg_core_reset(core_if);
518 /* Initialize parameters from Hardware configuration registers. */
519 dev_if->num_in_eps = calc_num_in_eps(core_if);
520 dev_if->num_out_eps = calc_num_out_eps(core_if);
522 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
523 core_if->hwcfg4.b.num_dev_perio_in_ep);
525 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
526 dev_if->perio_tx_fifo_size[i] =
527 dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
528 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
529 i, dev_if->perio_tx_fifo_size[i]);
532 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
533 dev_if->tx_fifo_size[i] =
534 dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
535 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
536 i, dev_if->perio_tx_fifo_size[i]);
539 core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
540 core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
541 core_if->nperio_tx_fifo_size =
542 dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
544 DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
545 DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
546 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
547 core_if->nperio_tx_fifo_size);
549 /* This programming sequence needs to happen in FS mode before any other
550 * programming occurs */
551 if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
552 (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
553 /* If FS mode with FS PHY */
555 /* core_init() is now called on every switch so only call the
556 * following for the first time through. */
557 //if (!core_if->phy_init_done) {
558 // core_if->phy_init_done = 1;
559 DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
560 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
562 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
564 /* Reset after a PHY select */
565 dwc_otg_core_reset(core_if);
568 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
569 * do this on HNP Dev/Host mode switches (done in dev_init and
571 if (dwc_otg_is_host_mode(core_if)) {
572 init_fslspclksel(core_if);
574 init_devspd(core_if);
577 if (core_if->core_params->i2c_enable) {
578 DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
579 /* Program GUSBCFG.OtgUtmifsSel to I2C */
580 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
581 usbcfg.b.otgutmifssel = 1;
582 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
584 /* Program GI2CCTL.I2CEn */
585 i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
586 i2cctl.b.i2cdevaddr = 1;
588 dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
590 dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
593 } /* endif speed == DWC_SPEED_PARAM_FULL */
596 /* High speed PHY. */
597 /* re set phy anyway sword*/
598 //if (!core_if->phy_init_done) {
599 //core_if->phy_init_done = 1;
600 /* HS PHY parameters. These parameters are preserved
601 * during soft reset so only program the first time. Do
602 * a soft reset immediately after setting phyif. */
603 usbcfg.b.ulpi_utmi_sel = core_if->core_params->phy_type;
604 /* UTMI+ interface */
605 if (core_if->core_params->phy_utmi_width == 16) {
611 usbcfg.b.ulpi_utmi_sel = 0;
613 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
614 /* Reset after setting the PHY parameters */
615 dwc_otg_core_reset(core_if);
619 if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
620 (core_if->hwcfg2.b.fs_phy_type == 1) &&
621 (core_if->core_params->ulpi_fs_ls)) {
622 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
623 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
624 usbcfg.b.ulpi_fsls = 1;
625 usbcfg.b.ulpi_clk_sus_m = 1;
626 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
628 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
629 usbcfg.b.ulpi_fsls = 0;
630 usbcfg.b.ulpi_clk_sus_m = 0;
631 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
634 /* Program the GAHBCFG Register. */
635 switch (core_if->hwcfg2.b.architecture) {
637 case DWC_SLAVE_ONLY_ARCH:
638 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
639 ahbcfg.b.nptxfemplvl_txfemplvl =
640 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
641 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
642 core_if->dma_enable = 0;
643 core_if->dma_desc_enable = 0;
646 case DWC_EXT_DMA_ARCH:
647 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
649 uint8_t brst_sz = core_if->core_params->dma_burst_size;
650 ahbcfg.b.hburstlen = 0;
651 while (brst_sz > 1) {
652 ahbcfg.b.hburstlen++;
656 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
657 core_if->dma_desc_enable =
658 (core_if->core_params->dma_desc_enable != 0);
661 case DWC_INT_DMA_ARCH:
662 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
663 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
664 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
665 core_if->dma_desc_enable =
666 (core_if->core_params->dma_desc_enable != 0);
670 if (core_if->dma_enable) {
671 if (core_if->dma_desc_enable) {
672 DWC_DEBUGPL(DBG_CIL,"Using Descriptor DMA mode\n");
674 DWC_DEBUGPL(DBG_CIL,"Using Buffer DMA mode\n");
678 DWC_DEBUGPL(DBG_CIL,"Using Slave mode\n");
680 ahbcfg.b.dmaenable = core_if->dma_enable;
681 dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
683 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
685 core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
686 core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
687 DWC_DEBUGPL(DBG_CIL,"Periodic Transfer Interrupt Enhancement - %s\n",
688 ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
689 DWC_DEBUGPL(DBG_CIL,"Multiprocessor Interrupt Enhancement - %s\n",
690 ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
693 * Program the GUSBCFG register.
695 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
697 switch (core_if->hwcfg2.b.op_mode) {
698 case DWC_MODE_HNP_SRP_CAPABLE:
699 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
700 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
701 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
702 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
705 case DWC_MODE_SRP_ONLY_CAPABLE:
707 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
708 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
711 case DWC_MODE_NO_HNP_SRP_CAPABLE:
716 case DWC_MODE_SRP_CAPABLE_DEVICE:
718 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
719 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
722 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
727 case DWC_MODE_SRP_CAPABLE_HOST:
729 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
730 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
733 case DWC_MODE_NO_SRP_CAPABLE_HOST:
739 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
741 #ifdef CONFIG_USB_DWC_OTG_LPM
742 if (core_if->core_params->lpm_enable) {
743 glpmcfg_data_t lpmcfg = {.d32 = 0 };
745 /* To enable LPM support set lpm_cap_en bit */
746 lpmcfg.b.lpm_cap_en = 1;
748 /* Make AppL1Res ACK */
749 lpmcfg.b.appl_resp = 1;
752 lpmcfg.b.retry_count = 3;
754 dwc_modify_reg32(&core_if->core_global_regs->glpmcfg,
759 if (core_if->core_params->ic_usb_cap) {
760 gusbcfg_data_t gusbcfg = {.d32 = 0 };
761 gusbcfg.b.ic_usb_cap = 1;
762 dwc_modify_reg32(&core_if->core_global_regs->gusbcfg,
766 /* Enable common interrupts */
767 dwc_otg_enable_common_interrupts(core_if);
769 /* Do device or host intialization based on mode during PCD
770 * and HCD initialization */
771 if (dwc_otg_is_host_mode(core_if)) {
772 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
773 core_if->op_state = A_HOST;
775 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
776 core_if->op_state = B_PERIPHERAL;
777 #ifdef DWC_DEVICE_ONLY
778 dwc_otg_core_dev_init(core_if);
784 * This function enables the Device mode interrupts.
786 * @param core_if Programming view of DWC_otg controller
788 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
790 gintmsk_data_t intr_mask = {.d32 = 0 };
791 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
793 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
795 /* Disable all interrupts. */
796 dwc_write_reg32(&global_regs->gintmsk, 0);
798 /* Clear any pending interrupts */
799 dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
801 /* Enable the common interrupts */
802 dwc_otg_enable_common_interrupts(core_if);
804 /* Enable interrupts */
805 intr_mask.b.usbreset = 1;
806 intr_mask.b.enumdone = 1;
808 if (!core_if->multiproc_int_enable) {
809 intr_mask.b.inepintr = 1;
810 intr_mask.b.outepintr = 1;
813 intr_mask.b.erlysuspend = 1;
815 if (core_if->en_multiple_tx_fifo == 0) {
816 intr_mask.b.epmismatch = 1;
819 if (core_if->dma_enable) {
820 if (core_if->dma_desc_enable == 0) {
821 if (core_if->pti_enh_enable) {
822 dctl_data_t dctl = {.d32 = 0 };
824 dwc_modify_reg32(&core_if->dev_if->
825 dev_global_regs->dctl, 0,
828 intr_mask.b.incomplisoin = 1;
829 intr_mask.b.incomplisoout = 1;
833 intr_mask.b.incomplisoin = 1;
834 intr_mask.b.incomplisoout = 1;
836 #endif /* DWC_EN_ISOC */
838 /** @todo NGS: Should this be a module parameter? */
839 #ifdef USE_PERIODIC_EP
840 intr_mask.b.isooutdrop = 1;
841 intr_mask.b.eopframe = 1;
842 intr_mask.b.incomplisoin = 1;
843 intr_mask.b.incomplisoout = 1;
846 dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
848 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
849 dwc_read_reg32(&global_regs->gintmsk));
853 * This function initializes the DWC_otg controller registers for
856 * @param core_if Programming view of DWC_otg controller
859 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
862 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
863 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
864 dwc_otg_core_params_t *params = core_if->core_params;
865 dcfg_data_t dcfg = {.d32 = 0 };
866 dctl_data_t dctl = {.d32 = 0 };
867 grstctl_t resetctl = {.d32 = 0 };
868 uint32_t rx_fifo_size;
869 fifosize_data_t nptxfifosize;
870 fifosize_data_t txfifosize;
871 dthrctl_data_t dthrctl;
872 fifosize_data_t ptxfifosize;
874 /* Restart the Phy Clock */
875 dwc_write_reg32(core_if->pcgcctl, 0);
876 #ifdef CONFIG_USB_CORE_IP_293A
877 dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
878 dctl.b.sftdiscon = 0;
879 dwc_write_reg32(&dev_if->dev_global_regs->dctl, dctl.d32);
881 /* Device configuration register */
882 init_devspd(core_if);
883 dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
884 dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
885 dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
886 dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
888 /* Configure data FIFO sizes */
889 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
890 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
891 core_if->total_fifo_size);
892 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
893 params->dev_rx_fifo_size);
894 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
895 params->dev_nperio_tx_fifo_size);
898 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
899 dwc_read_reg32(&global_regs->grxfsiz));
902 core_if->pwron_rxfsiz = dwc_read_reg32(&global_regs->grxfsiz);
903 core_if->init_rxfsiz = params->dev_rx_fifo_size;
905 rx_fifo_size = params->dev_rx_fifo_size;
906 dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
908 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
909 dwc_read_reg32(&global_regs->grxfsiz));
911 /** Set Periodic Tx FIFO Mask all bits 0 */
912 core_if->p_tx_msk = 0;
914 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
915 /**fisrt 3 txfifos are 0x40 in shark, tooo small, don't use them*/
918 /** Set Tx FIFO Mask all bits 0 */
922 if (core_if->en_multiple_tx_fifo == 0) {
923 /* Non-periodic Tx FIFO */
924 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
925 dwc_read_reg32(&global_regs->gnptxfsiz));
927 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
928 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
930 dwc_write_reg32(&global_regs->gnptxfsiz,
933 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
934 dwc_read_reg32(&global_regs->gnptxfsiz));
936 /**@todo NGS: Fix Periodic FIFO Sizing! */
938 * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
939 * Indexes of the FIFO size module parameters in the
940 * dev_perio_tx_fifo_size array and the FIFO size registers in
941 * the dptxfsiz array run from 0 to 14.
943 /** @todo Finish debug of this */
944 ptxfifosize.b.startaddr =
945 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
946 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep;
948 ptxfifosize.b.depth =
949 params->dev_perio_tx_fifo_size[i];
951 "initial dptxfsiz_dieptxf[%d]=%08x\n",
953 dwc_read_reg32(&global_regs->
956 dwc_write_reg32(&global_regs->
960 "new dptxfsiz_dieptxf[%d]=%08x\n",
962 dwc_read_reg32(&global_regs->
965 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
969 * Tx FIFOs These FIFOs are numbered from 1 to 15.
970 * Indexes of the FIFO size module parameters in the
971 * dev_tx_fifo_size array and the FIFO size registers in
972 * the dptxfsiz_dieptxf array run from 0 to 14.
975 /* Non-periodic Tx FIFO */
976 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
977 dwc_read_reg32(&global_regs->gnptxfsiz));
980 core_if->pwron_gnptxfsiz =
981 (dwc_read_reg32(&global_regs->gnptxfsiz) >> 16);
982 core_if->init_gnptxfsiz =
983 params->dev_nperio_tx_fifo_size;
985 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
986 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
988 dwc_write_reg32(&global_regs->gnptxfsiz,
991 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
992 dwc_read_reg32(&global_regs->gnptxfsiz));
994 txfifosize.b.startaddr =
995 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
997 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1000 params->dev_tx_fifo_size[i];
1002 DWC_DEBUGPL(DBG_CIL,
1003 "initial dptxfsiz_dieptxf[%d]=%08x\n",
1005 dwc_read_reg32(&global_regs->
1010 core_if->pwron_txfsiz[i] =
1012 (&global_regs->dptxfsiz_dieptxf[i]) >> 16);
1013 core_if->init_txfsiz[i] =
1014 params->dev_tx_fifo_size[i];
1016 dwc_write_reg32(&global_regs->
1017 dptxfsiz_dieptxf[i],
1020 DWC_DEBUGPL(DBG_CIL,
1021 "new dptxfsiz_dieptxf[%d]=%08x\n",
1023 dwc_read_reg32(&global_regs->
1027 txfifosize.b.startaddr += txfifosize.b.depth;
1031 /* Flush the FIFOs */
1032 dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
1033 dwc_otg_flush_rx_fifo(core_if);
1035 /* Flush the Learning Queue. */
1036 resetctl.b.intknqflsh = 1;
1037 dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
1039 /* Clear all pending Device Interrupts */
1040 /** @todo - if the condition needed to be checked
1041 * or in any case all pending interrutps should be cleared?
1043 if (core_if->multiproc_int_enable) {
1044 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
1045 dwc_write_reg32(&dev_if->dev_global_regs->
1046 diepeachintmsk[i], 0);
1049 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1050 dwc_write_reg32(&dev_if->dev_global_regs->
1051 doepeachintmsk[i], 0);
1054 dwc_write_reg32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1055 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, 0);
1057 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
1058 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
1059 dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1060 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
1063 for (i = 0; i <= dev_if->num_in_eps; i++) {
1064 depctl_data_t depctl;
1065 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
1066 if (depctl.b.epena) {
1074 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1076 dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1077 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
1078 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1081 for (i = 0; i <= dev_if->num_out_eps; i++) {
1082 depctl_data_t depctl;
1083 depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
1084 if (depctl.b.epena) {
1092 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1094 dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
1095 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
1096 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
1099 if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1100 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
1101 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
1102 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
1104 dev_if->rx_thr_length = params->rx_thr_length;
1105 dev_if->tx_thr_length = params->tx_thr_length;
1107 dev_if->setup_desc_index = 0;
1110 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1111 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1112 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1113 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1114 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1115 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
1117 dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1120 DWC_DEBUGPL(DBG_CIL,
1121 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1122 dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1123 dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1124 dthrctl.b.rx_thr_len);
1128 dwc_otg_enable_device_interrupts(core_if);
1131 diepmsk_data_t msk = {.d32 = 0 };
1132 msk.b.txfifoundrn = 1;
1133 if (core_if->multiproc_int_enable) {
1134 dwc_modify_reg32(&dev_if->dev_global_regs->
1135 diepeachintmsk[0], msk.d32, msk.d32);
1137 dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk,
1142 if (core_if->multiproc_int_enable) {
1143 /* Set NAK on Babble */
1144 dctl_data_t dctl = {.d32 = 0 };
1145 dctl.b.nakonbble = 1;
1146 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1151 * This function enables the Host mode interrupts.
1153 * @param core_if Programming view of DWC_otg controller
1155 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
1157 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1158 gintmsk_data_t intr_mask = {.d32 = 0 };
1160 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1162 /* Disable all interrupts. */
1163 dwc_write_reg32(&global_regs->gintmsk, 0);
1165 /* Clear any pending interrupts. */
1166 dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
1168 /* Enable the common interrupts */
1169 dwc_otg_enable_common_interrupts(core_if);
1172 * Enable host mode interrupts without disturbing common
1175 intr_mask.b.sofintr = 1;
1176 intr_mask.b.portintr = 1;
1177 intr_mask.b.hcintr = 1;
1179 dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1183 * This function disables the Host Mode interrupts.
1185 * @param core_if Programming view of DWC_otg controller
1187 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
1189 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1190 gintmsk_data_t intr_mask = {.d32 = 0 };
1192 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
1195 * Disable host mode interrupts without disturbing common
1198 intr_mask.b.sofintr = 1;
1199 intr_mask.b.portintr = 1;
1200 intr_mask.b.hcintr = 1;
1201 intr_mask.b.ptxfempty = 1;
1202 intr_mask.b.nptxfempty = 1;
1204 dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
1208 * This function initializes the DWC_otg controller registers for
1211 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
1212 * request queues. Host channels are reset to ensure that they are ready for
1213 * performing transfers.
1215 * @param core_if Programming view of DWC_otg controller
1218 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
1220 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1221 dwc_otg_host_if_t *host_if = core_if->host_if;
1222 dwc_otg_core_params_t *params = core_if->core_params;
1223 hprt0_data_t hprt0 = {.d32 = 0 };
1224 fifosize_data_t nptxfifosize;
1225 fifosize_data_t ptxfifosize;
1227 hcchar_data_t hcchar;
1229 dwc_otg_hc_regs_t *hc_regs;
1231 gotgctl_data_t gotgctl = {.d32 = 0 };
1233 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
1235 /* Restart the Phy Clock */
1236 dwc_write_reg32(core_if->pcgcctl, 0);
1238 /* Initialize Host Configuration Register */
1239 init_fslspclksel(core_if);
1240 if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1241 hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
1242 hcfg.b.fslssupp = 1;
1243 dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
1246 /* Configure data FIFO sizes */
1247 if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1248 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
1249 core_if->total_fifo_size);
1250 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
1251 params->host_rx_fifo_size);
1252 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
1253 params->host_nperio_tx_fifo_size);
1254 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
1255 params->host_perio_tx_fifo_size);
1258 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1259 dwc_read_reg32(&global_regs->grxfsiz));
1260 dwc_write_reg32(&global_regs->grxfsiz,
1261 params->host_rx_fifo_size);
1262 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1263 dwc_read_reg32(&global_regs->grxfsiz));
1265 /* Non-periodic Tx FIFO */
1266 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1267 dwc_read_reg32(&global_regs->gnptxfsiz));
1268 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
1269 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
1270 dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
1271 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1272 dwc_read_reg32(&global_regs->gnptxfsiz));
1274 /* Periodic Tx FIFO */
1275 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
1276 dwc_read_reg32(&global_regs->hptxfsiz));
1277 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
1278 ptxfifosize.b.startaddr =
1279 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1280 dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
1281 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
1282 dwc_read_reg32(&global_regs->hptxfsiz));
1285 /* Clear Host Set HNP Enable in the OTG Control Register */
1286 gotgctl.b.hstsethnpen = 1;
1287 dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
1289 /* Make sure the FIFOs are flushed. */
1290 dwc_otg_flush_tx_fifo(core_if, 0x10 /* all Tx FIFOs */ );
1291 dwc_otg_flush_rx_fifo(core_if);
1293 /* Flush out any leftover queued requests. */
1294 num_channels = core_if->core_params->host_channels;
1295 for (i = 0; i < num_channels; i++) {
1296 hc_regs = core_if->host_if->hc_regs[i];
1297 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1301 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1304 /* Halt all channels to put them into a known state. */
1305 for (i = 0; i < num_channels; i++) {
1307 hc_regs = core_if->host_if->hc_regs[i];
1308 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1312 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1313 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
1315 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1316 if (++count > 1000) {
1318 ("%s: Unable to clear halt on channel %d\n",
1323 } while (hcchar.b.chen);
1326 /* Turn on the vbus power. */
1327 DWC_DEBUGPL(DBG_CIL,"Init: Port Power? op_state=%d\n", core_if->op_state);
1328 if (core_if->op_state == A_HOST) {
1329 hprt0.d32 = dwc_otg_read_hprt0(core_if);
1330 DWC_DEBUGPL(DBG_CIL,"Init: Power Port (%d)\n", hprt0.b.prtpwr);
1331 if (hprt0.b.prtpwr == 0) {
1333 dwc_write_reg32(host_if->hprt0, hprt0.d32);
1337 dwc_otg_enable_host_interrupts(core_if);
1341 * Prepares a host channel for transferring packets to/from a specific
1342 * endpoint. The HCCHARn register is set up with the characteristics specified
1343 * in _hc. Host channel interrupts that may need to be serviced while this
1344 * transfer is in progress are enabled.
1346 * @param core_if Programming view of DWC_otg controller
1347 * @param hc Information needed to initialize the host channel
1349 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1351 uint32_t intr_enable;
1352 hcintmsk_data_t hc_intr_mask;
1353 gintmsk_data_t gintmsk = {.d32 = 0 };
1354 hcchar_data_t hcchar;
1355 hcsplt_data_t hcsplt;
1357 uint8_t hc_num = hc->hc_num;
1358 dwc_otg_host_if_t *host_if = core_if->host_if;
1359 dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
1361 /* Clear old interrupt conditions for this host channel. */
1362 hc_intr_mask.d32 = 0xFFFFFFFF;
1363 hc_intr_mask.b.reserved = 0;
1364 dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
1366 /* Enable channel interrupts required for this transfer. */
1367 hc_intr_mask.d32 = 0;
1368 hc_intr_mask.b.chhltd = 1;
1369 if (core_if->dma_enable) {
1370 hc_intr_mask.b.ahberr = 1;
1371 if (hc->error_state && !hc->do_split &&
1372 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
1373 hc_intr_mask.b.ack = 1;
1375 hc_intr_mask.b.datatglerr = 1;
1376 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
1377 hc_intr_mask.b.nak = 1;
1382 switch (hc->ep_type) {
1383 case DWC_OTG_EP_TYPE_CONTROL:
1384 case DWC_OTG_EP_TYPE_BULK:
1385 hc_intr_mask.b.xfercompl = 1;
1386 hc_intr_mask.b.stall = 1;
1387 hc_intr_mask.b.xacterr = 1;
1388 hc_intr_mask.b.datatglerr = 1;
1390 hc_intr_mask.b.bblerr = 1;
1392 hc_intr_mask.b.nak = 1;
1393 hc_intr_mask.b.nyet = 1;
1395 hc_intr_mask.b.ack = 1;
1400 hc_intr_mask.b.nak = 1;
1401 if (hc->complete_split) {
1402 hc_intr_mask.b.nyet = 1;
1404 hc_intr_mask.b.ack = 1;
1408 if (hc->error_state) {
1409 hc_intr_mask.b.ack = 1;
1412 case DWC_OTG_EP_TYPE_INTR:
1413 hc_intr_mask.b.xfercompl = 1;
1414 hc_intr_mask.b.nak = 1;
1415 hc_intr_mask.b.stall = 1;
1416 hc_intr_mask.b.xacterr = 1;
1417 hc_intr_mask.b.datatglerr = 1;
1418 hc_intr_mask.b.frmovrun = 1;
1421 hc_intr_mask.b.bblerr = 1;
1423 if (hc->error_state) {
1424 hc_intr_mask.b.ack = 1;
1427 if (hc->complete_split) {
1428 hc_intr_mask.b.nyet = 1;
1430 hc_intr_mask.b.ack = 1;
1434 case DWC_OTG_EP_TYPE_ISOC:
1435 hc_intr_mask.b.xfercompl = 1;
1436 hc_intr_mask.b.frmovrun = 1;
1437 hc_intr_mask.b.ack = 1;
1440 hc_intr_mask.b.xacterr = 1;
1441 hc_intr_mask.b.bblerr = 1;
1446 dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
1448 /* Enable the top level host channel interrupt. */
1449 intr_enable = (1 << hc_num);
1450 dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
1452 /* Make sure host channel interrupts are enabled. */
1453 gintmsk.b.hcintr = 1;
1454 dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
1457 * Program the HCCHARn register with the endpoint characteristics for
1458 * the current transfer.
1461 hcchar.b.devaddr = hc->dev_addr;
1462 hcchar.b.epnum = hc->ep_num;
1463 hcchar.b.epdir = hc->ep_is_in;
1464 hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
1465 hcchar.b.eptype = hc->ep_type;
1466 hcchar.b.mps = hc->max_packet;
1468 dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
1470 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1471 DWC_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n", hcchar.b.devaddr);
1472 DWC_DEBUGPL(DBG_HCDV, " Ep Num: %d\n", hcchar.b.epnum);
1473 DWC_DEBUGPL(DBG_HCDV, " Is In: %d\n", hcchar.b.epdir);
1474 DWC_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
1475 DWC_DEBUGPL(DBG_HCDV, " Ep Type: %d\n", hcchar.b.eptype);
1476 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
1477 DWC_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n", hcchar.b.multicnt);
1480 * Program the HCSPLIT register for SPLITs
1484 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
1486 hc->complete_split ? "CSPLIT" : "SSPLIT");
1487 hcsplt.b.compsplt = hc->complete_split;
1488 hcsplt.b.xactpos = hc->xact_pos;
1489 hcsplt.b.hubaddr = hc->hub_addr;
1490 hcsplt.b.prtaddr = hc->port_addr;
1491 DWC_DEBUGPL(DBG_HCDV, " comp split %d\n", hc->complete_split);
1492 DWC_DEBUGPL(DBG_HCDV, " xact pos %d\n", hc->xact_pos);
1493 DWC_DEBUGPL(DBG_HCDV, " hub addr %d\n", hc->hub_addr);
1494 DWC_DEBUGPL(DBG_HCDV, " port addr %d\n", hc->port_addr);
1495 DWC_DEBUGPL(DBG_HCDV, " is_in %d\n", hc->ep_is_in);
1496 DWC_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n", hcchar.b.mps);
1497 DWC_DEBUGPL(DBG_HCDV, " xferlen: %d\n", hc->xfer_len);
1499 dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
1504 * Attempts to halt a host channel. This function should only be called in
1505 * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
1506 * normal circumstances in DMA mode, the controller halts the channel when the
1507 * transfer is complete or a condition occurs that requires application
1510 * In slave mode, checks for a free request queue entry, then sets the Channel
1511 * Enable and Channel Disable bits of the Host Channel Characteristics
1512 * register of the specified channel to intiate the halt. If there is no free
1513 * request queue entry, sets only the Channel Disable bit of the HCCHARn
1514 * register to flush requests for this channel. In the latter case, sets a
1515 * flag to indicate that the host channel needs to be halted when a request
1516 * queue slot is open.
1518 * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
1519 * HCCHARn register. The controller ensures there is space in the request
1520 * queue before submitting the halt request.
1522 * Some time may elapse before the core flushes any posted requests for this
1523 * host channel and halts. The Channel Halted interrupt handler completes the
1524 * deactivation of the host channel.
1526 * @param core_if Controller register interface.
1527 * @param hc Host channel to halt.
1528 * @param halt_status Reason for halting the channel.
1530 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
1531 dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
1533 gnptxsts_data_t nptxsts;
1534 hptxsts_data_t hptxsts;
1535 hcchar_data_t hcchar;
1536 dwc_otg_hc_regs_t *hc_regs;
1537 dwc_otg_core_global_regs_t *global_regs;
1538 dwc_otg_host_global_regs_t *host_global_regs;
1540 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1541 global_regs = core_if->core_global_regs;
1542 host_global_regs = core_if->host_if->host_global_regs;
1544 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
1545 "halt_status = %d\n", halt_status);
1547 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
1548 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
1550 * Disable all channel interrupts except Ch Halted. The QTD
1551 * and QH state associated with this transfer has been cleared
1552 * (in the case of URB_DEQUEUE), so the channel needs to be
1553 * shut down carefully to prevent crashes.
1555 hcintmsk_data_t hcintmsk;
1557 hcintmsk.b.chhltd = 1;
1558 dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
1561 * Make sure no other interrupts besides halt are currently
1562 * pending. Handling another interrupt could cause a crash due
1563 * to the QTD and QH state.
1565 dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
1568 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
1569 * even if the channel was already halted for some other
1572 hc->halt_status = halt_status;
1574 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1575 if (hcchar.b.chen == 0) {
1577 * The channel is either already halted or it hasn't
1578 * started yet. In DMA mode, the transfer may halt if
1579 * it finishes normally or a condition occurs that
1580 * requires driver intervention. Don't want to halt
1581 * the channel again. In either Slave or DMA mode,
1582 * it's possible that the transfer has been assigned
1583 * to a channel, but not started yet when an URB is
1584 * dequeued. Don't want to halt a channel that hasn't
1591 if (hc->halt_pending) {
1593 * A halt has already been issued for this channel. This might
1594 * happen when a transfer is aborted by a higher level in
1598 DWC_DEBUGPL(DBG_CIL,"*** %s: Channel %d, _hc->halt_pending already set ***\n",
1599 __func__, hc->hc_num);
1601 /* dwc_otg_dump_global_registers(core_if); */
1602 /* dwc_otg_dump_host_registers(core_if); */
1607 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1611 if (!core_if->dma_enable) {
1612 /* Check for space in the request queue to issue the halt. */
1613 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
1614 hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
1615 nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
1616 if (nptxsts.b.nptxqspcavail == 0) {
1621 dwc_read_reg32(&host_global_regs->hptxsts);
1622 if ((hptxsts.b.ptxqspcavail == 0)
1623 || (core_if->queuing_high_bandwidth)) {
1629 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1631 hc->halt_status = halt_status;
1633 if (hcchar.b.chen) {
1634 hc->halt_pending = 1;
1635 hc->halt_on_queue = 0;
1637 hc->halt_on_queue = 1;
1640 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1641 DWC_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n", hcchar.d32);
1642 DWC_DEBUGPL(DBG_HCDV, " halt_pending: %d\n", hc->halt_pending);
1643 DWC_DEBUGPL(DBG_HCDV, " halt_on_queue: %d\n", hc->halt_on_queue);
1644 DWC_DEBUGPL(DBG_HCDV, " halt_status: %d\n", hc->halt_status);
1650 * Clears the transfer state for a host channel. This function is normally
1651 * called after a transfer is done and the host channel is being released.
1653 * @param core_if Programming view of DWC_otg controller.
1654 * @param hc Identifies the host channel to clean up.
1656 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1658 dwc_otg_hc_regs_t *hc_regs;
1660 hc->xfer_started = 0;
1663 * Clear channel interrupt enables and any unhandled channel interrupt
1666 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1667 dwc_write_reg32(&hc_regs->hcintmsk, 0);
1668 dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
1671 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
1673 hcchar_data_t hcchar;
1674 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1675 if (hcchar.b.chdis) {
1676 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1677 __func__, hc->hc_num, hcchar.d32);
1684 * Sets the channel property that indicates in which frame a periodic transfer
1685 * should occur. This is always set to the _next_ frame. This function has no
1686 * effect on non-periodic transfers.
1688 * @param core_if Programming view of DWC_otg controller.
1689 * @param hc Identifies the host channel to set up and its properties.
1690 * @param hcchar Current value of the HCCHAR register for the specified host
1693 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
1694 dwc_hc_t * hc, hcchar_data_t * hcchar)
1696 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1697 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1700 dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
1702 /* 1 if _next_ frame is odd, 0 if it's even */
1703 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
1705 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
1706 && !hc->complete_split) {
1707 switch (hfnum.b.frnum & 0x7) {
1709 core_if->hfnum_7_samples++;
1710 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
1713 core_if->hfnum_0_samples++;
1714 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
1717 core_if->hfnum_other_samples++;
1718 core_if->hfnum_other_frrem_accum +=
1728 void hc_xfer_timeout(void *ptr)
1730 hc_xfer_info_t *xfer_info = (hc_xfer_info_t *) ptr;
1731 int hc_num = xfer_info->hc->hc_num;
1732 DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
1733 DWC_WARN(" start_hcchar_val 0x%08x\n",
1734 xfer_info->core_if->start_hcchar_val[hc_num]);
1739 * This function does the setup for a data transfer for a host channel and
1740 * starts the transfer. May be called in either Slave mode or DMA mode. In
1741 * Slave mode, the caller must ensure that there is sufficient space in the
1742 * request queue and Tx Data FIFO.
1744 * For an OUT transfer in Slave mode, it loads a data packet into the
1745 * appropriate FIFO. If necessary, additional data packets will be loaded in
1748 * For an IN transfer in Slave mode, a data packet is requested. The data
1749 * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
1750 * additional data packets are requested in the Host ISR.
1752 * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
1753 * register along with a packet count of 1 and the channel is enabled. This
1754 * causes a single PING transaction to occur. Other fields in HCTSIZ are
1755 * simply set to 0 since no data transfer occurs in this case.
1757 * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
1758 * all the information required to perform the subsequent data transfer. In
1759 * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
1760 * controller performs the entire PING protocol, then starts the data
1763 * @param core_if Programming view of DWC_otg controller.
1764 * @param hc Information needed to initialize the host channel. The xfer_len
1765 * value may be reduced to accommodate the max widths of the XferSize and
1766 * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
1767 * to reflect the final xfer_len value.
1769 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1771 hcchar_data_t hcchar;
1772 hctsiz_data_t hctsiz;
1773 uint16_t num_packets;
1774 uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
1775 uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
1776 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1781 if (!core_if->dma_enable) {
1782 dwc_otg_hc_do_ping(core_if, hc);
1783 hc->xfer_started = 1;
1793 if (hc->complete_split && !hc->ep_is_in) {
1794 /* For CSPLIT OUT Transfer, set the size to 0 so the
1795 * core doesn't expect any data written to the FIFO */
1797 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
1798 hc->xfer_len = hc->max_packet;
1799 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
1803 hctsiz.b.xfersize = hc->xfer_len;
1806 * Ensure that the transfer length and packet count will fit
1807 * in the widths allocated for them in the HCTSIZn register.
1809 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1810 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1812 * Make sure the transfer size is no larger than one
1813 * (micro)frame's worth of data. (A check was done
1814 * when the periodic transfer was accepted to ensure
1815 * that a (micro)frame's worth of data can be
1816 * programmed into a channel.)
1818 uint32_t max_periodic_len =
1819 hc->multi_count * hc->max_packet;
1820 if (hc->xfer_len > max_periodic_len) {
1821 hc->xfer_len = max_periodic_len;
1824 } else if (hc->xfer_len > max_hc_xfer_size) {
1825 /* Make sure that xfer_len is a multiple of max packet size. */
1826 hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
1829 if (hc->xfer_len > 0) {
1831 (hc->xfer_len + hc->max_packet -
1832 1) / hc->max_packet;
1833 if (num_packets > max_hc_pkt_count) {
1834 num_packets = max_hc_pkt_count;
1835 hc->xfer_len = num_packets * hc->max_packet;
1838 /* Need 1 packet for transfer length of 0. */
1843 /* Always program an integral # of max packets for IN transfers. */
1844 hc->xfer_len = num_packets * hc->max_packet;
1847 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1848 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1850 * Make sure that the multi_count field matches the
1851 * actual transfer length.
1853 hc->multi_count = num_packets;
1856 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1857 /* Set up the initial PID for the transfer. */
1858 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
1860 if (hc->multi_count == 1) {
1861 hc->data_pid_start =
1862 DWC_OTG_HC_PID_DATA0;
1863 } else if (hc->multi_count == 2) {
1864 hc->data_pid_start =
1865 DWC_OTG_HC_PID_DATA1;
1867 hc->data_pid_start =
1868 DWC_OTG_HC_PID_DATA2;
1871 if (hc->multi_count == 1) {
1872 hc->data_pid_start =
1873 DWC_OTG_HC_PID_DATA0;
1875 hc->data_pid_start =
1876 DWC_OTG_HC_PID_MDATA;
1880 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
1884 hctsiz.b.xfersize = hc->xfer_len;
1887 hc->start_pkt_count = num_packets;
1888 hctsiz.b.pktcnt = num_packets;
1889 hctsiz.b.pid = hc->data_pid_start;
1890 dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
1892 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1893 DWC_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
1894 DWC_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n", hctsiz.b.pktcnt);
1895 DWC_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
1897 if (core_if->dma_enable) {
1898 dwc_write_reg32(&hc_regs->hcdma, (uint32_t) hc->xfer_buff);
1901 /* Start the split */
1903 hcsplt_data_t hcsplt;
1904 hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
1905 hcsplt.b.spltena = 1;
1906 dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
1909 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1910 hcchar.b.multicnt = hc->multi_count;
1911 hc_set_even_odd_frame(core_if, hc, &hcchar);
1913 core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
1914 if (hcchar.b.chdis) {
1915 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1916 __func__, hc->hc_num, hcchar.d32);
1920 /* Set host channel enable after all other setup is complete. */
1923 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1925 hc->xfer_started = 1;
1928 if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
1929 /* Load OUT packet into the appropriate Tx FIFO. */
1930 dwc_otg_hc_write_packet(core_if, hc);
1933 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
1934 core_if->hc_xfer_info[hc->hc_num].hc = hc;
1935 /* Start a timer for this transfer. */
1936 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
1941 * This function continues a data transfer that was started by previous call
1942 * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
1943 * sufficient space in the request queue and Tx Data FIFO. This function
1944 * should only be called in Slave mode. In DMA mode, the controller acts
1945 * autonomously to complete transfers programmed to a host channel.
1947 * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
1948 * if there is any data remaining to be queued. For an IN transfer, another
1949 * data packet is always requested. For the SETUP phase of a control transfer,
1950 * this function does nothing.
1952 * @return 1 if a new request is queued, 0 if no more requests are required
1953 * for this transfer.
1955 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1957 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1960 /* SPLITs always queue just once per channel */
1962 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
1963 /* SETUPs are queued only once since they can't be NAKed. */
1965 } else if (hc->ep_is_in) {
1967 * Always queue another request for other IN transfers. If
1968 * back-to-back INs are issued and NAKs are received for both,
1969 * the driver may still be processing the first NAK when the
1970 * second NAK is received. When the interrupt handler clears
1971 * the NAK interrupt for the first NAK, the second NAK will
1972 * not be seen. So we can't depend on the NAK interrupt
1973 * handler to requeue a NAKed request. Instead, IN requests
1974 * are issued each time this function is called. When the
1975 * transfer completes, the extra requests for the channel will
1978 hcchar_data_t hcchar;
1979 dwc_otg_hc_regs_t *hc_regs =
1980 core_if->host_if->hc_regs[hc->hc_num];
1982 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1983 hc_set_even_odd_frame(core_if, hc, &hcchar);
1986 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
1988 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1992 /* OUT transfers. */
1993 if (hc->xfer_count < hc->xfer_len) {
1994 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1995 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1996 hcchar_data_t hcchar;
1997 dwc_otg_hc_regs_t *hc_regs;
1998 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1999 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2000 hc_set_even_odd_frame(core_if, hc, &hcchar);
2003 /* Load OUT packet into the appropriate Tx FIFO. */
2004 dwc_otg_hc_write_packet(core_if, hc);
2014 * Starts a PING transfer. This function should only be called in Slave mode.
2015 * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
2017 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2019 hcchar_data_t hcchar;
2020 hctsiz_data_t hctsiz;
2021 dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2023 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2027 hctsiz.b.pktcnt = 1;
2028 dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2030 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2033 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2037 * This function writes a packet into the Tx FIFO associated with the Host
2038 * Channel. For a channel associated with a non-periodic EP, the non-periodic
2039 * Tx FIFO is written. For a channel associated with a periodic EP, the
2040 * periodic Tx FIFO is written. This function should only be called in Slave
2043 * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2044 * then number of bytes written to the Tx FIFO.
2046 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2049 uint32_t remaining_count;
2050 uint32_t byte_count;
2051 uint32_t dword_count;
2053 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
2054 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
2056 remaining_count = hc->xfer_len - hc->xfer_count;
2057 if (remaining_count > hc->max_packet) {
2058 byte_count = hc->max_packet;
2060 byte_count = remaining_count;
2063 dword_count = (byte_count + 3) / 4;
2065 if ((((unsigned long)data_buff) & 0x3) == 0) {
2066 /* xfer_buff is DWORD aligned. */
2067 for (i = 0; i < dword_count; i++, data_buff++) {
2068 dwc_write_reg32(data_fifo, *data_buff);
2071 /* xfer_buff is not DWORD aligned. */
2072 for (i = 0; i < dword_count; i++, data_buff++) {
2075 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
2076 16 | data_buff[3] << 24);
2077 dwc_write_reg32(data_fifo, data);
2081 hc->xfer_count += byte_count;
2082 hc->xfer_buff += byte_count;
2086 * Gets the current USB frame number. This is the frame number from the last
2089 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
2092 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
2094 /* read current frame/microframe number from DSTS register */
2095 return dsts.b.soffn;
2099 * This function reads a setup packet from the Rx FIFO into the destination
2100 * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
2101 * Interrupt routine when a SETUP packet has been received in Slave mode.
2103 * @param core_if Programming view of DWC_otg controller.
2104 * @param dest Destination buffer for packet data.
2106 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
2108 /* Get the 8 bytes of a setup transaction data */
2110 /* Pop 2 DWORDS off the receive data FIFO into memory */
2111 dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
2112 dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
2116 * This function enables EP0 OUT to receive SETUP packets and configures EP0
2117 * IN for transmitting packets. It is normally called when the
2118 * "Enumeration Done" interrupt occurs.
2120 * @param core_if Programming view of DWC_otg controller.
2121 * @param ep The EP0 data.
2123 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2125 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2127 depctl_data_t diepctl;
2128 depctl_data_t doepctl;
2129 dctl_data_t dctl = {.d32 = 0 };
2131 /* Read the Device Status and Endpoint 0 Control registers */
2132 dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
2133 diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
2134 doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
2136 /* Set the MPS of the IN EP based on the enumeration speed */
2137 switch (dsts.b.enumspd) {
2138 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
2139 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
2140 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
2141 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
2143 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
2144 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
2148 dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
2150 /* Enable OUT EP for receive */
2151 doepctl.b.epena = 1;
2152 dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
2155 DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
2156 dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
2157 DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
2158 dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
2160 dctl.b.cgnpinnak = 1;
2162 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
2163 DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
2164 dwc_read_reg32(&dev_if->dev_global_regs->dctl));
2168 * This function activates an EP. The Device EP control register for
2169 * the EP is configured as defined in the ep structure. Note: This
2170 * function is not used for EP0.
2172 * @param core_if Programming view of DWC_otg controller.
2173 * @param ep The EP to activate.
2175 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2177 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2178 depctl_data_t depctl;
2179 volatile uint32_t *addr;
2180 daint_data_t daintmsk = {.d32 = 0 };
2182 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
2183 (ep->is_in ? "IN" : "OUT"));
2185 /* Read DEPCTLn register */
2186 if (ep->is_in == 1) {
2187 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
2188 daintmsk.ep.in = 1 << ep->num;
2190 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
2191 daintmsk.ep.out = 1 << ep->num;
2194 /* If the EP is already active don't change the EP Control
2196 depctl.d32 = dwc_read_reg32(addr);
2197 if (!depctl.b.usbactep) {
2198 depctl.b.mps = ep->maxpacket;
2199 depctl.b.eptype = ep->type;
2200 depctl.b.txfnum = ep->tx_fifo_num;
2202 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
2203 depctl.b.setd0pid = 1; // ???
2205 depctl.b.setd0pid = 1;
2207 depctl.b.usbactep = 1;
2209 dwc_write_reg32(addr, depctl.d32);
2210 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr));
2213 /* Enable the Interrupt for this EP */
2214 if (core_if->multiproc_int_enable) {
2215 if (ep->is_in == 1) {
2216 diepmsk_data_t diepmsk = {.d32 = 0 };
2217 diepmsk.b.xfercompl = 1;
2218 diepmsk.b.timeout = 1;
2219 diepmsk.b.epdisabled = 1;
2220 diepmsk.b.ahberr = 1;
2221 diepmsk.b.intknepmis = 1;
2222 diepmsk.b.txfifoundrn = 1; //?????
2224 if (core_if->dma_desc_enable) {
2228 if(core_if->dma_enable) {
2232 dwc_write_reg32(&dev_if->dev_global_regs->
2233 diepeachintmsk[ep->num], diepmsk.d32);
2236 doepmsk_data_t doepmsk = {.d32 = 0 };
2237 doepmsk.b.xfercompl = 1;
2238 doepmsk.b.ahberr = 1;
2239 doepmsk.b.epdisabled = 1;
2241 if (core_if->dma_desc_enable) {
2245 doepmsk.b.babble = 1;
2249 dwc_write_reg32(&dev_if->dev_global_regs->
2250 doepeachintmsk[ep->num], doepmsk.d32);
2252 dwc_modify_reg32(&dev_if->dev_global_regs->deachintmsk,
2255 dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
2259 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
2260 dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
2262 ep->stall_clear_flag = 0;
2267 * This function deactivates an EP. This is done by clearing the USB Active
2268 * EP bit in the Device EP control register. Note: This function is not used
2269 * for EP0. EP0 cannot be deactivated.
2271 * @param core_if Programming view of DWC_otg controller.
2272 * @param ep The EP to deactivate.
2274 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2276 depctl_data_t depctl = {.d32 = 0 };
2277 volatile uint32_t *addr;
2278 daint_data_t daintmsk = {.d32 = 0 };
2280 /* Read DEPCTLn register */
2281 if (ep->is_in == 1) {
2282 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
2283 daintmsk.ep.in = 1 << ep->num;
2285 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
2286 daintmsk.ep.out = 1 << ep->num;
2289 depctl.d32 = dwc_read_reg32(addr);
2291 depctl.b.usbactep = 0;
2293 if (core_if->dma_desc_enable)
2296 dwc_write_reg32(addr, depctl.d32);
2298 /* Disable the Interrupt for this EP */
2299 if (core_if->multiproc_int_enable) {
2300 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->deachintmsk,
2303 if (ep->is_in == 1) {
2304 dwc_write_reg32(&core_if->dev_if->dev_global_regs->
2305 diepeachintmsk[ep->num], 0);
2307 dwc_write_reg32(&core_if->dev_if->dev_global_regs->
2308 doepeachintmsk[ep->num], 0);
2311 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
2317 * This function initializes dma descriptor chain.
2319 * @param core_if Programming view of DWC_otg controller.
2320 * @param ep The EP to start the transfer on.
2322 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2324 dwc_otg_dma_desc_t *dma_desc;
2329 ep->desc_cnt = (ep->total_len / ep->maxxfer) +
2330 ((ep->total_len % ep->maxxfer) ? 1 : 0);
2334 dma_desc = ep->desc_addr;
2335 xfer_est = ep->total_len;
2337 for (i = 0; i < ep->desc_cnt; ++i) {
2338 /** DMA Descriptor Setup */
2339 if (xfer_est > ep->maxxfer) {
2340 dma_desc->status.b.bs = BS_HOST_BUSY;
2341 dma_desc->status.b.l = 0;
2342 dma_desc->status.b.ioc = 0;
2343 dma_desc->status.b.sp = 0;
2344 dma_desc->status.b.bytes = ep->maxxfer;
2345 dma_desc->buf = ep->dma_addr + offset;
2346 dma_desc->status.b.bs = BS_HOST_READY;
2348 xfer_est -= ep->maxxfer;
2349 offset += ep->maxxfer;
2351 dma_desc->status.b.bs = BS_HOST_BUSY;
2352 dma_desc->status.b.l = 1;
2353 dma_desc->status.b.ioc = 1;
2355 dma_desc->status.b.sp =
2357 ep->maxpacket) ? 1 : ((ep->
2359 dma_desc->status.b.bytes = xfer_est;
2361 dma_desc->status.b.bytes =
2362 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
2365 dma_desc->buf = ep->dma_addr + offset;
2366 dma_desc->status.b.bs = BS_HOST_READY;
2373 * This function does the setup for a data transfer for an EP and
2374 * starts the transfer. For an IN transfer, the packets will be
2375 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
2376 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
2378 * @param core_if Programming view of DWC_otg controller.
2379 * @param ep The EP to start the transfer on.
2382 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2384 depctl_data_t depctl;
2385 deptsiz_data_t deptsiz;
2386 gintmsk_data_t intr_mask = {.d32 = 0 };
2388 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
2389 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
2390 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
2391 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
2392 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
2395 if (ep->is_in == 1) {
2396 dwc_otg_dev_in_ep_regs_t *in_regs =
2397 core_if->dev_if->in_ep_regs[ep->num];
2399 gnptxsts_data_t gtxstatus;
2402 dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2404 if (core_if->en_multiple_tx_fifo == 0
2405 && gtxstatus.b.nptxqspcavail == 0) {
2407 DWC_DEBUGPL(DBG_CIL,"TX Queue Full (0x%0x)\n", gtxstatus.d32);
2412 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
2413 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
2415 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
2416 ep->maxxfer : (ep->total_len - ep->xfer_len);
2418 /* Zero Length Packet? */
2419 if ((ep->xfer_len - ep->xfer_count) == 0) {
2420 deptsiz.b.xfersize = 0;
2421 deptsiz.b.pktcnt = 1;
2423 /* Program the transfer size and packet count
2424 * as follows: xfersize = N * maxpacket +
2425 * short_packet pktcnt = N + (short_packet
2428 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
2430 (ep->xfer_len - ep->xfer_count - 1 +
2431 ep->maxpacket) / ep->maxpacket;
2434 /* Write the DMA register */
2435 if (core_if->dma_enable) {
2436 if (core_if->dma_desc_enable == 0) {
2437 dwc_write_reg32(&in_regs->dieptsiz,
2439 dwc_write_reg32(&(in_regs->diepdma),
2440 (uint32_t) ep->dma_addr);
2443 /* The descriptor chain should be already initialized by now */
2444 if (ep->buff_mode != BM_STANDARD) {
2445 dwc_write_reg32(&in_regs->diepdma,
2446 ep->descs_dma_addr);
2449 init_dma_desc_chain(core_if, ep);
2450 /** DIEPDMAn Register write */
2451 dwc_write_reg32(&in_regs->diepdma,
2458 dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2459 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
2461 * Enable the Non-Periodic Tx FIFO empty interrupt,
2462 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
2463 * the data will be written into the fifo by the ISR.
2465 if (core_if->en_multiple_tx_fifo == 0) {
2466 intr_mask.b.nptxfempty = 1;
2467 dwc_modify_reg32(&core_if->
2469 gintmsk, intr_mask.d32,
2472 /* Enable the Tx FIFO Empty Interrupt for this EP */
2473 if (ep->xfer_len > 0) {
2474 uint32_t fifoemptymsk = 0;
2475 fifoemptymsk = 1 << ep->num;
2476 dwc_modify_reg32(&core_if->
2479 dtknqr4_fifoemptymsk,
2488 /* EP enable, IN data in FIFO */
2491 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2494 dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
2495 depctl.b.nextep = ep->num;
2496 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
2501 dwc_otg_dev_out_ep_regs_t *out_regs =
2502 core_if->dev_if->out_ep_regs[ep->num];
2504 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
2505 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
2507 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
2508 ep->maxxfer : (ep->total_len - ep->xfer_len);
2510 /* Program the transfer size and packet count as follows:
2513 * xfersize = N * maxpacket
2515 if ((ep->xfer_len - ep->xfer_count) == 0) {
2516 /* Zero Length Packet */
2517 deptsiz.b.xfersize = ep->maxpacket;
2518 deptsiz.b.pktcnt = 1;
2521 (ep->xfer_len - ep->xfer_count +
2522 (ep->maxpacket - 1)) / ep->maxpacket;
2524 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
2525 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
2528 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
2529 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
2531 if (core_if->dma_enable) {
2532 if (!core_if->dma_desc_enable) {
2533 dwc_write_reg32(&out_regs->doeptsiz,
2536 dwc_write_reg32(&(out_regs->doepdma),
2537 (uint32_t) ep->dma_addr);
2540 /* The descriptor chain should be already initialized by now */
2541 if (ep->buff_mode != BM_STANDARD) {
2542 dwc_write_reg32(&out_regs->doepdma,
2543 ep->descs_dma_addr);
2547 init_dma_desc_chain(core_if, ep);
2549 /** DOEPDMAn Register write */
2550 dwc_write_reg32(&out_regs->doepdma,
2557 dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2564 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
2566 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
2567 dwc_read_reg32(&out_regs->doepctl),
2568 dwc_read_reg32(&out_regs->doeptsiz));
2569 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
2570 dwc_read_reg32(&core_if->dev_if->dev_global_regs->
2572 dwc_read_reg32(&core_if->core_global_regs->
2578 * This function setup a zero length transfer in Buffer DMA and
2579 * Slave modes for usb requests with zero field set
2581 * @param core_if Programming view of DWC_otg controller.
2582 * @param ep The EP to start the transfer on.
2585 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2588 depctl_data_t depctl;
2589 deptsiz_data_t deptsiz;
2590 gintmsk_data_t intr_mask = {.d32 = 0 };
2592 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
2593 DWC_DEBUGPL(DBG_CIL,"zero length transfer is called\n");
2596 if (ep->is_in == 1) {
2597 dwc_otg_dev_in_ep_regs_t *in_regs =
2598 core_if->dev_if->in_ep_regs[ep->num];
2600 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
2601 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
2603 deptsiz.b.xfersize = 0;
2604 deptsiz.b.pktcnt = 1;
2606 /* Write the DMA register */
2607 if (core_if->dma_enable) {
2608 if (core_if->dma_desc_enable == 0) {
2609 dwc_write_reg32(&in_regs->dieptsiz,
2611 dwc_write_reg32(&(in_regs->diepdma),
2612 (uint32_t) ep->dma_addr);
2615 dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2617 * Enable the Non-Periodic Tx FIFO empty interrupt,
2618 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
2619 * the data will be written into the fifo by the ISR.
2621 if (core_if->en_multiple_tx_fifo == 0) {
2622 intr_mask.b.nptxfempty = 1;
2623 dwc_modify_reg32(&core_if->core_global_regs->
2624 gintmsk, intr_mask.d32,
2627 /* Enable the Tx FIFO Empty Interrupt for this EP */
2628 if (ep->xfer_len > 0) {
2629 uint32_t fifoemptymsk = 0;
2630 fifoemptymsk = 1 << ep->num;
2631 dwc_modify_reg32(&core_if->dev_if->
2633 dtknqr4_fifoemptymsk,
2639 /* EP enable, IN data in FIFO */
2642 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2645 dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
2646 depctl.b.nextep = ep->num;
2647 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
2652 dwc_otg_dev_out_ep_regs_t *out_regs =
2653 core_if->dev_if->out_ep_regs[ep->num];
2655 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
2656 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
2658 /* Zero Length Packet */
2659 deptsiz.b.xfersize = ep->maxpacket;
2660 deptsiz.b.pktcnt = 1;
2662 if (core_if->dma_enable) {
2663 if (!core_if->dma_desc_enable) {
2664 dwc_write_reg32(&out_regs->doeptsiz,
2667 dwc_write_reg32(&(out_regs->doepdma),
2668 (uint32_t) ep->dma_addr);
2671 dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2678 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
2684 * This function does the setup for a data transfer for EP0 and starts
2685 * the transfer. For an IN transfer, the packets will be loaded into
2686 * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
2687 * unloaded from the Rx FIFO in the ISR.
2689 * @param core_if Programming view of DWC_otg controller.
2690 * @param ep The EP0 data.
2692 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2694 depctl_data_t depctl;
2695 deptsiz0_data_t deptsiz;
2696 gintmsk_data_t intr_mask = {.d32 = 0 };
2697 dwc_otg_dma_desc_t *dma_desc;
2699 DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
2700 "xfer_buff=%p start_xfer_buff=%p \n",
2701 ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
2702 ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
2704 ep->total_len = ep->xfer_len;
2707 if (ep->is_in == 1) {
2708 dwc_otg_dev_in_ep_regs_t *in_regs =
2709 core_if->dev_if->in_ep_regs[0];
2711 gnptxsts_data_t gtxstatus;
2714 dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2716 if (core_if->en_multiple_tx_fifo == 0
2717 && gtxstatus.b.nptxqspcavail == 0) {
2719 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2720 DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
2721 dwc_read_reg32(&in_regs->diepctl));
2722 DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
2724 deptsiz.b.xfersize, deptsiz.b.pktcnt);
2725 DWC_DEBUGPL(DBG_CIL,"TX Queue or FIFO Full (0x%0x)\n",
2731 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
2732 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2734 /* Zero Length Packet? */
2735 if (ep->xfer_len == 0) {
2736 deptsiz.b.xfersize = 0;
2737 deptsiz.b.pktcnt = 1;
2739 /* Program the transfer size and packet count
2740 * as follows: xfersize = N * maxpacket +
2741 * short_packet pktcnt = N + (short_packet
2744 if (ep->xfer_len > ep->maxpacket) {
2745 ep->xfer_len = ep->maxpacket;
2746 deptsiz.b.xfersize = ep->maxpacket;
2748 deptsiz.b.xfersize = ep->xfer_len;
2750 deptsiz.b.pktcnt = 1;
2753 DWC_DEBUGPL(DBG_PCDV,
2754 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
2755 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
2758 /* Write the DMA register */
2759 if (core_if->dma_enable) {
2760 if (core_if->dma_desc_enable == 0) {
2761 dwc_write_reg32(&in_regs->dieptsiz,
2764 dwc_write_reg32(&(in_regs->diepdma),
2765 (uint32_t) ep->dma_addr);
2767 dma_desc = core_if->dev_if->in_desc_addr;
2769 /** DMA Descriptor Setup */
2770 dma_desc->status.b.bs = BS_HOST_BUSY;
2771 dma_desc->status.b.l = 1;
2772 dma_desc->status.b.ioc = 1;
2773 dma_desc->status.b.sp =
2774 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
2775 dma_desc->status.b.bytes = ep->xfer_len;
2776 dma_desc->buf = ep->dma_addr;
2777 dma_desc->status.b.bs = BS_HOST_READY;
2779 /** DIEPDMA0 Register write */
2780 dwc_write_reg32(&in_regs->diepdma,
2785 dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2788 /* EP enable, IN data in FIFO */
2791 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2794 * Enable the Non-Periodic Tx FIFO empty interrupt, the
2795 * data will be written into the fifo by the ISR.
2797 if (!core_if->dma_enable) {
2798 if (core_if->en_multiple_tx_fifo == 0) {
2799 intr_mask.b.nptxfempty = 1;
2800 dwc_modify_reg32(&core_if->core_global_regs->
2801 gintmsk, intr_mask.d32,
2804 /* Enable the Tx FIFO Empty Interrupt for this EP */
2805 if (ep->xfer_len > 0) {
2806 uint32_t fifoemptymsk = 0;
2807 fifoemptymsk |= 1 << ep->num;
2808 dwc_modify_reg32(&core_if->dev_if->
2810 dtknqr4_fifoemptymsk,
2817 dwc_otg_dev_out_ep_regs_t *out_regs =
2818 core_if->dev_if->out_ep_regs[0];
2820 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
2821 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
2823 /* Program the transfer size and packet count as follows:
2824 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
2826 /* Zero Length Packet */
2827 deptsiz.b.xfersize = ep->maxpacket;
2828 deptsiz.b.pktcnt = 1;
2830 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
2831 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
2833 if (core_if->dma_enable) {
2834 if (!core_if->dma_desc_enable) {
2835 dwc_write_reg32(&out_regs->doeptsiz,
2838 dwc_write_reg32(&(out_regs->doepdma),
2839 (uint32_t) ep->dma_addr);
2841 dma_desc = core_if->dev_if->out_desc_addr;
2843 /** DMA Descriptor Setup */
2844 dma_desc->status.b.bs = BS_HOST_BUSY;
2845 dma_desc->status.b.l = 1;
2846 dma_desc->status.b.ioc = 1;
2847 dma_desc->status.b.bytes = ep->maxpacket;
2848 dma_desc->buf = ep->dma_addr;
2849 dma_desc->status.b.bs = BS_HOST_READY;
2851 /** DOEPDMA0 Register write */
2852 dwc_write_reg32(&out_regs->doepdma,
2857 dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2863 dwc_write_reg32(&(out_regs->doepctl), depctl.d32);
2868 * This function continues control IN transfers started by
2869 * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
2870 * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
2871 * bit for the packet count.
2873 * @param core_if Programming view of DWC_otg controller.
2874 * @param ep The EP0 data.
2876 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2878 depctl_data_t depctl;
2879 deptsiz0_data_t deptsiz;
2880 gintmsk_data_t intr_mask = {.d32 = 0 };
2881 dwc_otg_dma_desc_t *dma_desc;
2883 if (ep->is_in == 1) {
2884 dwc_otg_dev_in_ep_regs_t *in_regs =
2885 core_if->dev_if->in_ep_regs[0];
2886 gnptxsts_data_t tx_status = {.d32 = 0 };
2889 dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2890 /** @todo Should there be check for room in the Tx
2891 * Status Queue. If not remove the code above this comment. */
2893 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
2894 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2896 /* Program the transfer size and packet count
2897 * as follows: xfersize = N * maxpacket +
2898 * short_packet pktcnt = N + (short_packet
2902 if (core_if->dma_desc_enable == 0) {
2903 deptsiz.b.xfersize =
2904 (ep->total_len - ep->xfer_count) >
2905 ep->maxpacket ? ep->maxpacket : (ep->total_len -
2907 deptsiz.b.pktcnt = 1;
2908 if (core_if->dma_enable == 0) {
2909 ep->xfer_len += deptsiz.b.xfersize;
2911 ep->xfer_len = deptsiz.b.xfersize;
2913 dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2916 (ep->total_len - ep->xfer_count) >
2917 ep->maxpacket ? ep->maxpacket : (ep->total_len -
2920 dma_desc = core_if->dev_if->in_desc_addr;
2922 /** DMA Descriptor Setup */
2923 dma_desc->status.b.bs = BS_HOST_BUSY;
2924 dma_desc->status.b.l = 1;
2925 dma_desc->status.b.ioc = 1;
2926 dma_desc->status.b.sp =
2927 (ep->xfer_len == ep->maxpacket) ? 0 : 1;
2928 dma_desc->status.b.bytes = ep->xfer_len;
2929 dma_desc->buf = ep->dma_addr;
2930 dma_desc->status.b.bs = BS_HOST_READY;
2932 /** DIEPDMA0 Register write */
2933 dwc_write_reg32(&in_regs->diepdma,
2934 core_if->dev_if->dma_in_desc_addr);
2937 DWC_DEBUGPL(DBG_PCDV,
2938 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
2939 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
2942 /* Write the DMA register */
2943 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
2944 if (core_if->dma_desc_enable == 0)
2945 dwc_write_reg32(&(in_regs->diepdma),
2946 (uint32_t) ep->dma_addr);
2949 /* EP enable, IN data in FIFO */
2952 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2955 * Enable the Non-Periodic Tx FIFO empty interrupt, the
2956 * data will be written into the fifo by the ISR.
2958 if (!core_if->dma_enable) {
2959 if (core_if->en_multiple_tx_fifo == 0) {
2960 /* First clear it from GINTSTS */
2961 intr_mask.b.nptxfempty = 1;
2962 dwc_modify_reg32(&core_if->core_global_regs->
2963 gintmsk, intr_mask.d32,
2967 /* Enable the Tx FIFO Empty Interrupt for this EP */
2968 if (ep->xfer_len > 0) {
2969 uint32_t fifoemptymsk = 0;
2970 fifoemptymsk |= 1 << ep->num;
2971 dwc_modify_reg32(&core_if->dev_if->
2973 dtknqr4_fifoemptymsk,
2979 dwc_otg_dev_out_ep_regs_t *out_regs =
2980 core_if->dev_if->out_ep_regs[0];
2982 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
2983 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
2985 /* Program the transfer size and packet count
2986 * as follows: xfersize = N * maxpacket +
2987 * short_packet pktcnt = N + (short_packet
2990 deptsiz.b.xfersize = ep->maxpacket;
2991 deptsiz.b.pktcnt = 1;
2993 if (core_if->dma_desc_enable == 0) {
2994 dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2996 dma_desc = core_if->dev_if->out_desc_addr;
2998 /** DMA Descriptor Setup */
2999 dma_desc->status.b.bs = BS_HOST_BUSY;
3000 dma_desc->status.b.l = 1;
3001 dma_desc->status.b.ioc = 1;
3002 dma_desc->status.b.bytes = ep->maxpacket;
3003 dma_desc->buf = ep->dma_addr;
3004 dma_desc->status.b.bs = BS_HOST_READY;
3006 /** DOEPDMA0 Register write */
3007 dwc_write_reg32(&out_regs->doepdma,
3008 core_if->dev_if->dma_out_desc_addr);
3011 DWC_DEBUGPL(DBG_PCDV,
3012 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
3013 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
3016 /* Write the DMA register */
3017 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
3018 if (core_if->dma_desc_enable == 0)
3019 dwc_write_reg32(&(out_regs->doepdma),
3020 (uint32_t) ep->dma_addr);
3023 /* EP enable, IN data in FIFO */
3026 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3032 void dump_msg(const u8 * buf, unsigned int length)
3034 unsigned int start, num, i;
3040 while (length > 0) {
3041 num = length < 16u ? length : 16u;
3043 for (i = 0; i < num; ++i) {
3046 DWC_SPRINTF(p, " %02x", buf[i]);
3050 DWC_DEBUGPL(DBG_CIL,"%6x: %s\n", start, line);
3057 static inline void dump_msg(const u8 * buf, unsigned int length)
3063 * This function writes a packet into the Tx FIFO associated with the
3064 * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
3065 * periodic EPs the periodic Tx FIFO associated with the EP is written
3066 * with all packets for the next micro-frame.
3068 * @param core_if Programming view of DWC_otg controller.
3069 * @param ep The EP to write packet for.
3070 * @param dma Indicates if DMA is being used.
3072 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
3076 * The buffer is padded to DWORD on a per packet basis in
3077 * slave/dma mode if the MPS is not DWORD aligned. The last
3078 * packet, if short, is also padded to a multiple of DWORD.
3080 * ep->xfer_buff always starts DWORD aligned in memory and is a
3081 * multiple of DWORD in length
3083 * ep->xfer_len can be any number of bytes
3085 * ep->xfer_count is a multiple of ep->maxpacket until the last
3088 * FIFO access is DWORD */
3091 uint32_t byte_count;
3092 uint32_t dword_count;
3094 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
3096 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
3098 if (ep->xfer_count >= ep->xfer_len) {
3099 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
3103 /* Find the byte length of the packet either short packet or MPS */
3104 if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
3105 byte_count = ep->xfer_len - ep->xfer_count;
3107 byte_count = ep->maxpacket;
3110 /* Find the DWORD length, padded by extra bytes as neccessary if MPS
3111 * is not a multiple of DWORD */
3112 dword_count = (byte_count + 3) / 4;
3115 dump_msg(ep->xfer_buff, byte_count);
3118 /**@todo NGS Where are the Periodic Tx FIFO addresses
3119 * intialized? What should this be? */
3121 fifo = core_if->data_fifo[ep->num];
3123 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
3124 fifo, data_buff, *data_buff, byte_count);
3127 for (i = 0; i < dword_count; i++, data_buff++) {
3128 dwc_write_reg32(fifo, *data_buff);
3132 ep->xfer_count += byte_count;
3133 ep->xfer_buff += byte_count;
3134 ep->dma_addr += byte_count;
3140 * @param core_if Programming view of DWC_otg controller.
3141 * @param ep The EP to set the stall on.
3143 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3145 depctl_data_t depctl;
3146 volatile uint32_t *depctl_addr;
3148 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
3149 (ep->is_in ? "IN" : "OUT"));
3151 if (ep->is_in == 1) {
3152 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
3153 depctl.d32 = dwc_read_reg32(depctl_addr);
3155 /* set the disable and stall bits */
3156 if (depctl.b.epena) {
3160 dwc_write_reg32(depctl_addr, depctl.d32);
3162 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
3163 depctl.d32 = dwc_read_reg32(depctl_addr);
3165 /* set the stall bit */
3167 dwc_write_reg32(depctl_addr, depctl.d32);
3170 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
3176 * Clear the EP STALL.
3178 * @param core_if Programming view of DWC_otg controller.
3179 * @param ep The EP to clear stall from.
3181 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3183 depctl_data_t depctl;
3184 volatile uint32_t *depctl_addr;
3186 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
3187 (ep->is_in ? "IN" : "OUT"));
3189 if (ep->is_in == 1) {
3190 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
3192 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
3195 depctl.d32 = dwc_read_reg32(depctl_addr);
3197 /* clear the stall bits */
3201 * USB Spec 9.4.5: For endpoints using data toggle, regardless
3202 * of whether an endpoint has the Halt feature set, a
3203 * ClearFeature(ENDPOINT_HALT) request always results in the
3204 * data toggle being reinitialized to DATA0.
3206 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
3207 ep->type == DWC_OTG_EP_TYPE_BULK) {
3208 depctl.b.setd0pid = 1; /* DATA0 */
3211 dwc_write_reg32(depctl_addr, depctl.d32);
3212 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
3217 * This function reads a packet from the Rx FIFO into the destination
3218 * buffer. To read SETUP data use dwc_otg_read_setup_packet.
3220 * @param core_if Programming view of DWC_otg controller.
3221 * @param dest Destination buffer for the packet.
3222 * @param bytes Number of bytes to copy to the destination.
3224 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
3225 uint8_t * dest, uint16_t bytes)
3228 int word_count = (bytes + 3) / 4;
3230 volatile uint32_t *fifo = core_if->data_fifo[0];
3231 uint32_t *data_buff = (uint32_t *) dest;
3234 * @todo Account for the case where _dest is not dword aligned. This
3235 * requires reading data from the FIFO into a uint32_t temp buffer,
3236 * then moving it into the data buffer.
3239 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
3240 core_if, dest, bytes);
3242 for (i = 0; i < word_count; i++, data_buff++) {
3243 *data_buff = dwc_read_reg32(fifo);
3250 * This functions reads the device registers and prints them
3252 * @param core_if Programming view of DWC_otg controller.
3254 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
3257 volatile uint32_t *addr;
3259 DWC_DEBUGPL(DBG_CIL,"Device Global Registers\n");
3260 addr = &core_if->dev_if->dev_global_regs->dcfg;
3261 DWC_DEBUGPL(DBG_CIL,"DCFG @0x%08X : 0x%08X\n", (uint32_t) addr,
3262 dwc_read_reg32(addr));
3263 addr = &core_if->dev_if->dev_global_regs->dctl;
3264 DWC_DEBUGPL(DBG_CIL,"DCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3265 dwc_read_reg32(addr));
3266 addr = &core_if->dev_if->dev_global_regs->dsts;
3267 DWC_DEBUGPL(DBG_CIL,"DSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3268 dwc_read_reg32(addr));
3269 addr = &core_if->dev_if->dev_global_regs->diepmsk;
3270 DWC_DEBUGPL(DBG_CIL,"DIEPMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3271 dwc_read_reg32(addr));
3272 addr = &core_if->dev_if->dev_global_regs->doepmsk;
3273 DWC_DEBUGPL(DBG_CIL,"DOEPMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3274 dwc_read_reg32(addr));
3275 addr = &core_if->dev_if->dev_global_regs->daint;
3276 DWC_DEBUGPL(DBG_CIL,"DAINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3277 dwc_read_reg32(addr));
3278 addr = &core_if->dev_if->dev_global_regs->daintmsk;
3279 DWC_DEBUGPL(DBG_CIL,"DAINTMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3280 dwc_read_reg32(addr));
3281 addr = &core_if->dev_if->dev_global_regs->dtknqr1;
3282 DWC_DEBUGPL(DBG_CIL,"DTKNQR1 @0x%08X : 0x%08X\n", (uint32_t) addr,
3283 dwc_read_reg32(addr));
3284 if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
3285 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
3286 DWC_DEBUGPL(DBG_CIL,"DTKNQR2 @0x%08X : 0x%08X\n",
3287 (uint32_t) addr, dwc_read_reg32(addr));
3290 addr = &core_if->dev_if->dev_global_regs->dvbusdis;
3291 DWC_DEBUGPL(DBG_CIL,"DVBUSID @0x%08X : 0x%08X\n", (uint32_t) addr,
3292 dwc_read_reg32(addr));
3294 addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
3295 DWC_DEBUGPL(DBG_CIL,"DVBUSPULSE @0x%08X : 0x%08X\n",
3296 (uint32_t) addr, dwc_read_reg32(addr));
3298 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
3299 DWC_DEBUGPL(DBG_CIL,"DTKNQR3_DTHRCTL @0x%08X : 0x%08X\n",
3300 (uint32_t) addr, dwc_read_reg32(addr));
3302 if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
3303 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
3304 DWC_DEBUGPL(DBG_CIL,"DTKNQR4 @0x%08X : 0x%08X\n",
3305 (uint32_t) addr, dwc_read_reg32(addr));
3308 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
3309 DWC_DEBUGPL(DBG_CIL,"FIFOEMPMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3310 dwc_read_reg32(addr));
3312 addr = &core_if->dev_if->dev_global_regs->deachint;
3313 DWC_DEBUGPL(DBG_CIL,"DEACHINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3314 dwc_read_reg32(addr));
3315 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
3316 DWC_DEBUGPL(DBG_CIL,"DEACHINTMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3317 dwc_read_reg32(addr));
3319 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3320 addr = &core_if->dev_if->dev_global_regs->diepeachintmsk[i];
3321 DWC_DEBUGPL(DBG_CIL,"DIEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i,
3322 (uint32_t) addr, dwc_read_reg32(addr));
3325 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
3326 addr = &core_if->dev_if->dev_global_regs->doepeachintmsk[i];
3327 DWC_DEBUGPL(DBG_CIL,"DOEPEACHINTMSK[%d] @0x%08X : 0x%08X\n", i,
3328 (uint32_t) addr, dwc_read_reg32(addr));
3331 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3332 DWC_DEBUGPL(DBG_CIL,"Device IN EP %d Registers\n", i);
3333 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
3334 DWC_DEBUGPL(DBG_CIL,"DIEPCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3335 dwc_read_reg32(addr));
3336 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
3337 DWC_DEBUGPL(DBG_CIL,"DIEPINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3338 dwc_read_reg32(addr));
3339 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
3340 DWC_DEBUGPL(DBG_CIL,"DIETSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3341 dwc_read_reg32(addr));
3342 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
3343 DWC_DEBUGPL(DBG_CIL,"DIEPDMA @0x%08X : 0x%08X\n", (uint32_t) addr,
3344 dwc_read_reg32(addr));
3345 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
3346 DWC_DEBUGPL(DBG_CIL,"DTXFSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3347 dwc_read_reg32(addr));
3348 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
3349 DWC_DEBUGPL(DBG_CIL,"DIEPDMAB @0x%08X : 0x%08X\n", (uint32_t) addr,
3350 0 /*dwc_read_reg32(addr) */ );
3353 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
3354 DWC_DEBUGPL(DBG_CIL,"Device OUT EP %d Registers\n", i);
3355 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
3356 DWC_DEBUGPL(DBG_CIL,"DOEPCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3357 dwc_read_reg32(addr));
3358 addr = &core_if->dev_if->out_ep_regs[i]->doepfn;
3359 DWC_DEBUGPL(DBG_CIL,"DOEPFN @0x%08X : 0x%08X\n", (uint32_t) addr,
3360 dwc_read_reg32(addr));
3361 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
3362 DWC_DEBUGPL(DBG_CIL,"DOEPINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3363 dwc_read_reg32(addr));
3364 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
3365 DWC_DEBUGPL(DBG_CIL,"DOETSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3366 dwc_read_reg32(addr));
3367 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
3368 DWC_DEBUGPL(DBG_CIL,"DOEPDMA @0x%08X : 0x%08X\n", (uint32_t) addr,
3369 dwc_read_reg32(addr));
3370 if (core_if->dma_enable) { /* Don't access this register in SLAVE mode */
3371 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
3372 DWC_DEBUGPL(DBG_CIL,"DOEPDMAB @0x%08X : 0x%08X\n",
3373 (uint32_t) addr, dwc_read_reg32(addr));
3380 * This functions reads the SPRAM and prints its content
3382 * @param core_if Programming view of DWC_otg controller.
3384 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
3386 volatile uint8_t *addr, *start_addr, *end_addr;
3388 DWC_DEBUGPL(DBG_CIL,"SPRAM Data:\n");
3389 start_addr = (void *)core_if->core_global_regs;
3390 DWC_DEBUGPL(DBG_CIL,"Base Address: 0x%8X\n", (uint32_t) start_addr);
3391 start_addr += 0x00028000;
3392 end_addr = (void *)core_if->core_global_regs;
3393 end_addr += 0x000280e0;
3395 for (addr = start_addr; addr < end_addr; addr += 16) {
3396 DWC_DEBUGPL(DBG_CIL,"0x%8X:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
3397 (uint32_t) addr, addr[0], addr[1], addr[2], addr[3],
3398 addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
3399 addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
3407 * This function reads the host registers and prints them
3409 * @param core_if Programming view of DWC_otg controller.
3411 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
3414 volatile uint32_t *addr;
3416 DWC_DEBUGPL(DBG_CIL,"Host Global Registers\n");
3417 addr = &core_if->host_if->host_global_regs->hcfg;
3418 DWC_DEBUGPL(DBG_CIL,"HCFG @0x%08X : 0x%08X\n", (uint32_t) addr,
3419 dwc_read_reg32(addr));
3420 addr = &core_if->host_if->host_global_regs->hfir;
3421 DWC_DEBUGPL(DBG_CIL,"HFIR @0x%08X : 0x%08X\n", (uint32_t) addr,
3422 dwc_read_reg32(addr));
3423 addr = &core_if->host_if->host_global_regs->hfnum;
3424 DWC_DEBUGPL(DBG_CIL,"HFNUM @0x%08X : 0x%08X\n", (uint32_t) addr,
3425 dwc_read_reg32(addr));
3426 addr = &core_if->host_if->host_global_regs->hptxsts;
3427 DWC_DEBUGPL(DBG_CIL,"HPTXSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3428 dwc_read_reg32(addr));
3429 addr = &core_if->host_if->host_global_regs->haint;
3430 DWC_DEBUGPL(DBG_CIL,"HAINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3431 dwc_read_reg32(addr));
3432 addr = &core_if->host_if->host_global_regs->haintmsk;
3433 DWC_DEBUGPL(DBG_CIL,"HAINTMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3434 dwc_read_reg32(addr));
3435 addr = core_if->host_if->hprt0;
3436 DWC_DEBUGPL(DBG_CIL,"HPRT0 @0x%08X : 0x%08X\n", (uint32_t) addr,
3437 dwc_read_reg32(addr));
3439 for (i = 0; i < core_if->core_params->host_channels; i++) {
3440 DWC_DEBUGPL(DBG_CIL,"Host Channel %d Specific Registers\n", i);
3441 addr = &core_if->host_if->hc_regs[i]->hcchar;
3442 DWC_DEBUGPL(DBG_CIL,"HCCHAR @0x%08X : 0x%08X\n", (uint32_t) addr,
3443 dwc_read_reg32(addr));
3444 addr = &core_if->host_if->hc_regs[i]->hcsplt;
3445 DWC_DEBUGPL(DBG_CIL,"HCSPLT @0x%08X : 0x%08X\n", (uint32_t) addr,
3446 dwc_read_reg32(addr));
3447 addr = &core_if->host_if->hc_regs[i]->hcint;
3448 DWC_DEBUGPL(DBG_CIL,"HCINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3449 dwc_read_reg32(addr));
3450 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
3451 DWC_DEBUGPL(DBG_CIL,"HCINTMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3452 dwc_read_reg32(addr));
3453 addr = &core_if->host_if->hc_regs[i]->hctsiz;
3454 DWC_DEBUGPL(DBG_CIL,"HCTSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3455 dwc_read_reg32(addr));
3456 addr = &core_if->host_if->hc_regs[i]->hcdma;
3457 DWC_DEBUGPL(DBG_CIL,"HCDMA @0x%08X : 0x%08X\n", (uint32_t) addr,
3458 dwc_read_reg32(addr));
3464 * This function reads the core global registers and prints them
3466 * @param core_if Programming view of DWC_otg controller.
3468 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
3471 volatile uint32_t *addr;
3473 DWC_DEBUGPL(DBG_CIL,"Core Global Registers\n");
3474 addr = &core_if->core_global_regs->gotgctl;
3475 DWC_DEBUGPL(DBG_CIL,"GOTGCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3476 dwc_read_reg32(addr));
3477 addr = &core_if->core_global_regs->gotgint;
3478 DWC_DEBUGPL(DBG_CIL,"GOTGINT @0x%08X : 0x%08X\n", (uint32_t) addr,
3479 dwc_read_reg32(addr));
3480 addr = &core_if->core_global_regs->gahbcfg;
3481 DWC_DEBUGPL(DBG_CIL,"GAHBCFG @0x%08X : 0x%08X\n", (uint32_t) addr,
3482 dwc_read_reg32(addr));
3483 addr = &core_if->core_global_regs->gusbcfg;
3484 DWC_DEBUGPL(DBG_CIL,"GUSBCFG @0x%08X : 0x%08X\n", (uint32_t) addr,
3485 dwc_read_reg32(addr));
3486 addr = &core_if->core_global_regs->grstctl;
3487 DWC_DEBUGPL(DBG_CIL,"GRSTCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3488 dwc_read_reg32(addr));
3489 addr = &core_if->core_global_regs->gintsts;
3490 DWC_DEBUGPL(DBG_CIL,"GINTSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3491 dwc_read_reg32(addr));
3492 addr = &core_if->core_global_regs->gintmsk;
3493 DWC_DEBUGPL(DBG_CIL,"GINTMSK @0x%08X : 0x%08X\n", (uint32_t) addr,
3494 dwc_read_reg32(addr));
3495 addr = &core_if->core_global_regs->grxstsr;
3496 DWC_DEBUGPL(DBG_CIL,"GRXSTSR @0x%08X : 0x%08X\n", (uint32_t) addr,
3497 dwc_read_reg32(addr));
3498 //addr=&core_if->core_global_regs->grxstsp;
3499 //DWC_DEBUGPL(DBG_CIL,"GRXSTSP @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3500 addr = &core_if->core_global_regs->grxfsiz;
3501 DWC_DEBUGPL(DBG_CIL,"GRXFSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3502 dwc_read_reg32(addr));
3503 addr = &core_if->core_global_regs->gnptxfsiz;
3504 DWC_DEBUGPL(DBG_CIL,"GNPTXFSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3505 dwc_read_reg32(addr));
3506 addr = &core_if->core_global_regs->gnptxsts;
3507 DWC_DEBUGPL(DBG_CIL,"GNPTXSTS @0x%08X : 0x%08X\n", (uint32_t) addr,
3508 dwc_read_reg32(addr));
3509 addr = &core_if->core_global_regs->gi2cctl;
3510 DWC_DEBUGPL(DBG_CIL,"GI2CCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3511 dwc_read_reg32(addr));
3512 addr = &core_if->core_global_regs->gpvndctl;
3513 DWC_DEBUGPL(DBG_CIL,"GPVNDCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3514 dwc_read_reg32(addr));
3515 addr = &core_if->core_global_regs->ggpio;
3516 DWC_DEBUGPL(DBG_CIL,"GGPIO @0x%08X : 0x%08X\n", (uint32_t) addr,
3517 dwc_read_reg32(addr));
3518 addr = &core_if->core_global_regs->guid;
3519 DWC_DEBUGPL(DBG_CIL,"GUID @0x%08X : 0x%08X\n", (uint32_t) addr,
3520 dwc_read_reg32(addr));
3521 addr = &core_if->core_global_regs->gsnpsid;
3522 DWC_DEBUGPL(DBG_CIL,"GSNPSID @0x%08X : 0x%08X\n", (uint32_t) addr,
3523 dwc_read_reg32(addr));
3524 addr = &core_if->core_global_regs->ghwcfg1;
3525 DWC_DEBUGPL(DBG_CIL,"GHWCFG1 @0x%08X : 0x%08X\n", (uint32_t) addr,
3526 dwc_read_reg32(addr));
3527 addr = &core_if->core_global_regs->ghwcfg2;
3528 DWC_DEBUGPL(DBG_CIL,"GHWCFG2 @0x%08X : 0x%08X\n", (uint32_t) addr,
3529 dwc_read_reg32(addr));
3530 addr = &core_if->core_global_regs->ghwcfg3;
3531 DWC_DEBUGPL(DBG_CIL,"GHWCFG3 @0x%08X : 0x%08X\n", (uint32_t) addr,
3532 dwc_read_reg32(addr));
3533 addr = &core_if->core_global_regs->ghwcfg4;
3534 DWC_DEBUGPL(DBG_CIL,"GHWCFG4 @0x%08X : 0x%08X\n", (uint32_t) addr,
3535 dwc_read_reg32(addr));
3536 addr = &core_if->core_global_regs->glpmcfg;
3537 DWC_DEBUGPL(DBG_CIL,"GLPMCFG @0x%08X : 0x%08X\n", (uint32_t) addr,
3538 dwc_read_reg32(addr));
3539 addr = &core_if->core_global_regs->hptxfsiz;
3540 DWC_DEBUGPL(DBG_CIL,"HPTXFSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3541 dwc_read_reg32(addr));
3543 for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
3544 addr = &core_if->core_global_regs->dptxfsiz_dieptxf[i];
3545 DWC_DEBUGPL(DBG_CIL,"DPTXFSIZ[%d] @0x%08X : 0x%08X\n", i,
3546 (uint32_t) addr, dwc_read_reg32(addr));
3548 addr = core_if->pcgcctl;
3549 DWC_DEBUGPL(DBG_CIL,"PCGCCTL @0x%08X : 0x%08X\n", (uint32_t) addr,
3550 dwc_read_reg32(addr));
3556 * @param core_if Programming view of DWC_otg controller.
3557 * @param num Tx FIFO to flush.
3559 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
3561 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3562 volatile grstctl_t greset = {.d32 = 0 };
3565 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
3567 greset.b.txfflsh = 1;
3568 greset.b.txfnum = num;
3569 dwc_write_reg32(&global_regs->grstctl, greset.d32);
3572 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3573 if (++count > 10000) {
3574 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
3575 __func__, greset.d32,
3576 dwc_read_reg32(&global_regs->gnptxsts));
3580 } while (greset.b.txfflsh == 1);
3582 /* Wait for 3 PHY Clocks */
3589 * @param core_if Programming view of DWC_otg controller.
3591 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
3593 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3594 volatile grstctl_t greset = {.d32 = 0 };
3597 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
3601 greset.b.rxfflsh = 1;
3602 dwc_write_reg32(&global_regs->grstctl, greset.d32);
3605 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3606 if (++count > 10000) {
3607 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
3612 } while (greset.b.rxfflsh == 1);
3614 /* Wait for 3 PHY Clocks */
3619 * Do core a soft reset of the core. Be careful with this because it
3620 * resets all the internal state machines of the core.
3622 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
3624 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3625 volatile grstctl_t greset = {.d32 = 0 };
3628 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
3629 /* Wait for AHB master IDLE state. */
3632 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3633 if (++count > 100000) {
3634 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
3639 while (greset.b.ahbidle == 0);
3641 /* Core Soft Reset */
3643 greset.b.csftrst = 1;
3644 dwc_write_reg32(&global_regs->grstctl, greset.d32);
3646 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3647 if (++count > 10000) {
3648 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
3649 __func__, greset.d32);
3654 while (greset.b.csftrst == 1);
3656 /* Wait for 3 PHY Clocks */
3657 /* orignal 100ms is too long, change to 1ms, sword */
3661 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
3663 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
3666 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
3668 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
3672 * Register HCD callbacks. The callbacks are used to start and stop
3673 * the HCD for interrupt processing.
3675 * @param core_if Programming view of DWC_otg controller.
3676 * @param cb the HCD callback structure.
3677 * @param p pointer to be passed to callback function (usb_hcd*).
3679 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
3680 dwc_otg_cil_callbacks_t * cb, void *p)
3682 core_if->hcd_cb = cb;
3687 * Register PCD callbacks. The callbacks are used to start and stop
3688 * the PCD for interrupt processing.
3690 * @param core_if Programming view of DWC_otg controller.
3691 * @param cb the PCD callback structure.
3692 * @param p pointer to be passed to callback function (pcd*).
3694 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
3695 dwc_otg_cil_callbacks_t * cb, void *p)
3697 core_if->pcd_cb = cb;
3704 * This function writes isoc data per 1 (micro)frame into tx fifo
3706 * @param core_if Programming view of DWC_otg controller.
3707 * @param ep The EP to start the transfer on.
3710 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3712 dwc_otg_dev_in_ep_regs_t *ep_regs;
3713 dtxfsts_data_t txstatus = {.d32 = 0 };
3717 ep->xfer_len = ep->data_per_frame;
3720 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
3722 len = ep->xfer_len - ep->xfer_count;
3724 if (len > ep->maxpacket) {
3725 len = ep->maxpacket;
3728 dwords = (len + 3) / 4;
3730 /* While there is space in the queue and space in the FIFO and
3731 * More data to tranfer, Write packets to the Tx FIFO */
3733 dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
3734 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
3736 while (txstatus.b.txfspcavail > dwords &&
3737 ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
3738 /* Write the FIFO */
3739 dwc_otg_ep_write_packet(core_if, ep, 0);
3741 len = ep->xfer_len - ep->xfer_count;
3742 if (len > ep->maxpacket) {
3743 len = ep->maxpacket;
3746 dwords = (len + 3) / 4;
3748 dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
3750 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
3756 * This function initializes a descriptor chain for Isochronous transfer
3758 * @param core_if Programming view of DWC_otg controller.
3759 * @param ep The EP to start the transfer on.
3762 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
3765 deptsiz_data_t deptsiz = {.d32 = 0 };
3766 depctl_data_t depctl = {.d32 = 0 };
3767 dsts_data_t dsts = {.d32 = 0 };
3768 volatile uint32_t *addr;
3771 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3773 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3776 ep->xfer_len = ep->data_per_frame;
3778 ep->xfer_buff = ep->cur_pkt_addr;
3779 ep->dma_addr = ep->cur_pkt_dma_addr;
3782 /* Program the transfer size and packet count
3783 * as follows: xfersize = N * maxpacket +
3784 * short_packet pktcnt = N + (short_packet
3787 deptsiz.b.xfersize = ep->xfer_len;
3789 (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
3790 deptsiz.b.mc = deptsiz.b.pktcnt;
3791 dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
3794 /* Write the DMA register */
3795 if (core_if->dma_enable) {
3797 (core_if->dev_if->in_ep_regs[ep->num]->
3798 diepdma), (uint32_t) ep->dma_addr);
3802 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
3803 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
3805 dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
3806 doeptsiz, deptsiz.d32);
3808 if (core_if->dma_enable) {
3810 (core_if->dev_if->out_ep_regs[ep->num]->
3811 doepdma), (uint32_t) ep->dma_addr);
3815 /** Enable endpoint, clear nak */
3818 if (ep->bInterval == 1) {
3820 dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
3821 ep->next_frame = dsts.b.soffn + ep->bInterval;
3823 if (ep->next_frame & 0x1) {
3824 depctl.b.setd1pid = 1;
3826 depctl.b.setd0pid = 1;
3829 ep->next_frame += ep->bInterval;
3831 if (ep->next_frame & 0x1) {
3832 depctl.b.setd1pid = 1;
3834 depctl.b.setd0pid = 1;
3840 dwc_modify_reg32(addr, 0, depctl.d32);
3841 depctl.d32 = dwc_read_reg32(addr);
3843 if (ep->is_in && core_if->dma_enable == 0) {
3844 write_isoc_frame_data(core_if, ep);
3848 #endif /* DWC_EN_ISOC */
3850 static void dwc_otg_set_uninitialized(int32_t * p, int size)
3853 for (i = 0; i < size; i++) {
3858 static int dwc_otg_param_initialized(int32_t val)
3863 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
3866 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
3867 if (!core_if->core_params) {
3868 return -DWC_E_NO_MEMORY;
3870 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
3871 sizeof(*core_if->core_params) /
3873 DWC_DEBUGPL(DBG_CIL,"Setting default values for core params\n");
3874 dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
3875 dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
3876 dwc_otg_set_param_dma_desc_enable(core_if,
3877 dwc_param_dma_desc_enable_default);
3878 dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
3879 dwc_otg_set_param_dma_burst_size(core_if,
3880 dwc_param_dma_burst_size_default);
3881 dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
3882 dwc_param_host_support_fs_ls_low_power_default);
3883 dwc_otg_set_param_enable_dynamic_fifo(core_if,
3884 dwc_param_enable_dynamic_fifo_default);
3885 dwc_otg_set_param_data_fifo_size(core_if,
3886 dwc_param_data_fifo_size_default);
3887 dwc_otg_set_param_dev_rx_fifo_size(core_if,
3888 dwc_param_dev_rx_fifo_size_default);
3889 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
3890 dwc_param_dev_nperio_tx_fifo_size_default);
3891 dwc_otg_set_param_host_rx_fifo_size(core_if,
3892 dwc_param_host_rx_fifo_size_default);
3893 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
3894 dwc_param_host_nperio_tx_fifo_size_default);
3895 dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
3896 dwc_param_host_perio_tx_fifo_size_default);
3897 dwc_otg_set_param_max_transfer_size(core_if,
3898 dwc_param_max_transfer_size_default);
3899 dwc_otg_set_param_max_packet_count(core_if,
3900 dwc_param_max_packet_count_default);
3901 dwc_otg_set_param_host_channels(core_if,
3902 dwc_param_host_channels_default);
3903 dwc_otg_set_param_dev_endpoints(core_if,
3904 dwc_param_dev_endpoints_default);
3905 dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
3906 dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
3907 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
3908 dwc_param_host_ls_low_power_phy_clk_default);
3909 dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
3910 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
3911 dwc_param_phy_ulpi_ext_vbus_default);
3912 dwc_otg_set_param_phy_utmi_width(core_if,
3913 dwc_param_phy_utmi_width_default);
3914 dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
3915 dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
3916 dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
3917 dwc_otg_set_param_en_multiple_tx_fifo(core_if,
3918 dwc_param_en_multiple_tx_fifo_default);
3919 for (i = 0; i < 15; i++) {
3920 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
3921 dwc_param_dev_perio_tx_fifo_size_default,
3925 for (i = 0; i < 15; i++) {
3926 dwc_otg_set_param_dev_tx_fifo_size(core_if,
3927 dwc_param_dev_tx_fifo_size_default,
3930 dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
3931 dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
3932 dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
3933 dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
3934 dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
3935 dwc_otg_set_param_tx_thr_length(core_if,
3936 dwc_param_tx_thr_length_default);
3937 dwc_otg_set_param_rx_thr_length(core_if,
3938 dwc_param_rx_thr_length_default);
3939 dwc_otg_set_param_ahb_thr_ratio(core_if, dwc_param_ahb_thr_ratio_default);
3943 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
3945 return core_if->dma_enable;
3948 /* Checks if the parameter is outside of its valid range of values */
3949 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
3950 (((_param_) < (_low_)) || \
3951 ((_param_) > (_high_)))
3953 /* Parameter access functions */
3954 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
3958 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
3959 DWC_WARN("Wrong value for otg_cap parameter\n");
3960 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
3961 retval = -DWC_E_INVALID;
3967 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
3968 if (core_if->hwcfg2.b.op_mode !=
3969 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3972 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
3973 if ((core_if->hwcfg2.b.op_mode !=
3974 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3975 && (core_if->hwcfg2.b.op_mode !=
3976 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
3977 && (core_if->hwcfg2.b.op_mode !=
3978 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
3979 && (core_if->hwcfg2.b.op_mode !=
3980 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
3984 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
3989 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
3991 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
3995 (((core_if->hwcfg2.b.op_mode ==
3996 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3997 || (core_if->hwcfg2.b.op_mode ==
3998 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
3999 || (core_if->hwcfg2.b.op_mode ==
4000 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
4001 || (core_if->hwcfg2.b.op_mode ==
4002 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
4003 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
4004 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
4005 retval = -DWC_E_INVALID;
4008 core_if->core_params->otg_cap = val;
4013 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
4015 return core_if->core_params->otg_cap;
4018 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
4020 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4021 DWC_WARN("Wrong value for opt parameter\n");
4022 return -DWC_E_INVALID;
4024 core_if->core_params->opt = val;
4028 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
4030 return core_if->core_params->opt;
4033 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
4036 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4037 DWC_WARN("Wrong value for dma enable\n");
4038 return -DWC_E_INVALID;
4041 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
4042 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
4044 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
4048 retval = -DWC_E_INVALID;
4051 core_if->core_params->dma_enable = val;
4053 dwc_otg_set_param_dma_desc_enable(core_if, 0);
4058 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
4060 return core_if->core_params->dma_enable;
4063 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
4066 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4067 DWC_WARN("Wrong value for dma_enable\n");
4068 DWC_WARN("dma_desc_enable must be 0 or 1\n");
4069 return -DWC_E_INVALID;
4073 && ((dwc_otg_get_param_dma_enable(core_if) == 0)
4074 || (core_if->hwcfg4.b.desc_dma == 0))) {
4075 if (dwc_otg_param_initialized
4076 (core_if->core_params->dma_desc_enable)) {
4078 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
4082 retval = -DWC_E_INVALID;
4084 core_if->core_params->dma_desc_enable = val;
4088 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
4090 return core_if->core_params->dma_desc_enable;
4093 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
4096 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4097 DWC_WARN("Wrong value for host_support_fs_low_power\n");
4098 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
4099 return -DWC_E_INVALID;
4101 core_if->core_params->host_support_fs_ls_low_power = val;
4105 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
4108 return core_if->core_params->host_support_fs_ls_low_power;
4111 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
4115 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4116 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
4117 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
4118 return -DWC_E_INVALID;
4121 if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
4122 if (dwc_otg_param_initialized
4123 (core_if->core_params->enable_dynamic_fifo)) {
4125 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
4129 retval = -DWC_E_INVALID;
4131 core_if->core_params->enable_dynamic_fifo = val;
4135 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
4137 return core_if->core_params->enable_dynamic_fifo;
4140 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
4143 if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
4144 DWC_WARN("Wrong value for data_fifo_size\n");
4145 DWC_WARN("data_fifo_size must be 32-32768\n");
4146 return -DWC_E_INVALID;
4149 if (val > core_if->hwcfg3.b.dfifo_depth) {
4150 if (dwc_otg_param_initialized
4151 (core_if->core_params->data_fifo_size)) {
4153 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
4156 val = core_if->hwcfg3.b.dfifo_depth;
4157 retval = -DWC_E_INVALID;
4160 core_if->core_params->data_fifo_size = val;
4164 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
4166 return core_if->core_params->data_fifo_size;
4169 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
4172 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4173 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
4174 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
4175 return -DWC_E_INVALID;
4178 if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
4179 if(dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
4180 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
4182 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
4183 retval = -DWC_E_INVALID;
4186 core_if->core_params->dev_rx_fifo_size = val;
4190 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
4192 return core_if->core_params->dev_rx_fifo_size;
4195 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4200 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4201 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
4202 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
4203 return -DWC_E_INVALID;
4206 if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
4207 if (dwc_otg_param_initialized
4208 (core_if->core_params->dev_nperio_tx_fifo_size)) {
4210 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
4214 (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
4216 retval = -DWC_E_INVALID;
4219 core_if->core_params->dev_nperio_tx_fifo_size = val;
4223 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4225 return core_if->core_params->dev_nperio_tx_fifo_size;
4228 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
4233 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4234 DWC_WARN("Wrong value for host_rx_fifo_size\n");
4235 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
4236 return -DWC_E_INVALID;
4239 if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
4240 if (dwc_otg_param_initialized
4241 (core_if->core_params->host_rx_fifo_size)) {
4243 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
4246 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
4247 retval = -DWC_E_INVALID;
4250 core_if->core_params->host_rx_fifo_size = val;
4255 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
4257 return core_if->core_params->host_rx_fifo_size;
4260 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4265 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4266 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
4267 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
4268 return -DWC_E_INVALID;
4271 if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
4272 if (dwc_otg_param_initialized
4273 (core_if->core_params->host_nperio_tx_fifo_size)) {
4275 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
4279 (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
4281 retval = -DWC_E_INVALID;
4284 core_if->core_params->host_nperio_tx_fifo_size = val;
4288 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4290 return core_if->core_params->host_nperio_tx_fifo_size;
4293 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4297 if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4298 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
4299 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
4300 return -DWC_E_INVALID;
4304 ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))) {
4305 if (dwc_otg_param_initialized
4306 (core_if->core_params->host_perio_tx_fifo_size)) {
4308 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
4312 (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >>
4314 retval = -DWC_E_INVALID;
4317 core_if->core_params->host_perio_tx_fifo_size = val;
4321 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4323 return core_if->core_params->host_perio_tx_fifo_size;
4326 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
4331 if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
4332 DWC_WARN("Wrong value for max_transfer_size\n");
4333 DWC_WARN("max_transfer_size must be 2047-524288\n");
4334 return -DWC_E_INVALID;
4337 if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
4338 if (dwc_otg_param_initialized
4339 (core_if->core_params->max_transfer_size)) {
4341 ("%d invalid for max_transfer_size. Check HW configuration.\n",
4345 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
4347 retval = -DWC_E_INVALID;
4350 core_if->core_params->max_transfer_size = val;
4354 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
4356 return core_if->core_params->max_transfer_size;
4359 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
4363 if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
4364 DWC_WARN("Wrong value for max_packet_count\n");
4365 DWC_WARN("max_packet_count must be 15-511\n");
4366 return -DWC_E_INVALID;
4369 if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
4370 if (dwc_otg_param_initialized
4371 (core_if->core_params->max_packet_count)) {
4373 ("%d invalid for max_packet_count. Check HW configuration.\n",
4377 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
4378 retval = -DWC_E_INVALID;
4381 core_if->core_params->max_packet_count = val;
4385 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
4387 return core_if->core_params->max_packet_count;
4390 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
4394 if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
4395 DWC_WARN("Wrong value for host_channels\n");
4396 DWC_WARN("host_channels must be 1-16\n");
4397 return -DWC_E_INVALID;
4400 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
4401 if (dwc_otg_param_initialized
4402 (core_if->core_params->host_channels)) {
4404 ("%d invalid for host_channels. Check HW configurations.\n",
4407 val = (core_if->hwcfg2.b.num_host_chan + 1);
4408 retval = -DWC_E_INVALID;
4411 core_if->core_params->host_channels = val;
4415 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
4417 return core_if->core_params->host_channels;
4420 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
4424 if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
4425 DWC_WARN("Wrong value for dev_endpoints\n");
4426 DWC_WARN("dev_endpoints must be 1-15\n");
4427 return -DWC_E_INVALID;
4430 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
4431 if (dwc_otg_param_initialized
4432 (core_if->core_params->dev_endpoints)) {
4434 ("%d invalid for dev_endpoints. Check HW configurations.\n",
4437 val = core_if->hwcfg2.b.num_dev_ep;
4438 retval = -DWC_E_INVALID;
4441 core_if->core_params->dev_endpoints = val;
4445 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
4447 return core_if->core_params->dev_endpoints;
4450 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
4455 if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
4456 DWC_WARN("Wrong value for phy_type\n");
4457 DWC_WARN("phy_type must be 0,1 or 2\n");
4458 return -DWC_E_INVALID;
4460 #ifndef NO_FS_PHY_HW_CHECKS
4461 if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
4462 ((core_if->hwcfg2.b.hs_phy_type == 1) ||
4463 (core_if->hwcfg2.b.hs_phy_type == 3))) {
4465 } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
4466 ((core_if->hwcfg2.b.hs_phy_type == 2) ||
4467 (core_if->hwcfg2.b.hs_phy_type == 3))) {
4469 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
4470 (core_if->hwcfg2.b.fs_phy_type == 1)) {
4474 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
4476 ("%d invalid for phy_type. Check HW configurations.\n",
4479 if (core_if->hwcfg2.b.hs_phy_type) {
4480 if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
4481 (core_if->hwcfg2.b.hs_phy_type == 1)) {
4482 val = DWC_PHY_TYPE_PARAM_UTMI;
4484 val = DWC_PHY_TYPE_PARAM_ULPI;
4487 retval = -DWC_E_INVALID;
4490 core_if->core_params->phy_type = val;
4494 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
4496 return core_if->core_params->phy_type;
4499 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
4502 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4503 DWC_WARN("Wrong value for speed parameter\n");
4504 DWC_WARN("max_speed parameter must be 0 or 1\n");
4505 return -DWC_E_INVALID;
4508 && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
4509 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
4511 ("%d invalid for speed paremter. Check HW configuration.\n",
4515 (dwc_otg_get_param_phy_type(core_if) ==
4516 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
4517 retval = -DWC_E_INVALID;
4519 core_if->core_params->speed = val;
4523 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
4525 return core_if->core_params->speed;
4528 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
4533 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4535 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
4536 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
4537 return -DWC_E_INVALID;
4540 if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
4541 && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
4542 if(dwc_otg_param_initialized(core_if->core_params->host_ls_low_power_phy_clk)) {
4543 DWC_ERROR("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
4547 (dwc_otg_get_param_phy_type(core_if) ==
4548 DWC_PHY_TYPE_PARAM_FS) ?
4549 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
4550 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
4551 retval = -DWC_E_INVALID;
4554 core_if->core_params->host_ls_low_power_phy_clk = val;
4558 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
4560 return core_if->core_params->host_ls_low_power_phy_clk;
4563 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
4565 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4566 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
4567 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
4568 return -DWC_E_INVALID;
4571 core_if->core_params->phy_ulpi_ddr = val;
4575 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
4577 return core_if->core_params->phy_ulpi_ddr;
4580 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
4583 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4584 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
4585 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
4586 return -DWC_E_INVALID;
4589 core_if->core_params->phy_ulpi_ext_vbus = val;
4593 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
4595 return core_if->core_params->phy_ulpi_ext_vbus;
4598 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
4600 if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
4601 DWC_WARN("Wrong valaue for phy_utmi_width\n");
4602 DWC_WARN("phy_utmi_width must be 8 or 16\n");
4603 return -DWC_E_INVALID;
4606 core_if->core_params->phy_utmi_width = val;
4610 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
4612 return core_if->core_params->phy_utmi_width;
4615 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
4617 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4618 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
4619 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
4620 return -DWC_E_INVALID;
4623 core_if->core_params->ulpi_fs_ls = val;
4627 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
4629 return core_if->core_params->ulpi_fs_ls;
4632 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
4634 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4635 DWC_WARN("Wrong valaue for ts_dline\n");
4636 DWC_WARN("ts_dline must be 0 or 1\n");
4637 return -DWC_E_INVALID;
4640 core_if->core_params->ts_dline = val;
4644 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
4646 return core_if->core_params->ts_dline;
4649 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
4652 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4653 DWC_WARN("Wrong valaue for i2c_enable\n");
4654 DWC_WARN("i2c_enable must be 0 or 1\n");
4655 return -DWC_E_INVALID;
4657 #ifndef NO_FS_PHY_HW_CHECK
4658 if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
4659 if(dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
4660 DWC_ERROR("%d invalid for i2c_enable. Check HW configuration.\n",
4664 retval = -DWC_E_INVALID;
4668 core_if->core_params->i2c_enable = val;
4672 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
4674 return core_if->core_params->i2c_enable;
4677 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4678 int32_t val, int fifo_num)
4682 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
4683 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
4684 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
4685 return -DWC_E_INVALID;
4688 if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
4689 if(dwc_otg_param_initialized(core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
4690 DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
4693 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
4694 retval = -DWC_E_INVALID;
4697 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
4701 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4704 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
4707 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
4711 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4712 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
4713 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
4714 return -DWC_E_INVALID;
4717 if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
4718 if(dwc_otg_param_initialized(core_if->core_params->en_multiple_tx_fifo)) {
4719 DWC_ERROR("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
4723 retval = -DWC_E_INVALID;
4726 core_if->core_params->en_multiple_tx_fifo = val;
4730 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
4732 return core_if->core_params->en_multiple_tx_fifo;
4735 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
4740 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
4741 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
4742 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
4743 return -DWC_E_INVALID;
4746 if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
4747 if(dwc_otg_param_initialized(core_if->core_params->dev_tx_fifo_size[fifo_num])) {
4748 DWC_ERROR("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
4751 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
4752 retval = -DWC_E_INVALID;
4755 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
4759 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
4762 return core_if->core_params->dev_tx_fifo_size[fifo_num];
4765 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
4769 if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
4770 DWC_WARN("Wrong value for thr_ctl\n");
4771 DWC_WARN("thr_ctl must be 0-7\n");
4772 return -DWC_E_INVALID;
4776 (!dwc_otg_get_param_dma_enable(core_if) ||
4777 !core_if->hwcfg4.b.ded_fifo_en)) {
4778 if(dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
4779 DWC_ERROR("%d invalid for parameter thr_ctl. Check HW configuration.\n",
4783 retval = -DWC_E_INVALID;
4786 core_if->core_params->thr_ctl = val;
4790 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
4792 return core_if->core_params->thr_ctl;
4795 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
4799 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4800 DWC_WARN("Wrong value for lpm_enable\n");
4801 DWC_WARN("lpm_enable must be 0 or 1\n");
4802 return -DWC_E_INVALID;
4805 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
4806 if(dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
4807 DWC_ERROR("%d invalid for parameter lpm_enable. Check HW configuration.\n",
4811 retval = -DWC_E_INVALID;
4814 core_if->core_params->lpm_enable = val;
4818 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
4820 return core_if->core_params->lpm_enable;
4823 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
4825 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
4826 DWC_WARN("Wrong valaue for tx_thr_length\n");
4827 DWC_WARN("tx_thr_length must be 8 - 128\n");
4828 return -DWC_E_INVALID;
4831 core_if->core_params->tx_thr_length = val;
4835 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
4837 return core_if->core_params->tx_thr_length;
4840 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
4842 if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
4843 DWC_WARN("Wrong valaue for rx_thr_length\n");
4844 DWC_WARN("rx_thr_length must be 8 - 128\n");
4845 return -DWC_E_INVALID;
4848 core_if->core_params->rx_thr_length = val;
4852 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
4854 return core_if->core_params->rx_thr_length;
4857 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
4859 if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
4860 DWC_OTG_PARAM_TEST(val, 4, 4) &&
4861 DWC_OTG_PARAM_TEST(val, 8, 8) &&
4862 DWC_OTG_PARAM_TEST(val, 16, 16) &&
4863 DWC_OTG_PARAM_TEST(val, 32, 32) &&
4864 DWC_OTG_PARAM_TEST(val, 64, 64) &&
4865 DWC_OTG_PARAM_TEST(val, 128, 128) &&
4866 DWC_OTG_PARAM_TEST(val, 256, 256)) {
4867 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
4868 return -DWC_E_INVALID;
4870 core_if->core_params->dma_burst_size = val;
4874 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
4876 return core_if->core_params->dma_burst_size;
4879 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
4882 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4883 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
4884 return -DWC_E_INVALID;
4886 if (val && (core_if->snpsid < 0x4F54272A)) {
4887 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
4888 DWC_ERROR("%d invalid for parameter pti_enable. Check HW configuration.\n",
4891 retval = -DWC_E_INVALID;
4894 core_if->core_params->pti_enable = val;
4898 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
4900 return core_if->core_params->pti_enable;
4903 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
4906 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4907 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
4908 return -DWC_E_INVALID;
4910 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
4911 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
4912 DWC_ERROR("%d invalid for parameter mpi_enable. Check HW configuration.\n",
4915 retval = -DWC_E_INVALID;
4918 core_if->core_params->mpi_enable = val;
4922 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
4924 return core_if->core_params->mpi_enable;
4927 extern int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if,
4931 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4932 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
4933 DWC_WARN("ic_usb_cap must be 0 or 1\n");
4934 return -DWC_E_INVALID;
4937 if (val && (core_if->hwcfg3.b.otg_enable_ic_usb == 0)) {
4938 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
4939 DWC_ERROR("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
4942 retval = -DWC_E_INVALID;
4945 core_if->core_params->ic_usb_cap = val;
4948 extern int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
4950 return core_if->core_params->ic_usb_cap;
4953 extern int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
4958 if(DWC_OTG_PARAM_TEST(val, 0, 3)) {
4959 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
4960 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
4961 return -DWC_E_INVALID;
4964 if(val && (core_if->snpsid < 0x4F54281A || !dwc_otg_get_param_thr_ctl(core_if))) {
4966 } else if(val && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) < 4)) {
4970 if(dwc_otg_param_initialized(core_if->core_params->ahb_thr_ratio)) {
4971 DWC_ERROR("%d invalid for parameter ahb_thr_ratio. Chack HW configuration.\n", val);
4973 retval = -DWC_E_INVALID;
4977 core_if->core_params->ahb_thr_ratio = val;
4980 extern int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
4982 return core_if->core_params->ahb_thr_ratio;
4986 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
4988 gotgctl_data_t otgctl;
4989 otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
4990 return otgctl.b.hstnegscs;
4993 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
4995 gotgctl_data_t otgctl;
4996 otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
4997 return otgctl.b.sesreqscs;
5000 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
5002 gotgctl_data_t otgctl;
5003 otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5004 otgctl.b.hnpreq = val;
5005 dwc_write_reg32(&core_if->core_global_regs->gotgctl, otgctl.d32);
5008 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
5010 return core_if->snpsid;
5013 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
5015 gotgctl_data_t otgctl;
5016 otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5017 return otgctl.b.currmod;
5020 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
5022 gusbcfg_data_t usbcfg;
5023 usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5024 return usbcfg.b.hnpcap;
5027 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
5029 gusbcfg_data_t usbcfg;
5030 usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5031 usbcfg.b.hnpcap = val;
5032 dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
5035 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
5037 gusbcfg_data_t usbcfg;
5038 usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5039 return usbcfg.b.srpcap;
5042 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
5044 gusbcfg_data_t usbcfg;
5045 usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5046 usbcfg.b.srpcap = val;
5047 dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
5050 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
5053 dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
5054 return dcfg.b.devspd;
5057 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
5060 dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
5061 dcfg.b.devspd = val;
5062 dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
5065 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
5068 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5069 return hprt0.b.prtconnsts;
5072 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
5075 dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
5076 return dsts.b.enumspd;
5079 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
5082 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5083 return hprt0.b.prtpwr;
5087 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
5090 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5091 hprt0.b.prtpwr = val;
5092 dwc_write_reg32(core_if->host_if->hprt0, val);
5095 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
5098 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5099 return hprt0.b.prtsusp;
5103 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
5106 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5107 hprt0.b.prtsusp = val;
5108 dwc_write_reg32(core_if->host_if->hprt0, val);
5111 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
5114 hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5115 hprt0.b.prtres = val;
5116 dwc_write_reg32(core_if->host_if->hprt0, val);
5119 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
5122 dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
5123 return dctl.b.rmtwkupsig;
5126 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
5128 glpmcfg_data_t lpmcfg;
5129 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5132 ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
5133 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
5134 core_if->lx_state, lpmcfg.b.prt_sleep_sts);
5136 return lpmcfg.b.prt_sleep_sts;
5139 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
5141 glpmcfg_data_t lpmcfg;
5142 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5143 return lpmcfg.b.rem_wkup_en;
5146 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
5148 glpmcfg_data_t lpmcfg;
5149 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5150 return lpmcfg.b.appl_resp;
5153 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
5155 glpmcfg_data_t lpmcfg;
5156 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5157 lpmcfg.b.appl_resp = val;
5158 dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5161 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
5163 glpmcfg_data_t lpmcfg;
5164 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5165 return lpmcfg.b.hsic_connect;
5168 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
5170 glpmcfg_data_t lpmcfg;
5171 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5172 lpmcfg.b.hsic_connect = val;
5173 dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5176 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
5178 glpmcfg_data_t lpmcfg;
5179 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5180 return lpmcfg.b.inv_sel_hsic;
5184 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
5186 glpmcfg_data_t lpmcfg;
5187 lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5188 lpmcfg.b.inv_sel_hsic = val;
5189 dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5192 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
5194 return dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5197 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
5199 dwc_write_reg32(&core_if->core_global_regs->gotgctl, val);
5202 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
5204 return dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5207 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
5209 dwc_write_reg32(&core_if->core_global_regs->gusbcfg, val);
5212 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
5214 return dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
5217 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
5219 dwc_write_reg32(&core_if->core_global_regs->grxfsiz, val);
5222 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
5224 return dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz);
5227 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
5229 dwc_write_reg32(&core_if->core_global_regs->gnptxfsiz, val);
5232 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
5234 return dwc_read_reg32(&core_if->core_global_regs->gpvndctl);
5237 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
5239 dwc_write_reg32(&core_if->core_global_regs->gpvndctl, val);
5242 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
5244 return dwc_read_reg32(&core_if->core_global_regs->ggpio);
5247 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
5249 dwc_write_reg32(&core_if->core_global_regs->ggpio, val);
5252 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
5254 return dwc_read_reg32(core_if->host_if->hprt0);
5258 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
5260 dwc_write_reg32(core_if->host_if->hprt0, val);
5263 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
5265 return dwc_read_reg32(&core_if->core_global_regs->guid);
5268 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
5270 dwc_write_reg32(&core_if->core_global_regs->guid, val);
5273 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
5275 return dwc_read_reg32(&core_if->core_global_regs->hptxfsiz);