1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9 * otherwise expressly agreed to in writing between Synopsys and you.
11 * The Software IS NOT an item of Licensed Software or Licensed Product under
12 * any End User Software License Agreement or Agreement for Licensed Product
13 * with Synopsys or any supplement thereto. You are permitted to use and
14 * redistribute this Software in source and binary forms, with or without
15 * modification, provided that redistributions of source code must retain this
16 * notice. You may not view, use, disclose, copy or distribute this file or
17 * any information contained herein except pursuant to this license grant from
18 * Synopsys. If you do not agree with this notice, including the disclaimer
19 * below, then you are not authorized to use the Software.
21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
32 * ========================================================================== */
36 * The Core Interface Layer provides basic services for accessing and
37 * managing the DWC_otg hardware. These services are used by both the
38 * Host Controller Driver and the Peripheral Controller Driver.
40 * The CIL manages the memory map for the core so that the HCD and PCD
41 * don't have to do this separately. It also handles basic tasks like
42 * reading/writing the registers and data FIFOs in the controller.
43 * Some of the data access functions provide encapsulation of several
44 * operations required to perform a task, such as writing multiple
45 * registers to start a transfer. Finally, the CIL performs basic
46 * services that are not specific to either the host or device modes
47 * of operation. These services include management of the OTG Host
48 * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
49 * Diagnostic API is also provided to allow testing of the controller
52 * The Core Interface Layer has the following requirements:
53 * - Provides basic controller operations.
54 * - Minimal use of OS services.
55 * - The OS services used will be abstracted by using inline functions
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
64 static int dwc_otg_setup_params(dwc_otg_core_if_t
* core_if
);
67 * This function is called to initialize the DWC_otg CSR data
68 * structures. The register addresses in the device and host
69 * structures are initialized from the base address supplied by the
70 * caller. The calling function must make the OS calls to get the
71 * base address of the DWC_otg controller registers. The core_params
72 * argument holds the parameters that specify how the core should be
75 * @param reg_base_addr Base address of DWC_otg core registers
78 dwc_otg_core_if_t
*dwc_otg_cil_init(const uint32_t * reg_base_addr
)
80 dwc_otg_core_if_t
*core_if
= 0;
81 dwc_otg_dev_if_t
*dev_if
= 0;
82 dwc_otg_host_if_t
*host_if
= 0;
83 uint8_t *reg_base
= (uint8_t *) reg_base_addr
;
86 DWC_DEBUGPL(DBG_CILV
, "%s(%p)\n", __func__
, reg_base_addr
);
88 core_if
= DWC_ALLOC(sizeof(dwc_otg_core_if_t
));
90 if (core_if
== NULL
) {
92 "Allocation of dwc_otg_core_if_t failed\n");
95 core_if
->core_global_regs
= (dwc_otg_core_global_regs_t
*) reg_base
;
98 * Allocate the Device Mode structures.
100 dev_if
= DWC_ALLOC(sizeof(dwc_otg_dev_if_t
));
102 if (dev_if
== NULL
) {
103 DWC_DEBUGPL(DBG_CIL
, "Allocation of dwc_otg_dev_if_t failed\n");
108 dev_if
->dev_global_regs
=
109 (dwc_otg_device_global_regs_t
*) (reg_base
+
110 DWC_DEV_GLOBAL_REG_OFFSET
);
112 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
113 dev_if
->in_ep_regs
[i
] = (dwc_otg_dev_in_ep_regs_t
*)
114 (reg_base
+ DWC_DEV_IN_EP_REG_OFFSET
+
115 (i
* DWC_EP_REG_OFFSET
));
117 dev_if
->out_ep_regs
[i
] = (dwc_otg_dev_out_ep_regs_t
*)
118 (reg_base
+ DWC_DEV_OUT_EP_REG_OFFSET
+
119 (i
* DWC_EP_REG_OFFSET
));
120 DWC_DEBUGPL(DBG_CILV
, "in_ep_regs[%d]->diepctl=%p\n",
121 i
, &dev_if
->in_ep_regs
[i
]->diepctl
);
122 DWC_DEBUGPL(DBG_CILV
, "out_ep_regs[%d]->doepctl=%p\n",
123 i
, &dev_if
->out_ep_regs
[i
]->doepctl
);
126 dev_if
->speed
= 0; // unknown
128 core_if
->dev_if
= dev_if
;
131 * Allocate the Host Mode structures.
133 host_if
= DWC_ALLOC(sizeof(dwc_otg_host_if_t
));
135 if (host_if
== NULL
) {
137 "Allocation of dwc_otg_host_if_t failed\n");
143 host_if
->host_global_regs
= (dwc_otg_host_global_regs_t
*)
144 (reg_base
+ DWC_OTG_HOST_GLOBAL_REG_OFFSET
);
147 (uint32_t *) (reg_base
+ DWC_OTG_HOST_PORT_REGS_OFFSET
);
149 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
150 host_if
->hc_regs
[i
] = (dwc_otg_hc_regs_t
*)
151 (reg_base
+ DWC_OTG_HOST_CHAN_REGS_OFFSET
+
152 (i
* DWC_OTG_CHAN_REGS_OFFSET
));
153 DWC_DEBUGPL(DBG_CILV
, "hc_reg[%d]->hcchar=%p\n",
154 i
, &host_if
->hc_regs
[i
]->hcchar
);
157 host_if
->num_host_channels
= MAX_EPS_CHANNELS
;
158 core_if
->host_if
= host_if
;
160 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
161 core_if
->data_fifo
[i
] =
162 (uint32_t *) (reg_base
+ DWC_OTG_DATA_FIFO_OFFSET
+
163 (i
* DWC_OTG_DATA_FIFO_SIZE
));
164 DWC_DEBUGPL(DBG_CILV
, "data_fifo[%d]=0x%08lx\n",
165 i
, (unsigned long)core_if
->data_fifo
[i
]);
168 core_if
->pcgcctl
= (uint32_t *) (reg_base
+ DWC_OTG_PCGCCTL_OFFSET
);
170 /* Initiate lx_state to L3 disconnected state */
171 core_if
->lx_state
= DWC_OTG_L3
;
173 * Store the contents of the hardware configuration registers here for
176 core_if
->hwcfg1
.d32
=
177 DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg1
);
178 core_if
->hwcfg2
.d32
=
179 DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg2
);
180 core_if
->hwcfg3
.d32
=
181 DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg3
);
182 core_if
->hwcfg4
.d32
=
183 DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg4
);
185 /* Force host mode to get HPTXFSIZ exact power on value */
187 gusbcfg_data_t gusbcfg
= {.d32
= 0 };
188 gusbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
189 gusbcfg
.b
.force_host_mode
= 1;
190 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, gusbcfg
.d32
);
192 core_if
->hptxfsiz
.d32
=
193 DWC_READ_REG32(&core_if
->core_global_regs
->hptxfsiz
);
194 gusbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
195 gusbcfg
.b
.force_host_mode
= 1;
196 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, gusbcfg
.d32
);
200 DWC_DEBUGPL(DBG_CILV
, "hwcfg1=%08x\n", core_if
->hwcfg1
.d32
);
201 DWC_DEBUGPL(DBG_CILV
, "hwcfg2=%08x\n", core_if
->hwcfg2
.d32
);
202 DWC_DEBUGPL(DBG_CILV
, "hwcfg3=%08x\n", core_if
->hwcfg3
.d32
);
203 DWC_DEBUGPL(DBG_CILV
, "hwcfg4=%08x\n", core_if
->hwcfg4
.d32
);
206 DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hcfg
);
208 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
210 DWC_DEBUGPL(DBG_CILV
, "hcfg=%08x\n", core_if
->hcfg
.d32
);
211 DWC_DEBUGPL(DBG_CILV
, "dcfg=%08x\n", core_if
->dcfg
.d32
);
213 DWC_DEBUGPL(DBG_CILV
, "op_mode=%0x\n", core_if
->hwcfg2
.b
.op_mode
);
214 DWC_DEBUGPL(DBG_CILV
, "arch=%0x\n", core_if
->hwcfg2
.b
.architecture
);
215 DWC_DEBUGPL(DBG_CILV
, "num_dev_ep=%d\n", core_if
->hwcfg2
.b
.num_dev_ep
);
216 DWC_DEBUGPL(DBG_CILV
, "num_host_chan=%d\n",
217 core_if
->hwcfg2
.b
.num_host_chan
);
218 DWC_DEBUGPL(DBG_CILV
, "nonperio_tx_q_depth=0x%0x\n",
219 core_if
->hwcfg2
.b
.nonperio_tx_q_depth
);
220 DWC_DEBUGPL(DBG_CILV
, "host_perio_tx_q_depth=0x%0x\n",
221 core_if
->hwcfg2
.b
.host_perio_tx_q_depth
);
222 DWC_DEBUGPL(DBG_CILV
, "dev_token_q_depth=0x%0x\n",
223 core_if
->hwcfg2
.b
.dev_token_q_depth
);
225 DWC_DEBUGPL(DBG_CILV
, "Total FIFO SZ=%d\n",
226 core_if
->hwcfg3
.b
.dfifo_depth
);
227 DWC_DEBUGPL(DBG_CILV
, "xfer_size_cntr_width=%0x\n",
228 core_if
->hwcfg3
.b
.xfer_size_cntr_width
);
231 * Set the SRP sucess bit for FS-I2c
233 core_if
->srp_success
= 0;
234 core_if
->srp_timer_started
= 0;
237 * Create new workqueue and init works
239 core_if
->wq_otg
= DWC_WORKQ_ALLOC("dwc_otg");
240 if (core_if
->wq_otg
== 0) {
241 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
248 core_if
->snpsid
= DWC_READ_REG32(&core_if
->core_global_regs
->gsnpsid
);
250 DWC_PRINTF("Core Release: %x.%x%x%x\n",
251 (core_if
->snpsid
>> 12 & 0xF),
252 (core_if
->snpsid
>> 8 & 0xF),
253 (core_if
->snpsid
>> 4 & 0xF), (core_if
->snpsid
& 0xF));
255 core_if
->wkp_timer
= DWC_TIMER_ALLOC("Wake Up Timer",
256 w_wakeup_detected
, core_if
);
257 if (core_if
->wkp_timer
== 0) {
258 DWC_WARN("DWC_TIMER_ALLOC failed\n");
261 DWC_WORKQ_FREE(core_if
->wq_otg
);
266 if (dwc_otg_setup_params(core_if
)) {
267 DWC_WARN("Error while setting core params\n");
270 core_if
->hibernation_suspend
= 0;
272 /** ADP initialization */
273 dwc_otg_adp_init(core_if
);
279 * This function frees the structures allocated by dwc_otg_cil_init().
281 * @param core_if The core interface pointer returned from
282 * dwc_otg_cil_init().
285 void dwc_otg_cil_remove(dwc_otg_core_if_t
* core_if
)
287 dctl_data_t dctl
= {.d32
= 0 };
288 DWC_DEBUGPL(DBG_CILV
, "%s(%p)\n", __func__
, core_if
);
290 /* Disable all interrupts */
291 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gahbcfg
, 1, 0);
292 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintmsk
, 0);
294 dctl
.b
.sftdiscon
= 1;
295 if (core_if
->snpsid
>= OTG_CORE_REV_3_00a
) {
296 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, 0,
300 if (core_if
->wq_otg
) {
301 DWC_WORKQ_WAIT_WORK_DONE(core_if
->wq_otg
, 500);
302 DWC_WORKQ_FREE(core_if
->wq_otg
);
304 if (core_if
->dev_if
) {
305 DWC_FREE(core_if
->dev_if
);
307 if (core_if
->host_if
) {
308 DWC_FREE(core_if
->host_if
);
311 /** Remove ADP Stuff */
312 dwc_otg_adp_remove(core_if
);
313 if (core_if
->core_params
) {
314 DWC_FREE(core_if
->core_params
);
316 if (core_if
->wkp_timer
) {
317 DWC_TIMER_FREE(core_if
->wkp_timer
);
319 if (core_if
->srp_timer
) {
320 DWC_TIMER_FREE(core_if
->srp_timer
);
326 * This function enables the controller's Global Interrupt in the AHB Config
329 * @param core_if Programming view of DWC_otg controller.
331 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t
* core_if
)
333 gahbcfg_data_t ahbcfg
= {.d32
= 0 };
334 ahbcfg
.b
.glblintrmsk
= 1; /* Enable interrupts */
335 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gahbcfg
, 0, ahbcfg
.d32
);
339 * This function disables the controller's Global Interrupt in the AHB Config
342 * @param core_if Programming view of DWC_otg controller.
344 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t
* core_if
)
346 gahbcfg_data_t ahbcfg
= {.d32
= 0 };
347 ahbcfg
.b
.glblintrmsk
= 1; /* Disable interrupts */
348 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gahbcfg
, ahbcfg
.d32
, 0);
352 * This function initializes the commmon interrupts, used in both
353 * device and host modes.
355 * @param core_if Programming view of the DWC_otg controller
358 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t
* core_if
)
360 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
361 gintmsk_data_t intr_mask
= {.d32
= 0 };
363 /* Clear any pending OTG Interrupts */
364 DWC_WRITE_REG32(&global_regs
->gotgint
, 0xFFFFFFFF);
366 /* Clear any pending interrupts */
367 DWC_WRITE_REG32(&global_regs
->gintsts
, 0xFFFFFFFF);
370 * Enable the interrupts in the GINTMSK.
372 intr_mask
.b
.modemismatch
= 1;
373 intr_mask
.b
.otgintr
= 1;
375 if (!core_if
->dma_enable
) {
376 intr_mask
.b
.rxstsqlvl
= 1;
379 intr_mask
.b
.conidstschng
= 1;
380 intr_mask
.b
.wkupintr
= 1;
381 intr_mask
.b
.disconnect
= 0;
382 intr_mask
.b
.usbsuspend
= 1;
383 intr_mask
.b
.sessreqintr
= 1;
384 #ifdef CONFIG_USB_DWC_OTG_LPM
385 if (core_if
->core_params
->lpm_enable
) {
386 intr_mask
.b
.lpmtranrcvd
= 1;
389 DWC_WRITE_REG32(&global_regs
->gintmsk
, intr_mask
.d32
);
393 * The restore operation is modified to support Synopsys Emulated Powerdown and
394 * Hibernation. This function is for exiting from Device mode hibernation by
395 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
396 * @param core_if Programming view of DWC_otg controller.
397 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
398 * @param reset - indicates whether resume is initiated by Reset.
400 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t
* core_if
,
401 int rem_wakeup
, int reset
)
403 gpwrdn_data_t gpwrdn
= {.d32
= 0 };
404 pcgcctl_data_t pcgcctl
= {.d32
= 0 };
405 dctl_data_t dctl
= {.d32
= 0 };
409 if (!core_if
->hibernation_suspend
) {
410 DWC_PRINTF("Already exited from Hibernation\n");
414 DWC_DEBUGPL(DBG_PCD
, "%s called\n", __FUNCTION__
);
415 /* Switch-on voltage to the core */
416 gpwrdn
.b
.pwrdnswtch
= 1;
417 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
422 gpwrdn
.b
.pwrdnrstn
= 1;
423 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
426 /* Assert Restore signal */
428 gpwrdn
.b
.restore
= 1;
429 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, 0, gpwrdn
.d32
);
432 /* Disable power clamps */
434 gpwrdn
.b
.pwrdnclmp
= 1;
435 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
441 /* Deassert Reset core */
443 gpwrdn
.b
.pwrdnrstn
= 1;
444 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, 0, gpwrdn
.d32
);
447 /* Disable PMU interrupt */
449 gpwrdn
.b
.pmuintsel
= 1;
450 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
452 /* Mask interrupts from gpwrdn */
454 gpwrdn
.b
.connect_det_msk
= 1;
455 gpwrdn
.b
.srp_det_msk
= 1;
456 gpwrdn
.b
.disconn_det_msk
= 1;
457 gpwrdn
.b
.rst_det_msk
= 1;
458 gpwrdn
.b
.lnstchng_msk
= 1;
459 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
461 /* Indicates that we are going out from hibernation */
462 core_if
->hibernation_suspend
= 0;
465 * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
466 * indicates restore from remote_wakeup
468 restore_essential_regs(core_if
, rem_wakeup
, 0);
471 * Wait a little for seeing new value of variable hibernation_suspend if
472 * Restore done interrupt received before polling
476 if (core_if
->hibernation_suspend
== 0) {
478 * Wait For Restore_done Interrupt. This mechanism of polling the
479 * interrupt is introduced to avoid any possible race conditions
482 gintsts_data_t gintsts
;
484 DWC_READ_REG32(&core_if
->core_global_regs
->gintsts
);
485 if (gintsts
.b
.restoredone
) {
487 gintsts
.b
.restoredone
= 1;
488 DWC_WRITE_REG32(&core_if
->core_global_regs
->
489 gintsts
, gintsts
.d32
);
490 DWC_PRINTF("Restore Done Interrupt seen\n");
496 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
499 /* Clear all pending interupts */
500 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
502 /* De-assert Restore */
504 gpwrdn
.b
.restore
= 1;
505 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
510 pcgcctl
.b
.rstpdwnmodule
= 1;
511 DWC_MODIFY_REG32(core_if
->pcgcctl
, pcgcctl
.d32
, 0);
514 /* Restore GUSBCFG and DCFG */
515 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
,
516 core_if
->gr_backup
->gusbcfg_local
);
517 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
,
518 core_if
->dr_backup
->dcfg
);
520 /* De-assert Wakeup Logic */
522 gpwrdn
.b
.pmuactv
= 1;
523 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
527 /* Set Device programming done bit */
528 dctl
.b
.pwronprgdone
= 1;
529 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
531 /* Start Remote Wakeup Signaling */
532 dctl
.d32
= core_if
->dr_backup
->dctl
;
533 dctl
.b
.rmtwkupsig
= 1;
534 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, dctl
.d32
);
538 /* Clear all pending interupts */
539 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
541 /* Restore global registers */
542 dwc_otg_restore_global_regs(core_if
);
543 /* Restore device global registers */
544 dwc_otg_restore_dev_regs(core_if
, rem_wakeup
);
549 dctl
.b
.rmtwkupsig
= 1;
550 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, dctl
.d32
, 0);
553 core_if
->hibernation_suspend
= 0;
554 /* The core will be in ON STATE */
555 core_if
->lx_state
= DWC_OTG_L0
;
556 DWC_PRINTF("Hibernation recovery completes here\n");
562 * The restore operation is modified to support Synopsys Emulated Powerdown and
563 * Hibernation. This function is for exiting from Host mode hibernation by
564 * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
565 * @param core_if Programming view of DWC_otg controller.
566 * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
567 * @param reset - indicates whether resume is initiated by Reset.
569 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t
* core_if
,
570 int rem_wakeup
, int reset
)
572 gpwrdn_data_t gpwrdn
= {.d32
= 0 };
573 hprt0_data_t hprt0
= {.d32
= 0 };
577 DWC_DEBUGPL(DBG_HCD
, "%s called\n", __FUNCTION__
);
578 /* Switch-on voltage to the core */
579 gpwrdn
.b
.pwrdnswtch
= 1;
580 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
585 gpwrdn
.b
.pwrdnrstn
= 1;
586 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
589 /* Assert Restore signal */
591 gpwrdn
.b
.restore
= 1;
592 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, 0, gpwrdn
.d32
);
595 /* Disable power clamps */
597 gpwrdn
.b
.pwrdnclmp
= 1;
598 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
604 /* Deassert Reset core */
606 gpwrdn
.b
.pwrdnrstn
= 1;
607 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, 0, gpwrdn
.d32
);
610 /* Disable PMU interrupt */
612 gpwrdn
.b
.pmuintsel
= 1;
613 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
616 gpwrdn
.b
.connect_det_msk
= 1;
617 gpwrdn
.b
.srp_det_msk
= 1;
618 gpwrdn
.b
.disconn_det_msk
= 1;
619 gpwrdn
.b
.rst_det_msk
= 1;
620 gpwrdn
.b
.lnstchng_msk
= 1;
621 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
623 /* Indicates that we are going out from hibernation */
624 core_if
->hibernation_suspend
= 0;
626 /* Set Restore Essential Regs bit in PCGCCTL register */
627 restore_essential_regs(core_if
, rem_wakeup
, 1);
629 /* Wait a little for seeing new value of variable hibernation_suspend if
630 * Restore done interrupt received before polling */
633 if (core_if
->hibernation_suspend
== 0) {
634 /* Wait For Restore_done Interrupt. This mechanism of polling the
635 * interrupt is introduced to avoid any possible race conditions
638 gintsts_data_t gintsts
;
639 gintsts
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gintsts
);
640 if (gintsts
.b
.restoredone
) {
642 gintsts
.b
.restoredone
= 1;
643 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, gintsts
.d32
);
644 DWC_DEBUGPL(DBG_HCD
,"Restore Done Interrupt seen\n");
650 DWC_WARN("Restore Done interrupt wasn't generated\n");
654 /* Set the flag's value to 0 again after receiving restore done interrupt */
655 core_if
->hibernation_suspend
= 0;
657 /* This step is not described in functional spec but if not wait for this
658 * delay, mismatch interrupts occurred because just after restore core is
659 * in Device mode(gintsts.curmode == 0) */
662 /* Clear all pending interrupts */
663 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
665 /* De-assert Restore */
667 gpwrdn
.b
.restore
= 1;
668 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
671 /* Restore GUSBCFG and HCFG */
672 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
,
673 core_if
->gr_backup
->gusbcfg_local
);
674 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hcfg
,
675 core_if
->hr_backup
->hcfg_local
);
677 /* De-assert Wakeup Logic */
679 gpwrdn
.b
.pmuactv
= 1;
680 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gpwrdn
, gpwrdn
.d32
, 0);
683 /* Start the Resume operation by programming HPRT0 */
684 hprt0
.d32
= core_if
->hr_backup
->hprt0_local
;
688 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
690 DWC_PRINTF("Resume Starts Now\n");
691 if (!reset
) { // Indicates it is Resume Operation
692 hprt0
.d32
= core_if
->hr_backup
->hprt0_local
;
697 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
701 /* Wait for Resume time and then program HPRT again */
703 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
705 } else { // Indicates it is Reset Operation
706 hprt0
.d32
= core_if
->hr_backup
->hprt0_local
;
711 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
712 /* Wait for Reset time and then program HPRT again */
715 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
717 /* Clear all interrupt status */
718 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
719 hprt0
.b
.prtconndet
= 1;
720 hprt0
.b
.prtenchng
= 1;
721 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
723 /* Clear all pending interupts */
724 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
726 /* Restore global registers */
727 dwc_otg_restore_global_regs(core_if
);
728 /* Restore host global registers */
729 dwc_otg_restore_host_regs(core_if
, reset
);
731 /* The core will be in ON STATE */
732 core_if
->lx_state
= DWC_OTG_L0
;
733 DWC_PRINTF("Hibernation recovery is complete here\n");
737 /** Saves some register values into system memory. */
738 int dwc_otg_save_global_regs(dwc_otg_core_if_t
* core_if
)
740 struct dwc_otg_global_regs_backup
*gr
;
743 gr
= core_if
->gr_backup
;
745 gr
= DWC_ALLOC(sizeof(*gr
));
747 return -DWC_E_NO_MEMORY
;
749 core_if
->gr_backup
= gr
;
752 gr
->gotgctl_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gotgctl
);
753 gr
->gintmsk_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gintmsk
);
754 gr
->gahbcfg_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gahbcfg
);
755 gr
->gusbcfg_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
756 gr
->grxfsiz_local
= DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
);
757 gr
->gnptxfsiz_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
);
758 gr
->hptxfsiz_local
= DWC_READ_REG32(&core_if
->core_global_regs
->hptxfsiz
);
759 #ifdef CONFIG_USB_DWC_OTG_LPM
760 gr
->glpmcfg_local
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
762 gr
->gi2cctl_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gi2cctl
);
763 gr
->pcgcctl_local
= DWC_READ_REG32(core_if
->pcgcctl
);
764 gr
->gdfifocfg_local
=
765 DWC_READ_REG32(&core_if
->core_global_regs
->gdfifocfg
);
766 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
767 gr
->dtxfsiz_local
[i
] =
768 DWC_READ_REG32(&(core_if
->core_global_regs
->dtxfsiz
[i
]));
771 DWC_DEBUGPL(DBG_ANY
, "===========Backing Global registers==========\n");
772 DWC_DEBUGPL(DBG_ANY
, "Backed up gotgctl = %08x\n", gr
->gotgctl_local
);
773 DWC_DEBUGPL(DBG_ANY
, "Backed up gintmsk = %08x\n", gr
->gintmsk_local
);
774 DWC_DEBUGPL(DBG_ANY
, "Backed up gahbcfg = %08x\n", gr
->gahbcfg_local
);
775 DWC_DEBUGPL(DBG_ANY
, "Backed up gusbcfg = %08x\n", gr
->gusbcfg_local
);
776 DWC_DEBUGPL(DBG_ANY
, "Backed up grxfsiz = %08x\n", gr
->grxfsiz_local
);
777 DWC_DEBUGPL(DBG_ANY
, "Backed up gnptxfsiz = %08x\n",
778 gr
->gnptxfsiz_local
);
779 DWC_DEBUGPL(DBG_ANY
, "Backed up hptxfsiz = %08x\n",
781 #ifdef CONFIG_USB_DWC_OTG_LPM
782 DWC_DEBUGPL(DBG_ANY
, "Backed up glpmcfg = %08x\n", gr
->glpmcfg_local
);
784 DWC_DEBUGPL(DBG_ANY
, "Backed up gi2cctl = %08x\n", gr
->gi2cctl_local
);
785 DWC_DEBUGPL(DBG_ANY
, "Backed up pcgcctl = %08x\n", gr
->pcgcctl_local
);
786 DWC_DEBUGPL(DBG_ANY
,"Backed up gdfifocfg = %08x\n",gr
->gdfifocfg_local
);
791 /** Saves GINTMSK register before setting the msk bits. */
792 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t
* core_if
)
794 struct dwc_otg_global_regs_backup
*gr
;
796 gr
= core_if
->gr_backup
;
798 gr
= DWC_ALLOC(sizeof(*gr
));
800 return -DWC_E_NO_MEMORY
;
802 core_if
->gr_backup
= gr
;
805 gr
->gintmsk_local
= DWC_READ_REG32(&core_if
->core_global_regs
->gintmsk
);
807 DWC_DEBUGPL(DBG_ANY
,"=============Backing GINTMSK registers============\n");
808 DWC_DEBUGPL(DBG_ANY
, "Backed up gintmsk = %08x\n", gr
->gintmsk_local
);
813 int dwc_otg_save_dev_regs(dwc_otg_core_if_t
* core_if
)
815 struct dwc_otg_dev_regs_backup
*dr
;
818 dr
= core_if
->dr_backup
;
820 dr
= DWC_ALLOC(sizeof(*dr
));
822 return -DWC_E_NO_MEMORY
;
824 core_if
->dr_backup
= dr
;
827 dr
->dcfg
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
828 dr
->dctl
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
);
830 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->daintmsk
);
832 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->diepmsk
);
834 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->doepmsk
);
836 for (i
= 0; i
< core_if
->dev_if
->num_in_eps
; ++i
) {
838 DWC_READ_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->diepctl
);
840 DWC_READ_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->dieptsiz
);
842 DWC_READ_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->diepdma
);
846 "=============Backing Host registers==============\n");
847 DWC_DEBUGPL(DBG_ANY
, "Backed up dcfg = %08x\n", dr
->dcfg
);
848 DWC_DEBUGPL(DBG_ANY
, "Backed up dctl = %08x\n", dr
->dctl
);
849 DWC_DEBUGPL(DBG_ANY
, "Backed up daintmsk = %08x\n",
851 DWC_DEBUGPL(DBG_ANY
, "Backed up diepmsk = %08x\n", dr
->diepmsk
);
852 DWC_DEBUGPL(DBG_ANY
, "Backed up doepmsk = %08x\n", dr
->doepmsk
);
853 for (i
= 0; i
< core_if
->dev_if
->num_in_eps
; ++i
) {
854 DWC_DEBUGPL(DBG_ANY
, "Backed up diepctl[%d] = %08x\n", i
,
856 DWC_DEBUGPL(DBG_ANY
, "Backed up dieptsiz[%d] = %08x\n",
858 DWC_DEBUGPL(DBG_ANY
, "Backed up diepdma[%d] = %08x\n", i
,
865 int dwc_otg_save_host_regs(dwc_otg_core_if_t
* core_if
)
867 struct dwc_otg_host_regs_backup
*hr
;
870 hr
= core_if
->hr_backup
;
872 hr
= DWC_ALLOC(sizeof(*hr
));
874 return -DWC_E_NO_MEMORY
;
876 core_if
->hr_backup
= hr
;
880 DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hcfg
);
882 DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->haintmsk
);
883 for (i
= 0; i
< dwc_otg_get_param_host_channels(core_if
); ++i
) {
884 hr
->hcintmsk_local
[i
] =
885 DWC_READ_REG32(&core_if
->host_if
->hc_regs
[i
]->hcintmsk
);
887 hr
->hprt0_local
= DWC_READ_REG32(core_if
->host_if
->hprt0
);
889 DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hfir
);
892 "=============Backing Host registers===============\n");
893 DWC_DEBUGPL(DBG_ANY
, "Backed up hcfg = %08x\n",
895 DWC_DEBUGPL(DBG_ANY
, "Backed up haintmsk = %08x\n", hr
->haintmsk_local
);
896 for (i
= 0; i
< dwc_otg_get_param_host_channels(core_if
); ++i
) {
897 DWC_DEBUGPL(DBG_ANY
, "Backed up hcintmsk[%02d]=%08x\n", i
,
898 hr
->hcintmsk_local
[i
]);
900 DWC_DEBUGPL(DBG_ANY
, "Backed up hprt0 = %08x\n",
902 DWC_DEBUGPL(DBG_ANY
, "Backed up hfir = %08x\n",
908 int dwc_otg_restore_global_regs(dwc_otg_core_if_t
*core_if
)
910 struct dwc_otg_global_regs_backup
*gr
;
913 gr
= core_if
->gr_backup
;
915 return -DWC_E_INVALID
;
918 DWC_WRITE_REG32(&core_if
->core_global_regs
->gotgctl
, gr
->gotgctl_local
);
919 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintmsk
, gr
->gintmsk_local
);
920 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, gr
->gusbcfg_local
);
921 DWC_WRITE_REG32(&core_if
->core_global_regs
->gahbcfg
, gr
->gahbcfg_local
);
922 DWC_WRITE_REG32(&core_if
->core_global_regs
->grxfsiz
, gr
->grxfsiz_local
);
923 DWC_WRITE_REG32(&core_if
->core_global_regs
->gnptxfsiz
,
924 gr
->gnptxfsiz_local
);
925 DWC_WRITE_REG32(&core_if
->core_global_regs
->hptxfsiz
,
927 DWC_WRITE_REG32(&core_if
->core_global_regs
->gdfifocfg
,
928 gr
->gdfifocfg_local
);
929 for (i
= 0; i
< MAX_EPS_CHANNELS
; i
++) {
930 DWC_WRITE_REG32(&core_if
->core_global_regs
->dtxfsiz
[i
],
931 gr
->dtxfsiz_local
[i
]);
934 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
935 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, 0x0000100A);
936 DWC_WRITE_REG32(&core_if
->core_global_regs
->gahbcfg
,
937 (gr
->gahbcfg_local
));
941 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t
* core_if
, int rem_wakeup
)
943 struct dwc_otg_dev_regs_backup
*dr
;
946 dr
= core_if
->dr_backup
;
949 return -DWC_E_INVALID
;
953 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
,
957 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->daintmsk
, dr
->daintmsk
);
958 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->diepmsk
, dr
->diepmsk
);
959 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->doepmsk
, dr
->doepmsk
);
961 for (i
= 0; i
< core_if
->dev_if
->num_in_eps
; ++i
) {
962 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->dieptsiz
, dr
->dieptsiz
[i
]);
963 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->diepdma
, dr
->diepdma
[i
]);
964 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[i
]->diepctl
, dr
->diepctl
[i
]);
970 int dwc_otg_restore_host_regs(dwc_otg_core_if_t
* core_if
, int reset
)
972 struct dwc_otg_host_regs_backup
*hr
;
974 hr
= core_if
->hr_backup
;
977 return -DWC_E_INVALID
;
980 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hcfg
, hr
->hcfg_local
);
983 // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
986 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->haintmsk
,
988 for (i
= 0; i
< dwc_otg_get_param_host_channels(core_if
); ++i
) {
989 DWC_WRITE_REG32(&core_if
->host_if
->hc_regs
[i
]->hcintmsk
,
990 hr
->hcintmsk_local
[i
]);
996 int restore_lpm_i2c_regs(dwc_otg_core_if_t
* core_if
)
998 struct dwc_otg_global_regs_backup
*gr
;
1000 gr
= core_if
->gr_backup
;
1002 /* Restore values for LPM and I2C */
1003 #ifdef CONFIG_USB_DWC_OTG_LPM
1004 DWC_WRITE_REG32(&core_if
->core_global_regs
->glpmcfg
, gr
->glpmcfg_local
);
1006 DWC_WRITE_REG32(&core_if
->core_global_regs
->gi2cctl
, gr
->gi2cctl_local
);
1011 int restore_essential_regs(dwc_otg_core_if_t
* core_if
, int rmode
, int is_host
)
1013 struct dwc_otg_global_regs_backup
*gr
;
1014 pcgcctl_data_t pcgcctl
= {.d32
= 0 };
1015 gahbcfg_data_t gahbcfg
= {.d32
= 0 };
1016 gusbcfg_data_t gusbcfg
= {.d32
= 0 };
1017 gintmsk_data_t gintmsk
= {.d32
= 0 };
1019 /* Restore LPM and I2C registers */
1020 restore_lpm_i2c_regs(core_if
);
1022 /* Set PCGCCTL to 0 */
1023 DWC_WRITE_REG32(core_if
->pcgcctl
, 0x00000000);
1025 gr
= core_if
->gr_backup
;
1026 /* Load restore values for [31:14] bits */
1027 DWC_WRITE_REG32(core_if
->pcgcctl
,
1028 ((gr
->pcgcctl_local
& 0xffffc000) | 0x00020000));
1030 /* Umnask global Interrupt in GAHBCFG and restore it */
1031 gahbcfg
.d32
= gr
->gahbcfg_local
;
1032 gahbcfg
.b
.glblintrmsk
= 1;
1033 DWC_WRITE_REG32(&core_if
->core_global_regs
->gahbcfg
, gahbcfg
.d32
);
1035 /* Clear all pending interupts */
1036 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, 0xFFFFFFFF);
1038 /* Unmask restore done interrupt */
1039 gintmsk
.b
.restoredone
= 1;
1040 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintmsk
, gintmsk
.d32
);
1042 /* Restore GUSBCFG and HCFG/DCFG */
1043 gusbcfg
.d32
= core_if
->gr_backup
->gusbcfg_local
;
1044 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, gusbcfg
.d32
);
1047 hcfg_data_t hcfg
= {.d32
= 0 };
1048 hcfg
.d32
= core_if
->hr_backup
->hcfg_local
;
1049 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hcfg
,
1052 /* Load restore values for [31:14] bits */
1053 pcgcctl
.d32
= gr
->pcgcctl_local
& 0xffffc000;
1054 pcgcctl
.d32
= gr
->pcgcctl_local
| 0x00020000;
1057 pcgcctl
.b
.restoremode
= 1;
1058 DWC_WRITE_REG32(core_if
->pcgcctl
, pcgcctl
.d32
);
1061 /* Load restore values for [31:14] bits and set EssRegRestored bit */
1062 pcgcctl
.d32
= gr
->pcgcctl_local
| 0xffffc000;
1063 pcgcctl
.d32
= gr
->pcgcctl_local
& 0xffffc000;
1064 pcgcctl
.b
.ess_reg_restored
= 1;
1066 pcgcctl
.b
.restoremode
= 1;
1067 DWC_WRITE_REG32(core_if
->pcgcctl
, pcgcctl
.d32
);
1069 dcfg_data_t dcfg
= {.d32
= 0 };
1070 dcfg
.d32
= core_if
->dr_backup
->dcfg
;
1071 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
1073 /* Load restore values for [31:14] bits */
1074 pcgcctl
.d32
= gr
->pcgcctl_local
& 0xffffc000;
1075 pcgcctl
.d32
= gr
->pcgcctl_local
| 0x00020000;
1077 pcgcctl
.d32
|= 0x208;
1079 DWC_WRITE_REG32(core_if
->pcgcctl
, pcgcctl
.d32
);
1082 /* Load restore values for [31:14] bits */
1083 pcgcctl
.d32
= gr
->pcgcctl_local
& 0xffffc000;
1084 pcgcctl
.d32
= gr
->pcgcctl_local
| 0x00020000;
1085 pcgcctl
.b
.ess_reg_restored
= 1;
1087 pcgcctl
.d32
|= 0x208;
1088 DWC_WRITE_REG32(core_if
->pcgcctl
, pcgcctl
.d32
);
1095 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1098 static void init_fslspclksel(dwc_otg_core_if_t
* core_if
)
1103 if (((core_if
->hwcfg2
.b
.hs_phy_type
== 2) &&
1104 (core_if
->hwcfg2
.b
.fs_phy_type
== 1) &&
1105 (core_if
->core_params
->ulpi_fs_ls
)) ||
1106 (core_if
->core_params
->phy_type
== DWC_PHY_TYPE_PARAM_FS
)) {
1107 /* Full speed PHY */
1108 val
= DWC_HCFG_48_MHZ
;
1110 /* High speed PHY running at full speed or high speed */
1111 val
= DWC_HCFG_30_60_MHZ
;
1114 DWC_DEBUGPL(DBG_CIL
, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val
);
1115 hcfg
.d32
= DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hcfg
);
1116 hcfg
.b
.fslspclksel
= val
;
1117 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hcfg
, hcfg
.d32
);
1121 * Initializes the DevSpd field of the DCFG register depending on the PHY type
1122 * and the enumeration speed of the device.
1124 static void init_devspd(dwc_otg_core_if_t
* core_if
)
1129 if (((core_if
->hwcfg2
.b
.hs_phy_type
== 2) &&
1130 (core_if
->hwcfg2
.b
.fs_phy_type
== 1) &&
1131 (core_if
->core_params
->ulpi_fs_ls
)) ||
1132 (core_if
->core_params
->phy_type
== DWC_PHY_TYPE_PARAM_FS
)) {
1133 /* Full speed PHY */
1135 } else if (core_if
->core_params
->speed
== DWC_SPEED_PARAM_FULL
) {
1136 /* High speed PHY running at full speed */
1139 /* High speed PHY running at high speed */
1143 DWC_DEBUGPL(DBG_CIL
, "Initializing DCFG.DevSpd to 0x%1x\n", val
);
1145 dcfg
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
1146 dcfg
.b
.devspd
= val
;
1147 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
1151 * This function calculates the number of IN EPS
1152 * using GHWCFG1 and GHWCFG2 registers values
1154 * @param core_if Programming view of the DWC_otg controller
1156 static uint32_t calc_num_in_eps(dwc_otg_core_if_t
* core_if
)
1158 uint32_t num_in_eps
= 0;
1159 uint32_t num_eps
= core_if
->hwcfg2
.b
.num_dev_ep
;
1160 uint32_t hwcfg1
= core_if
->hwcfg1
.d32
>> 3;
1161 uint32_t num_tx_fifos
= core_if
->hwcfg4
.b
.num_in_eps
;
1164 for (i
= 0; i
< num_eps
; ++i
) {
1165 if (!(hwcfg1
& 0x1))
1171 if (core_if
->hwcfg4
.b
.ded_fifo_en
) {
1173 (num_in_eps
> num_tx_fifos
) ? num_tx_fifos
: num_in_eps
;
1180 * This function calculates the number of OUT EPS
1181 * using GHWCFG1 and GHWCFG2 registers values
1183 * @param core_if Programming view of the DWC_otg controller
1185 static uint32_t calc_num_out_eps(dwc_otg_core_if_t
* core_if
)
1187 uint32_t num_out_eps
= 0;
1188 uint32_t num_eps
= core_if
->hwcfg2
.b
.num_dev_ep
;
1189 uint32_t hwcfg1
= core_if
->hwcfg1
.d32
>> 2;
1192 for (i
= 0; i
< num_eps
; ++i
) {
1193 if (!(hwcfg1
& 0x1))
1202 * This function initializes the DWC_otg controller registers and
1203 * prepares the core for device mode or host mode operation.
1205 * @param core_if Programming view of the DWC_otg controller
1208 void dwc_otg_core_init(dwc_otg_core_if_t
* core_if
)
1211 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
1212 dwc_otg_dev_if_t
*dev_if
= core_if
->dev_if
;
1213 gahbcfg_data_t ahbcfg
= {.d32
= 0 };
1214 gusbcfg_data_t usbcfg
= {.d32
= 0 };
1215 gi2cctl_data_t i2cctl
= {.d32
= 0 };
1217 DWC_DEBUGPL(DBG_CILV
, "dwc_otg_core_init(%p) regs at %p\n",
1218 core_if
, global_regs
);
1220 /* Common Initialization */
1221 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1223 /* Program the ULPI External VBUS bit if needed */
1224 usbcfg
.b
.ulpi_ext_vbus_drv
=
1225 (core_if
->core_params
->phy_ulpi_ext_vbus
==
1226 DWC_PHY_ULPI_EXTERNAL_VBUS
) ? 1 : 0;
1228 /* Set external TS Dline pulsing */
1229 usbcfg
.b
.term_sel_dl_pulse
=
1230 (core_if
->core_params
->ts_dline
== 1) ? 1 : 0;
1231 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1233 /* Reset the Controller */
1234 dwc_otg_core_reset(core_if
);
1236 core_if
->adp_enable
= core_if
->core_params
->adp_supp_enable
;
1237 core_if
->power_down
= core_if
->core_params
->power_down
;
1238 core_if
->otg_sts
= 0;
1240 /* Initialize parameters from Hardware configuration registers. */
1241 dev_if
->num_in_eps
= calc_num_in_eps(core_if
);
1242 dev_if
->num_out_eps
= calc_num_out_eps(core_if
);
1244 DWC_DEBUGPL(DBG_CIL
, "num_dev_perio_in_ep=%d\n",
1245 core_if
->hwcfg4
.b
.num_dev_perio_in_ep
);
1247 for (i
= 0; i
< core_if
->hwcfg4
.b
.num_dev_perio_in_ep
; i
++) {
1248 dev_if
->perio_tx_fifo_size
[i
] =
1249 DWC_READ_REG32(&global_regs
->dtxfsiz
[i
]) >> 16;
1250 DWC_DEBUGPL(DBG_CIL
, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1251 i
, dev_if
->perio_tx_fifo_size
[i
]);
1254 for (i
= 0; i
< core_if
->hwcfg4
.b
.num_in_eps
; i
++) {
1255 dev_if
->tx_fifo_size
[i
] =
1256 DWC_READ_REG32(&global_regs
->dtxfsiz
[i
]) >> 16;
1257 DWC_DEBUGPL(DBG_CIL
, "Tx FIFO SZ #%d=0x%0x\n",
1258 i
, dev_if
->tx_fifo_size
[i
]);
1261 core_if
->total_fifo_size
= core_if
->hwcfg3
.b
.dfifo_depth
;
1262 core_if
->rx_fifo_size
= DWC_READ_REG32(&global_regs
->grxfsiz
);
1263 core_if
->nperio_tx_fifo_size
=
1264 DWC_READ_REG32(&global_regs
->gnptxfsiz
) >> 16;
1266 DWC_DEBUGPL(DBG_CIL
, "Total FIFO SZ=%d\n", core_if
->total_fifo_size
);
1267 DWC_DEBUGPL(DBG_CIL
, "Rx FIFO SZ=%d\n", core_if
->rx_fifo_size
);
1268 DWC_DEBUGPL(DBG_CIL
, "NP Tx FIFO SZ=%d\n",
1269 core_if
->nperio_tx_fifo_size
);
1271 /* This programming sequence needs to happen in FS mode before any other
1272 * programming occurs */
1273 if ((core_if
->core_params
->speed
== DWC_SPEED_PARAM_FULL
) &&
1274 (core_if
->core_params
->phy_type
== DWC_PHY_TYPE_PARAM_FS
)) {
1275 /* If FS mode with FS PHY */
1277 /* core_init() is now called on every switch so only call the
1278 * following for the first time through. */
1279 if (!core_if
->phy_init_done
) {
1280 core_if
->phy_init_done
= 1;
1281 DWC_DEBUGPL(DBG_CIL
, "FS_PHY detected\n");
1282 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1283 usbcfg
.b
.physel
= 1;
1284 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1286 /* Reset after a PHY select */
1287 dwc_otg_core_reset(core_if
);
1290 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS. Also
1291 * do this on HNP Dev/Host mode switches (done in dev_init and
1293 if (dwc_otg_is_host_mode(core_if
)) {
1294 init_fslspclksel(core_if
);
1296 init_devspd(core_if
);
1299 if (core_if
->core_params
->i2c_enable
) {
1300 DWC_DEBUGPL(DBG_CIL
, "FS_PHY Enabling I2c\n");
1301 /* Program GUSBCFG.OtgUtmifsSel to I2C */
1302 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1303 usbcfg
.b
.otgutmifssel
= 1;
1304 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1306 /* Program GI2CCTL.I2CEn */
1307 i2cctl
.d32
= DWC_READ_REG32(&global_regs
->gi2cctl
);
1308 i2cctl
.b
.i2cdevaddr
= 1;
1310 DWC_WRITE_REG32(&global_regs
->gi2cctl
, i2cctl
.d32
);
1312 DWC_WRITE_REG32(&global_regs
->gi2cctl
, i2cctl
.d32
);
1315 } /* endif speed == DWC_SPEED_PARAM_FULL */
1317 /* High speed PHY. */
1318 if (!core_if
->phy_init_done
) {
1319 core_if
->phy_init_done
= 1;
1320 /* HS PHY parameters. These parameters are preserved
1321 * during soft reset so only program the first time. Do
1322 * a soft reset immediately after setting phyif. */
1324 if (core_if
->core_params
->phy_type
== 2) {
1325 /* ULPI interface */
1326 usbcfg
.b
.ulpi_utmi_sel
= 1;
1329 core_if
->core_params
->phy_ulpi_ddr
;
1330 } else if (core_if
->core_params
->phy_type
== 1) {
1331 /* UTMI+ interface */
1332 usbcfg
.b
.ulpi_utmi_sel
= 0;
1333 if (core_if
->core_params
->phy_utmi_width
== 16) {
1340 DWC_ERROR("FS PHY TYPE\n");
1342 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1343 /* Reset after setting the PHY parameters */
1344 dwc_otg_core_reset(core_if
);
1348 if ((core_if
->hwcfg2
.b
.hs_phy_type
== 2) &&
1349 (core_if
->hwcfg2
.b
.fs_phy_type
== 1) &&
1350 (core_if
->core_params
->ulpi_fs_ls
)) {
1351 DWC_DEBUGPL(DBG_CIL
, "Setting ULPI FSLS\n");
1352 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1353 usbcfg
.b
.ulpi_fsls
= 1;
1354 usbcfg
.b
.ulpi_clk_sus_m
= 1;
1355 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1357 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1358 usbcfg
.b
.ulpi_fsls
= 0;
1359 usbcfg
.b
.ulpi_clk_sus_m
= 0;
1360 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1363 /* Program the GAHBCFG Register. */
1364 switch (core_if
->hwcfg2
.b
.architecture
) {
1366 case DWC_SLAVE_ONLY_ARCH
:
1367 DWC_DEBUGPL(DBG_CIL
, "Slave Only Mode\n");
1368 ahbcfg
.b
.nptxfemplvl_txfemplvl
=
1369 DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY
;
1370 ahbcfg
.b
.ptxfemplvl
= DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY
;
1371 core_if
->dma_enable
= 0;
1372 core_if
->dma_desc_enable
= 0;
1375 case DWC_EXT_DMA_ARCH
:
1376 DWC_DEBUGPL(DBG_CIL
, "External DMA Mode\n");
1378 uint8_t brst_sz
= core_if
->core_params
->dma_burst_size
;
1379 ahbcfg
.b
.hburstlen
= 0;
1380 while (brst_sz
> 1) {
1381 ahbcfg
.b
.hburstlen
++;
1385 core_if
->dma_enable
= (core_if
->core_params
->dma_enable
!= 0);
1386 core_if
->dma_desc_enable
=
1387 (core_if
->core_params
->dma_desc_enable
!= 0);
1390 case DWC_INT_DMA_ARCH
:
1391 DWC_DEBUGPL(DBG_CIL
, "Internal DMA Mode\n");
1392 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
1393 Host mode ISOC in issue fix - vahrama */
1394 /* Broadcom had altered to (1<<3)|(0<<0) - WRESP=1, max 4 beats */
1395 ahbcfg
.b
.hburstlen
= (1<<3)|(0<<0);//DWC_GAHBCFG_INT_DMA_BURST_INCR4;
1396 core_if
->dma_enable
= (core_if
->core_params
->dma_enable
!= 0);
1397 core_if
->dma_desc_enable
=
1398 (core_if
->core_params
->dma_desc_enable
!= 0);
1402 if (core_if
->dma_enable
) {
1403 if (core_if
->dma_desc_enable
) {
1404 DWC_PRINTF("Using Descriptor DMA mode\n");
1406 DWC_PRINTF("Using Buffer DMA mode\n");
1410 DWC_PRINTF("Using Slave mode\n");
1411 core_if
->dma_desc_enable
= 0;
1414 if (core_if
->core_params
->ahb_single
) {
1415 ahbcfg
.b
.ahbsingle
= 1;
1418 ahbcfg
.b
.dmaenable
= core_if
->dma_enable
;
1419 DWC_WRITE_REG32(&global_regs
->gahbcfg
, ahbcfg
.d32
);
1421 core_if
->en_multiple_tx_fifo
= core_if
->hwcfg4
.b
.ded_fifo_en
;
1423 core_if
->pti_enh_enable
= core_if
->core_params
->pti_enable
!= 0;
1424 core_if
->multiproc_int_enable
= core_if
->core_params
->mpi_enable
;
1425 DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1426 ((core_if
->pti_enh_enable
) ? "enabled" : "disabled"));
1427 DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1428 ((core_if
->multiproc_int_enable
) ? "enabled" : "disabled"));
1431 * Program the GUSBCFG register.
1433 usbcfg
.d32
= DWC_READ_REG32(&global_regs
->gusbcfg
);
1435 switch (core_if
->hwcfg2
.b
.op_mode
) {
1436 case DWC_MODE_HNP_SRP_CAPABLE
:
1437 usbcfg
.b
.hnpcap
= (core_if
->core_params
->otg_cap
==
1438 DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
);
1439 usbcfg
.b
.srpcap
= (core_if
->core_params
->otg_cap
!=
1440 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
);
1443 case DWC_MODE_SRP_ONLY_CAPABLE
:
1444 usbcfg
.b
.hnpcap
= 0;
1445 usbcfg
.b
.srpcap
= (core_if
->core_params
->otg_cap
!=
1446 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
);
1449 case DWC_MODE_NO_HNP_SRP_CAPABLE
:
1450 usbcfg
.b
.hnpcap
= 0;
1451 usbcfg
.b
.srpcap
= 0;
1454 case DWC_MODE_SRP_CAPABLE_DEVICE
:
1455 usbcfg
.b
.hnpcap
= 0;
1456 usbcfg
.b
.srpcap
= (core_if
->core_params
->otg_cap
!=
1457 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
);
1460 case DWC_MODE_NO_SRP_CAPABLE_DEVICE
:
1461 usbcfg
.b
.hnpcap
= 0;
1462 usbcfg
.b
.srpcap
= 0;
1465 case DWC_MODE_SRP_CAPABLE_HOST
:
1466 usbcfg
.b
.hnpcap
= 0;
1467 usbcfg
.b
.srpcap
= (core_if
->core_params
->otg_cap
!=
1468 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
);
1471 case DWC_MODE_NO_SRP_CAPABLE_HOST
:
1472 usbcfg
.b
.hnpcap
= 0;
1473 usbcfg
.b
.srpcap
= 0;
1477 DWC_WRITE_REG32(&global_regs
->gusbcfg
, usbcfg
.d32
);
1479 #ifdef CONFIG_USB_DWC_OTG_LPM
1480 if (core_if
->core_params
->lpm_enable
) {
1481 glpmcfg_data_t lpmcfg
= {.d32
= 0 };
1483 /* To enable LPM support set lpm_cap_en bit */
1484 lpmcfg
.b
.lpm_cap_en
= 1;
1486 /* Make AppL1Res ACK */
1487 lpmcfg
.b
.appl_resp
= 1;
1490 lpmcfg
.b
.retry_count
= 3;
1492 DWC_MODIFY_REG32(&core_if
->core_global_regs
->glpmcfg
,
1497 if (core_if
->core_params
->ic_usb_cap
) {
1498 gusbcfg_data_t gusbcfg
= {.d32
= 0 };
1499 gusbcfg
.b
.ic_usb_cap
= 1;
1500 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gusbcfg
,
1504 gotgctl_data_t gotgctl
= {.d32
= 0 };
1505 gotgctl
.b
.otgver
= core_if
->core_params
->otg_ver
;
1506 DWC_MODIFY_REG32(&core_if
->core_global_regs
->gotgctl
, 0,
1508 /* Set OTG version supported */
1509 core_if
->otg_ver
= core_if
->core_params
->otg_ver
;
1510 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1511 core_if
->core_params
->otg_ver
, core_if
->otg_ver
);
1515 /* Enable common interrupts */
1516 dwc_otg_enable_common_interrupts(core_if
);
1518 /* Do device or host intialization based on mode during PCD
1519 * and HCD initialization */
1520 if (dwc_otg_is_host_mode(core_if
)) {
1521 DWC_DEBUGPL(DBG_ANY
, "Host Mode\n");
1522 core_if
->op_state
= A_HOST
;
1524 DWC_DEBUGPL(DBG_ANY
, "Device Mode\n");
1525 core_if
->op_state
= B_PERIPHERAL
;
1526 #ifdef DWC_DEVICE_ONLY
1527 dwc_otg_core_dev_init(core_if
);
1533 * This function enables the Device mode interrupts.
1535 * @param core_if Programming view of DWC_otg controller
1537 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t
* core_if
)
1539 gintmsk_data_t intr_mask
= {.d32
= 0 };
1540 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
1542 DWC_DEBUGPL(DBG_CIL
, "%s()\n", __func__
);
1544 /* Disable all interrupts. */
1545 DWC_WRITE_REG32(&global_regs
->gintmsk
, 0);
1547 /* Clear any pending interrupts */
1548 DWC_WRITE_REG32(&global_regs
->gintsts
, 0xFFFFFFFF);
1550 /* Enable the common interrupts */
1551 dwc_otg_enable_common_interrupts(core_if
);
1553 /* Enable interrupts */
1554 intr_mask
.b
.usbreset
= 1;
1555 intr_mask
.b
.enumdone
= 1;
1556 /* Disable Disconnect interrupt in Device mode */
1557 intr_mask
.b
.disconnect
= 0;
1559 if (!core_if
->multiproc_int_enable
) {
1560 intr_mask
.b
.inepintr
= 1;
1561 intr_mask
.b
.outepintr
= 1;
1564 intr_mask
.b
.erlysuspend
= 1;
1566 if (core_if
->en_multiple_tx_fifo
== 0) {
1567 intr_mask
.b
.epmismatch
= 1;
1570 //intr_mask.b.incomplisoout = 1;
1571 intr_mask
.b
.incomplisoin
= 1;
1573 /* Enable the ignore frame number for ISOC xfers - MAS */
1574 /* Disable to support high bandwith ISOC transfers - manukz */
1576 #ifdef DWC_UTE_PER_IO
1577 if (core_if
->dma_enable
) {
1578 if (core_if
->dma_desc_enable
) {
1579 dctl_data_t dctl1
= {.d32
= 0 };
1580 dctl1
.b
.ifrmnum
= 1;
1581 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->
1582 dctl
, 0, dctl1
.d32
);
1583 DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
1584 DWC_READ_REG32(&core_if
->dev_if
->
1585 dev_global_regs
->dctl
));
1591 if (core_if
->dma_enable
) {
1592 if (core_if
->dma_desc_enable
== 0) {
1593 if (core_if
->pti_enh_enable
) {
1594 dctl_data_t dctl
= {.d32
= 0 };
1596 DWC_MODIFY_REG32(&core_if
->
1597 dev_if
->dev_global_regs
->dctl
,
1600 intr_mask
.b
.incomplisoin
= 1;
1601 intr_mask
.b
.incomplisoout
= 1;
1605 intr_mask
.b
.incomplisoin
= 1;
1606 intr_mask
.b
.incomplisoout
= 1;
1608 #endif /* DWC_EN_ISOC */
1610 /** @todo NGS: Should this be a module parameter? */
1611 #ifdef USE_PERIODIC_EP
1612 intr_mask
.b
.isooutdrop
= 1;
1613 intr_mask
.b
.eopframe
= 1;
1614 intr_mask
.b
.incomplisoin
= 1;
1615 intr_mask
.b
.incomplisoout
= 1;
1618 DWC_MODIFY_REG32(&global_regs
->gintmsk
, intr_mask
.d32
, intr_mask
.d32
);
1620 DWC_DEBUGPL(DBG_CIL
, "%s() gintmsk=%0x\n", __func__
,
1621 DWC_READ_REG32(&global_regs
->gintmsk
));
1625 * This function initializes the DWC_otg controller registers for
1628 * @param core_if Programming view of DWC_otg controller
1631 void dwc_otg_core_dev_init(dwc_otg_core_if_t
* core_if
)
1634 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
1635 dwc_otg_dev_if_t
*dev_if
= core_if
->dev_if
;
1636 dwc_otg_core_params_t
*params
= core_if
->core_params
;
1637 dcfg_data_t dcfg
= {.d32
= 0 };
1638 depctl_data_t diepctl
= {.d32
= 0 };
1639 grstctl_t resetctl
= {.d32
= 0 };
1640 uint32_t rx_fifo_size
;
1641 fifosize_data_t nptxfifosize
;
1642 fifosize_data_t txfifosize
;
1643 dthrctl_data_t dthrctl
;
1644 fifosize_data_t ptxfifosize
;
1645 uint16_t rxfsiz
, nptxfsiz
;
1646 gdfifocfg_data_t gdfifocfg
= {.d32
= 0 };
1647 hwcfg3_data_t hwcfg3
= {.d32
= 0 };
1649 /* Restart the Phy Clock */
1650 DWC_WRITE_REG32(core_if
->pcgcctl
, 0);
1652 /* Device configuration register */
1653 init_devspd(core_if
);
1654 dcfg
.d32
= DWC_READ_REG32(&dev_if
->dev_global_regs
->dcfg
);
1655 dcfg
.b
.descdma
= (core_if
->dma_desc_enable
) ? 1 : 0;
1656 dcfg
.b
.perfrint
= DWC_DCFG_FRAME_INTERVAL_80
;
1657 /* Enable Device OUT NAK in case of DDMA mode*/
1658 if (core_if
->core_params
->dev_out_nak
) {
1659 dcfg
.b
.endevoutnak
= 1;
1662 if (core_if
->core_params
->cont_on_bna
) {
1663 dctl_data_t dctl
= {.d32
= 0 };
1664 dctl
.b
.encontonbna
= 1;
1665 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
1669 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
1671 /* Configure data FIFO sizes */
1672 if (core_if
->hwcfg2
.b
.dynamic_fifo
&& params
->enable_dynamic_fifo
) {
1673 DWC_DEBUGPL(DBG_CIL
, "Total FIFO Size=%d\n",
1674 core_if
->total_fifo_size
);
1675 DWC_DEBUGPL(DBG_CIL
, "Rx FIFO Size=%d\n",
1676 params
->dev_rx_fifo_size
);
1677 DWC_DEBUGPL(DBG_CIL
, "NP Tx FIFO Size=%d\n",
1678 params
->dev_nperio_tx_fifo_size
);
1681 DWC_DEBUGPL(DBG_CIL
, "initial grxfsiz=%08x\n",
1682 DWC_READ_REG32(&global_regs
->grxfsiz
));
1685 core_if
->pwron_rxfsiz
= DWC_READ_REG32(&global_regs
->grxfsiz
);
1686 core_if
->init_rxfsiz
= params
->dev_rx_fifo_size
;
1688 rx_fifo_size
= params
->dev_rx_fifo_size
;
1689 DWC_WRITE_REG32(&global_regs
->grxfsiz
, rx_fifo_size
);
1691 DWC_DEBUGPL(DBG_CIL
, "new grxfsiz=%08x\n",
1692 DWC_READ_REG32(&global_regs
->grxfsiz
));
1694 /** Set Periodic Tx FIFO Mask all bits 0 */
1695 core_if
->p_tx_msk
= 0;
1697 /** Set Tx FIFO Mask all bits 0 */
1698 core_if
->tx_msk
= 0;
1700 if (core_if
->en_multiple_tx_fifo
== 0) {
1701 /* Non-periodic Tx FIFO */
1702 DWC_DEBUGPL(DBG_CIL
, "initial gnptxfsiz=%08x\n",
1703 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
1705 nptxfifosize
.b
.depth
= params
->dev_nperio_tx_fifo_size
;
1706 nptxfifosize
.b
.startaddr
= params
->dev_rx_fifo_size
;
1708 DWC_WRITE_REG32(&global_regs
->gnptxfsiz
,
1711 DWC_DEBUGPL(DBG_CIL
, "new gnptxfsiz=%08x\n",
1712 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
1714 /**@todo NGS: Fix Periodic FIFO Sizing! */
1716 * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1717 * Indexes of the FIFO size module parameters in the
1718 * dev_perio_tx_fifo_size array and the FIFO size registers in
1719 * the dptxfsiz array run from 0 to 14.
1721 /** @todo Finish debug of this */
1722 ptxfifosize
.b
.startaddr
=
1723 nptxfifosize
.b
.startaddr
+ nptxfifosize
.b
.depth
;
1724 for (i
= 0; i
< core_if
->hwcfg4
.b
.num_dev_perio_in_ep
; i
++) {
1725 ptxfifosize
.b
.depth
=
1726 params
->dev_perio_tx_fifo_size
[i
];
1727 DWC_DEBUGPL(DBG_CIL
,
1728 "initial dtxfsiz[%d]=%08x\n", i
,
1729 DWC_READ_REG32(&global_regs
->dtxfsiz
1731 DWC_WRITE_REG32(&global_regs
->dtxfsiz
[i
],
1733 DWC_DEBUGPL(DBG_CIL
, "new dtxfsiz[%d]=%08x\n",
1735 DWC_READ_REG32(&global_regs
->dtxfsiz
1737 ptxfifosize
.b
.startaddr
+= ptxfifosize
.b
.depth
;
1741 * Tx FIFOs These FIFOs are numbered from 1 to 15.
1742 * Indexes of the FIFO size module parameters in the
1743 * dev_tx_fifo_size array and the FIFO size registers in
1744 * the dtxfsiz array run from 0 to 14.
1747 /* Non-periodic Tx FIFO */
1748 DWC_DEBUGPL(DBG_CIL
, "initial gnptxfsiz=%08x\n",
1749 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
1752 core_if
->pwron_gnptxfsiz
=
1753 (DWC_READ_REG32(&global_regs
->gnptxfsiz
) >> 16);
1754 core_if
->init_gnptxfsiz
=
1755 params
->dev_nperio_tx_fifo_size
;
1757 nptxfifosize
.b
.depth
= params
->dev_nperio_tx_fifo_size
;
1758 nptxfifosize
.b
.startaddr
= params
->dev_rx_fifo_size
;
1760 DWC_WRITE_REG32(&global_regs
->gnptxfsiz
,
1763 DWC_DEBUGPL(DBG_CIL
, "new gnptxfsiz=%08x\n",
1764 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
1766 txfifosize
.b
.startaddr
=
1767 nptxfifosize
.b
.startaddr
+ nptxfifosize
.b
.depth
;
1769 for (i
= 0; i
< core_if
->hwcfg4
.b
.num_in_eps
; i
++) {
1771 txfifosize
.b
.depth
=
1772 params
->dev_tx_fifo_size
[i
];
1774 DWC_DEBUGPL(DBG_CIL
,
1775 "initial dtxfsiz[%d]=%08x\n",
1777 DWC_READ_REG32(&global_regs
->dtxfsiz
1781 core_if
->pwron_txfsiz
[i
] =
1783 (&global_regs
->dtxfsiz
[i
]) >> 16);
1784 core_if
->init_txfsiz
[i
] =
1785 params
->dev_tx_fifo_size
[i
];
1787 DWC_WRITE_REG32(&global_regs
->dtxfsiz
[i
],
1790 DWC_DEBUGPL(DBG_CIL
,
1791 "new dtxfsiz[%d]=%08x\n",
1793 DWC_READ_REG32(&global_regs
->dtxfsiz
1796 txfifosize
.b
.startaddr
+= txfifosize
.b
.depth
;
1798 if (core_if
->snpsid
<= OTG_CORE_REV_2_94a
) {
1799 /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO */
1800 gdfifocfg
.d32
= DWC_READ_REG32(&global_regs
->gdfifocfg
);
1801 hwcfg3
.d32
= DWC_READ_REG32(&global_regs
->ghwcfg3
);
1802 gdfifocfg
.b
.gdfifocfg
= (DWC_READ_REG32(&global_regs
->ghwcfg3
) >> 16);
1803 DWC_WRITE_REG32(&global_regs
->gdfifocfg
, gdfifocfg
.d32
);
1804 rxfsiz
= (DWC_READ_REG32(&global_regs
->grxfsiz
) & 0x0000ffff);
1805 nptxfsiz
= (DWC_READ_REG32(&global_regs
->gnptxfsiz
) >> 16);
1806 gdfifocfg
.b
.epinfobase
= rxfsiz
+ nptxfsiz
;
1807 DWC_WRITE_REG32(&global_regs
->gdfifocfg
, gdfifocfg
.d32
);
1811 /* Flush the FIFOs */
1812 dwc_otg_flush_tx_fifo(core_if
, 0x10); /* all Tx FIFOs */
1813 dwc_otg_flush_rx_fifo(core_if
);
1815 /* Flush the Learning Queue. */
1816 resetctl
.b
.intknqflsh
= 1;
1817 DWC_WRITE_REG32(&core_if
->core_global_regs
->grstctl
, resetctl
.d32
);
1819 if (!core_if
->core_params
->en_multiple_tx_fifo
&& core_if
->dma_enable
) {
1820 core_if
->start_predict
= 0;
1821 for (i
= 0; i
<= core_if
->dev_if
->num_in_eps
; ++i
) {
1822 core_if
->nextep_seq
[i
] = 0xff; // 0xff - EP not active
1824 core_if
->nextep_seq
[0] = 0;
1825 core_if
->first_in_nextep_seq
= 0;
1826 diepctl
.d32
= DWC_READ_REG32(&dev_if
->in_ep_regs
[0]->diepctl
);
1827 diepctl
.b
.nextep
= 0;
1828 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[0]->diepctl
, diepctl
.d32
);
1830 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
1831 dcfg
.d32
= DWC_READ_REG32(&dev_if
->dev_global_regs
->dcfg
);
1833 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
1835 DWC_DEBUGPL(DBG_CILV
,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
1836 __func__
, core_if
->first_in_nextep_seq
);
1837 for (i
=0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
1838 DWC_DEBUGPL(DBG_CILV
, "%2d ", core_if
->nextep_seq
[i
]);
1840 DWC_DEBUGPL(DBG_CILV
,"\n");
1843 /* Clear all pending Device Interrupts */
1844 /** @todo - if the condition needed to be checked
1845 * or in any case all pending interrutps should be cleared?
1847 if (core_if
->multiproc_int_enable
) {
1848 for (i
= 0; i
< core_if
->dev_if
->num_in_eps
; ++i
) {
1849 DWC_WRITE_REG32(&dev_if
->
1850 dev_global_regs
->diepeachintmsk
[i
], 0);
1854 for (i
= 0; i
< core_if
->dev_if
->num_out_eps
; ++i
) {
1855 DWC_WRITE_REG32(&dev_if
->
1856 dev_global_regs
->doepeachintmsk
[i
], 0);
1859 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->deachint
, 0xFFFFFFFF);
1860 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->deachintmsk
, 0);
1862 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->diepmsk
, 0);
1863 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->doepmsk
, 0);
1864 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->daint
, 0xFFFFFFFF);
1865 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->daintmsk
, 0);
1868 for (i
= 0; i
<= dev_if
->num_in_eps
; i
++) {
1869 depctl_data_t depctl
;
1870 depctl
.d32
= DWC_READ_REG32(&dev_if
->in_ep_regs
[i
]->diepctl
);
1871 if (depctl
.b
.epena
) {
1879 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[i
]->diepctl
, depctl
.d32
);
1881 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[i
]->dieptsiz
, 0);
1882 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[i
]->diepdma
, 0);
1883 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[i
]->diepint
, 0xFF);
1886 for (i
= 0; i
<= dev_if
->num_out_eps
; i
++) {
1887 depctl_data_t depctl
;
1888 depctl
.d32
= DWC_READ_REG32(&dev_if
->out_ep_regs
[i
]->doepctl
);
1889 if (depctl
.b
.epena
) {
1890 dctl_data_t dctl
= {.d32
= 0 };
1891 gintmsk_data_t gintsts
= {.d32
= 0 };
1892 doepint_data_t doepint
= {.d32
= 0 };
1893 dctl
.b
.sgoutnak
= 1;
1894 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
1897 gintsts
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gintsts
);
1898 } while (!gintsts
.b
.goutnakeff
);
1900 gintsts
.b
.goutnakeff
= 1;
1901 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, gintsts
.d32
);
1906 DWC_WRITE_REG32(&core_if
->dev_if
->out_ep_regs
[i
]->doepctl
, depctl
.d32
);
1909 doepint
.d32
= DWC_READ_REG32(&core_if
->dev_if
->
1910 out_ep_regs
[i
]->doepint
);
1911 } while (!doepint
.b
.epdisabled
);
1913 doepint
.b
.epdisabled
= 1;
1914 DWC_WRITE_REG32(&core_if
->dev_if
->out_ep_regs
[i
]->doepint
, doepint
.d32
);
1917 dctl
.b
.cgoutnak
= 1;
1918 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
1923 DWC_WRITE_REG32(&dev_if
->out_ep_regs
[i
]->doepctl
, depctl
.d32
);
1925 DWC_WRITE_REG32(&dev_if
->out_ep_regs
[i
]->doeptsiz
, 0);
1926 DWC_WRITE_REG32(&dev_if
->out_ep_regs
[i
]->doepdma
, 0);
1927 DWC_WRITE_REG32(&dev_if
->out_ep_regs
[i
]->doepint
, 0xFF);
1930 if (core_if
->en_multiple_tx_fifo
&& core_if
->dma_enable
) {
1931 dev_if
->non_iso_tx_thr_en
= params
->thr_ctl
& 0x1;
1932 dev_if
->iso_tx_thr_en
= (params
->thr_ctl
>> 1) & 0x1;
1933 dev_if
->rx_thr_en
= (params
->thr_ctl
>> 2) & 0x1;
1935 dev_if
->rx_thr_length
= params
->rx_thr_length
;
1936 dev_if
->tx_thr_length
= params
->tx_thr_length
;
1938 dev_if
->setup_desc_index
= 0;
1941 dthrctl
.b
.non_iso_thr_en
= dev_if
->non_iso_tx_thr_en
;
1942 dthrctl
.b
.iso_thr_en
= dev_if
->iso_tx_thr_en
;
1943 dthrctl
.b
.tx_thr_len
= dev_if
->tx_thr_length
;
1944 dthrctl
.b
.rx_thr_en
= dev_if
->rx_thr_en
;
1945 dthrctl
.b
.rx_thr_len
= dev_if
->rx_thr_length
;
1946 dthrctl
.b
.ahb_thr_ratio
= params
->ahb_thr_ratio
;
1948 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->dtknqr3_dthrctl
,
1951 DWC_DEBUGPL(DBG_CIL
,
1952 "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1953 dthrctl
.b
.non_iso_thr_en
, dthrctl
.b
.iso_thr_en
,
1954 dthrctl
.b
.rx_thr_en
, dthrctl
.b
.tx_thr_len
,
1955 dthrctl
.b
.rx_thr_len
);
1959 dwc_otg_enable_device_interrupts(core_if
);
1962 diepmsk_data_t msk
= {.d32
= 0 };
1963 msk
.b
.txfifoundrn
= 1;
1964 if (core_if
->multiproc_int_enable
) {
1965 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->
1966 diepeachintmsk
[0], msk
.d32
, msk
.d32
);
1968 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->diepmsk
,
1973 if (core_if
->multiproc_int_enable
) {
1974 /* Set NAK on Babble */
1975 dctl_data_t dctl
= {.d32
= 0 };
1976 dctl
.b
.nakonbble
= 1;
1977 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
1980 if (core_if
->snpsid
>= OTG_CORE_REV_2_94a
) {
1981 dctl_data_t dctl
= {.d32
= 0 };
1982 dctl
.d32
= DWC_READ_REG32(&dev_if
->dev_global_regs
->dctl
);
1983 dctl
.b
.sftdiscon
= 0;
1984 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->dctl
, dctl
.d32
);
1989 * This function enables the Host mode interrupts.
1991 * @param core_if Programming view of DWC_otg controller
1993 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t
* core_if
)
1995 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
1996 gintmsk_data_t intr_mask
= {.d32
= 0 };
1998 DWC_DEBUGPL(DBG_CIL
, "%s(%p)\n", __func__
, core_if
);
2000 /* Disable all interrupts. */
2001 DWC_WRITE_REG32(&global_regs
->gintmsk
, 0);
2003 /* Clear any pending interrupts. */
2004 DWC_WRITE_REG32(&global_regs
->gintsts
, 0xFFFFFFFF);
2006 /* Enable the common interrupts */
2007 dwc_otg_enable_common_interrupts(core_if
);
2010 * Enable host mode interrupts without disturbing common
2014 intr_mask
.b
.disconnect
= 1;
2015 intr_mask
.b
.portintr
= 1;
2016 intr_mask
.b
.hcintr
= 1;
2018 DWC_MODIFY_REG32(&global_regs
->gintmsk
, intr_mask
.d32
, intr_mask
.d32
);
2022 * This function disables the Host Mode interrupts.
2024 * @param core_if Programming view of DWC_otg controller
2026 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t
* core_if
)
2028 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
2029 gintmsk_data_t intr_mask
= {.d32
= 0 };
2031 DWC_DEBUGPL(DBG_CILV
, "%s()\n", __func__
);
2034 * Disable host mode interrupts without disturbing common
2037 intr_mask
.b
.sofintr
= 1;
2038 intr_mask
.b
.portintr
= 1;
2039 intr_mask
.b
.hcintr
= 1;
2040 intr_mask
.b
.ptxfempty
= 1;
2041 intr_mask
.b
.nptxfempty
= 1;
2043 DWC_MODIFY_REG32(&global_regs
->gintmsk
, intr_mask
.d32
, 0);
2047 * This function initializes the DWC_otg controller registers for
2050 * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2051 * request queues. Host channels are reset to ensure that they are ready for
2052 * performing transfers.
2054 * @param core_if Programming view of DWC_otg controller
2057 void dwc_otg_core_host_init(dwc_otg_core_if_t
* core_if
)
2059 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
2060 dwc_otg_host_if_t
*host_if
= core_if
->host_if
;
2061 dwc_otg_core_params_t
*params
= core_if
->core_params
;
2062 hprt0_data_t hprt0
= {.d32
= 0 };
2063 fifosize_data_t nptxfifosize
;
2064 fifosize_data_t ptxfifosize
;
2065 uint16_t rxfsiz
, nptxfsiz
, hptxfsiz
;
2066 gdfifocfg_data_t gdfifocfg
= {.d32
= 0 };
2068 hcchar_data_t hcchar
;
2071 dwc_otg_hc_regs_t
*hc_regs
;
2073 gotgctl_data_t gotgctl
= {.d32
= 0 };
2075 DWC_DEBUGPL(DBG_CILV
, "%s(%p)\n", __func__
, core_if
);
2077 /* Restart the Phy Clock */
2078 DWC_WRITE_REG32(core_if
->pcgcctl
, 0);
2080 /* Initialize Host Configuration Register */
2081 init_fslspclksel(core_if
);
2082 if (core_if
->core_params
->speed
== DWC_SPEED_PARAM_FULL
) {
2083 hcfg
.d32
= DWC_READ_REG32(&host_if
->host_global_regs
->hcfg
);
2084 hcfg
.b
.fslssupp
= 1;
2085 DWC_WRITE_REG32(&host_if
->host_global_regs
->hcfg
, hcfg
.d32
);
2089 /* This bit allows dynamic reloading of the HFIR register
2090 * during runtime. This bit needs to be programmed during
2091 * initial configuration and its value must not be changed
2093 if (core_if
->core_params
->reload_ctl
== 1) {
2094 hfir
.d32
= DWC_READ_REG32(&host_if
->host_global_regs
->hfir
);
2095 hfir
.b
.hfirrldctrl
= 1;
2096 DWC_WRITE_REG32(&host_if
->host_global_regs
->hfir
, hfir
.d32
);
2099 if (core_if
->core_params
->dma_desc_enable
) {
2100 uint8_t op_mode
= core_if
->hwcfg2
.b
.op_mode
;
2102 (core_if
->hwcfg4
.b
.desc_dma
2103 && (core_if
->snpsid
>= OTG_CORE_REV_2_90a
)
2104 && ((op_mode
== DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG
)
2105 || (op_mode
== DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG
)
2107 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG
)
2108 || (op_mode
== DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST
)
2110 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST
)))) {
2112 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
2113 "Either core version is below 2.90a or "
2114 "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
2115 "To run the driver in Buffer DMA host mode set dma_desc_enable "
2116 "module parameter to 0.\n");
2119 hcfg
.d32
= DWC_READ_REG32(&host_if
->host_global_regs
->hcfg
);
2121 DWC_WRITE_REG32(&host_if
->host_global_regs
->hcfg
, hcfg
.d32
);
2124 /* Configure data FIFO sizes */
2125 if (core_if
->hwcfg2
.b
.dynamic_fifo
&& params
->enable_dynamic_fifo
) {
2126 DWC_DEBUGPL(DBG_CIL
, "Total FIFO Size=%d\n",
2127 core_if
->total_fifo_size
);
2128 DWC_DEBUGPL(DBG_CIL
, "Rx FIFO Size=%d\n",
2129 params
->host_rx_fifo_size
);
2130 DWC_DEBUGPL(DBG_CIL
, "NP Tx FIFO Size=%d\n",
2131 params
->host_nperio_tx_fifo_size
);
2132 DWC_DEBUGPL(DBG_CIL
, "P Tx FIFO Size=%d\n",
2133 params
->host_perio_tx_fifo_size
);
2136 DWC_DEBUGPL(DBG_CIL
, "initial grxfsiz=%08x\n",
2137 DWC_READ_REG32(&global_regs
->grxfsiz
));
2138 DWC_WRITE_REG32(&global_regs
->grxfsiz
,
2139 params
->host_rx_fifo_size
);
2140 DWC_DEBUGPL(DBG_CIL
, "new grxfsiz=%08x\n",
2141 DWC_READ_REG32(&global_regs
->grxfsiz
));
2143 /* Non-periodic Tx FIFO */
2144 DWC_DEBUGPL(DBG_CIL
, "initial gnptxfsiz=%08x\n",
2145 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
2146 nptxfifosize
.b
.depth
= params
->host_nperio_tx_fifo_size
;
2147 nptxfifosize
.b
.startaddr
= params
->host_rx_fifo_size
;
2148 DWC_WRITE_REG32(&global_regs
->gnptxfsiz
, nptxfifosize
.d32
);
2149 DWC_DEBUGPL(DBG_CIL
, "new gnptxfsiz=%08x\n",
2150 DWC_READ_REG32(&global_regs
->gnptxfsiz
));
2152 /* Periodic Tx FIFO */
2153 DWC_DEBUGPL(DBG_CIL
, "initial hptxfsiz=%08x\n",
2154 DWC_READ_REG32(&global_regs
->hptxfsiz
));
2155 ptxfifosize
.b
.depth
= params
->host_perio_tx_fifo_size
;
2156 ptxfifosize
.b
.startaddr
=
2157 nptxfifosize
.b
.startaddr
+ nptxfifosize
.b
.depth
;
2158 DWC_WRITE_REG32(&global_regs
->hptxfsiz
, ptxfifosize
.d32
);
2159 DWC_DEBUGPL(DBG_CIL
, "new hptxfsiz=%08x\n",
2160 DWC_READ_REG32(&global_regs
->hptxfsiz
));
2162 if (core_if
->en_multiple_tx_fifo
2163 && core_if
->snpsid
<= OTG_CORE_REV_2_94a
) {
2164 /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
2165 gdfifocfg
.d32
= DWC_READ_REG32(&global_regs
->gdfifocfg
);
2166 rxfsiz
= (DWC_READ_REG32(&global_regs
->grxfsiz
) & 0x0000ffff);
2167 nptxfsiz
= (DWC_READ_REG32(&global_regs
->gnptxfsiz
) >> 16);
2168 hptxfsiz
= (DWC_READ_REG32(&global_regs
->hptxfsiz
) >> 16);
2169 gdfifocfg
.b
.epinfobase
= rxfsiz
+ nptxfsiz
+ hptxfsiz
;
2170 DWC_WRITE_REG32(&global_regs
->gdfifocfg
, gdfifocfg
.d32
);
2174 /* TODO - check this */
2175 /* Clear Host Set HNP Enable in the OTG Control Register */
2176 gotgctl
.b
.hstsethnpen
= 1;
2177 DWC_MODIFY_REG32(&global_regs
->gotgctl
, gotgctl
.d32
, 0);
2178 /* Make sure the FIFOs are flushed. */
2179 dwc_otg_flush_tx_fifo(core_if
, 0x10 /* all TX FIFOs */ );
2180 dwc_otg_flush_rx_fifo(core_if
);
2182 /* Clear Host Set HNP Enable in the OTG Control Register */
2183 gotgctl
.b
.hstsethnpen
= 1;
2184 DWC_MODIFY_REG32(&global_regs
->gotgctl
, gotgctl
.d32
, 0);
2186 if (!core_if
->core_params
->dma_desc_enable
) {
2187 /* Flush out any leftover queued requests. */
2188 num_channels
= core_if
->core_params
->host_channels
;
2190 for (i
= 0; i
< num_channels
; i
++) {
2191 hc_regs
= core_if
->host_if
->hc_regs
[i
];
2192 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2196 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
2199 /* Halt all channels to put them into a known state. */
2200 for (i
= 0; i
< num_channels
; i
++) {
2202 hc_regs
= core_if
->host_if
->hc_regs
[i
];
2203 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2207 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
2208 DWC_DEBUGPL(DBG_HCDV
, "%s: Halt channel %d regs %p\n", __func__
, i
, hc_regs
);
2210 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2211 if (++count
> 1000) {
2213 ("%s: Unable to clear halt on channel %d (timeout HCCHAR 0x%X @%p)\n",
2214 __func__
, i
, hcchar
.d32
, &hc_regs
->hcchar
);
2218 } while (hcchar
.b
.chen
);
2222 /* Turn on the vbus power. */
2223 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if
->op_state
);
2224 if (core_if
->op_state
== A_HOST
) {
2225 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
2226 DWC_PRINTF("Init: Power Port (%d)\n", hprt0
.b
.prtpwr
);
2227 if (hprt0
.b
.prtpwr
== 0) {
2229 DWC_WRITE_REG32(host_if
->hprt0
, hprt0
.d32
);
2233 dwc_otg_enable_host_interrupts(core_if
);
2237 * Prepares a host channel for transferring packets to/from a specific
2238 * endpoint. The HCCHARn register is set up with the characteristics specified
2239 * in _hc. Host channel interrupts that may need to be serviced while this
2240 * transfer is in progress are enabled.
2242 * @param core_if Programming view of DWC_otg controller
2243 * @param hc Information needed to initialize the host channel
2245 void dwc_otg_hc_init(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
2247 hcintmsk_data_t hc_intr_mask
;
2248 hcchar_data_t hcchar
;
2249 hcsplt_data_t hcsplt
;
2251 uint8_t hc_num
= hc
->hc_num
;
2252 dwc_otg_host_if_t
*host_if
= core_if
->host_if
;
2253 dwc_otg_hc_regs_t
*hc_regs
= host_if
->hc_regs
[hc_num
];
2255 /* Clear old interrupt conditions for this host channel. */
2256 hc_intr_mask
.d32
= 0xFFFFFFFF;
2257 hc_intr_mask
.b
.reserved14_31
= 0;
2258 DWC_WRITE_REG32(&hc_regs
->hcint
, hc_intr_mask
.d32
);
2260 /* Enable channel interrupts required for this transfer. */
2261 hc_intr_mask
.d32
= 0;
2262 hc_intr_mask
.b
.chhltd
= 1;
2263 if (core_if
->dma_enable
) {
2264 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
2265 if (!core_if
->dma_desc_enable
)
2266 hc_intr_mask
.b
.ahberr
= 1;
2268 if (hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
)
2269 hc_intr_mask
.b
.xfercompl
= 1;
2272 if (hc
->error_state
&& !hc
->do_split
&&
2273 hc
->ep_type
!= DWC_OTG_EP_TYPE_ISOC
) {
2274 hc_intr_mask
.b
.ack
= 1;
2276 hc_intr_mask
.b
.datatglerr
= 1;
2277 if (hc
->ep_type
!= DWC_OTG_EP_TYPE_INTR
) {
2278 hc_intr_mask
.b
.nak
= 1;
2283 switch (hc
->ep_type
) {
2284 case DWC_OTG_EP_TYPE_CONTROL
:
2285 case DWC_OTG_EP_TYPE_BULK
:
2286 hc_intr_mask
.b
.xfercompl
= 1;
2287 hc_intr_mask
.b
.stall
= 1;
2288 hc_intr_mask
.b
.xacterr
= 1;
2289 hc_intr_mask
.b
.datatglerr
= 1;
2291 hc_intr_mask
.b
.bblerr
= 1;
2293 hc_intr_mask
.b
.nak
= 1;
2294 hc_intr_mask
.b
.nyet
= 1;
2296 hc_intr_mask
.b
.ack
= 1;
2301 hc_intr_mask
.b
.nak
= 1;
2302 if (hc
->complete_split
) {
2303 hc_intr_mask
.b
.nyet
= 1;
2305 hc_intr_mask
.b
.ack
= 1;
2309 if (hc
->error_state
) {
2310 hc_intr_mask
.b
.ack
= 1;
2313 case DWC_OTG_EP_TYPE_INTR
:
2314 hc_intr_mask
.b
.xfercompl
= 1;
2315 hc_intr_mask
.b
.nak
= 1;
2316 hc_intr_mask
.b
.stall
= 1;
2317 hc_intr_mask
.b
.xacterr
= 1;
2318 hc_intr_mask
.b
.datatglerr
= 1;
2319 hc_intr_mask
.b
.frmovrun
= 1;
2322 hc_intr_mask
.b
.bblerr
= 1;
2324 if (hc
->error_state
) {
2325 hc_intr_mask
.b
.ack
= 1;
2328 if (hc
->complete_split
) {
2329 hc_intr_mask
.b
.nyet
= 1;
2331 hc_intr_mask
.b
.ack
= 1;
2335 case DWC_OTG_EP_TYPE_ISOC
:
2336 hc_intr_mask
.b
.xfercompl
= 1;
2337 hc_intr_mask
.b
.frmovrun
= 1;
2338 hc_intr_mask
.b
.ack
= 1;
2341 hc_intr_mask
.b
.xacterr
= 1;
2342 hc_intr_mask
.b
.bblerr
= 1;
2347 DWC_WRITE_REG32(&hc_regs
->hcintmsk
, hc_intr_mask
.d32
);
2350 * Program the HCCHARn register with the endpoint characteristics for
2351 * the current transfer.
2354 hcchar
.b
.devaddr
= hc
->dev_addr
;
2355 hcchar
.b
.epnum
= hc
->ep_num
;
2356 hcchar
.b
.epdir
= hc
->ep_is_in
;
2357 hcchar
.b
.lspddev
= (hc
->speed
== DWC_OTG_EP_SPEED_LOW
);
2358 hcchar
.b
.eptype
= hc
->ep_type
;
2359 hcchar
.b
.mps
= hc
->max_packet
;
2361 DWC_WRITE_REG32(&host_if
->hc_regs
[hc_num
]->hcchar
, hcchar
.d32
);
2363 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d, Dev Addr %d, EP #%d\n",
2364 __func__
, hc
->hc_num
, hcchar
.b
.devaddr
, hcchar
.b
.epnum
);
2365 DWC_DEBUGPL(DBG_HCDV
, " Is In %d, Is Low Speed %d, EP Type %d, "
2366 "Max Pkt %d, Multi Cnt %d\n",
2367 hcchar
.b
.epdir
, hcchar
.b
.lspddev
, hcchar
.b
.eptype
,
2368 hcchar
.b
.mps
, hcchar
.b
.multicnt
);
2371 * Program the HCSPLIT register for SPLITs
2375 DWC_DEBUGPL(DBG_HCDV
, "Programming HC %d with split --> %s\n",
2377 hc
->complete_split
? "CSPLIT" : "SSPLIT");
2378 hcsplt
.b
.compsplt
= hc
->complete_split
;
2379 hcsplt
.b
.xactpos
= hc
->xact_pos
;
2380 hcsplt
.b
.hubaddr
= hc
->hub_addr
;
2381 hcsplt
.b
.prtaddr
= hc
->port_addr
;
2382 DWC_DEBUGPL(DBG_HCDV
, "\t comp split %d\n", hc
->complete_split
);
2383 DWC_DEBUGPL(DBG_HCDV
, "\t xact pos %d\n", hc
->xact_pos
);
2384 DWC_DEBUGPL(DBG_HCDV
, "\t hub addr %d\n", hc
->hub_addr
);
2385 DWC_DEBUGPL(DBG_HCDV
, "\t port addr %d\n", hc
->port_addr
);
2386 DWC_DEBUGPL(DBG_HCDV
, "\t is_in %d\n", hc
->ep_is_in
);
2387 DWC_DEBUGPL(DBG_HCDV
, "\t Max Pkt: %d\n", hcchar
.b
.mps
);
2388 DWC_DEBUGPL(DBG_HCDV
, "\t xferlen: %d\n", hc
->xfer_len
);
2390 DWC_WRITE_REG32(&host_if
->hc_regs
[hc_num
]->hcsplt
, hcsplt
.d32
);
2395 * Attempts to halt a host channel. This function should only be called in
2396 * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2397 * normal circumstances in DMA mode, the controller halts the channel when the
2398 * transfer is complete or a condition occurs that requires application
2401 * In slave mode, checks for a free request queue entry, then sets the Channel
2402 * Enable and Channel Disable bits of the Host Channel Characteristics
2403 * register of the specified channel to intiate the halt. If there is no free
2404 * request queue entry, sets only the Channel Disable bit of the HCCHARn
2405 * register to flush requests for this channel. In the latter case, sets a
2406 * flag to indicate that the host channel needs to be halted when a request
2407 * queue slot is open.
2409 * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2410 * HCCHARn register. The controller ensures there is space in the request
2411 * queue before submitting the halt request.
2413 * Some time may elapse before the core flushes any posted requests for this
2414 * host channel and halts. The Channel Halted interrupt handler completes the
2415 * deactivation of the host channel.
2417 * @param core_if Controller register interface.
2418 * @param hc Host channel to halt.
2419 * @param halt_status Reason for halting the channel.
2421 void dwc_otg_hc_halt(dwc_otg_core_if_t
* core_if
,
2422 dwc_hc_t
* hc
, dwc_otg_halt_status_e halt_status
)
2424 gnptxsts_data_t nptxsts
;
2425 hptxsts_data_t hptxsts
;
2426 hcchar_data_t hcchar
;
2427 dwc_otg_hc_regs_t
*hc_regs
;
2428 dwc_otg_core_global_regs_t
*global_regs
;
2429 dwc_otg_host_global_regs_t
*host_global_regs
;
2431 hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
2432 global_regs
= core_if
->core_global_regs
;
2433 host_global_regs
= core_if
->host_if
->host_global_regs
;
2435 DWC_ASSERT(!(halt_status
== DWC_OTG_HC_XFER_NO_HALT_STATUS
),
2436 "halt_status = %d\n", halt_status
);
2438 if (halt_status
== DWC_OTG_HC_XFER_URB_DEQUEUE
||
2439 halt_status
== DWC_OTG_HC_XFER_AHB_ERR
) {
2441 * Disable all channel interrupts except Ch Halted. The QTD
2442 * and QH state associated with this transfer has been cleared
2443 * (in the case of URB_DEQUEUE), so the channel needs to be
2444 * shut down carefully to prevent crashes.
2446 hcintmsk_data_t hcintmsk
;
2448 hcintmsk
.b
.chhltd
= 1;
2449 DWC_WRITE_REG32(&hc_regs
->hcintmsk
, hcintmsk
.d32
);
2452 * Make sure no other interrupts besides halt are currently
2453 * pending. Handling another interrupt could cause a crash due
2454 * to the QTD and QH state.
2456 DWC_WRITE_REG32(&hc_regs
->hcint
, ~hcintmsk
.d32
);
2459 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2460 * even if the channel was already halted for some other
2463 hc
->halt_status
= halt_status
;
2465 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2466 if (hcchar
.b
.chen
== 0) {
2468 * The channel is either already halted or it hasn't
2469 * started yet. In DMA mode, the transfer may halt if
2470 * it finishes normally or a condition occurs that
2471 * requires driver intervention. Don't want to halt
2472 * the channel again. In either Slave or DMA mode,
2473 * it's possible that the transfer has been assigned
2474 * to a channel, but not started yet when an URB is
2475 * dequeued. Don't want to halt a channel that hasn't
2481 if (hc
->halt_pending
) {
2483 * A halt has already been issued for this channel. This might
2484 * happen when a transfer is aborted by a higher level in
2489 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2490 __func__
, hc
->hc_num
);
2496 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2498 /* No need to set the bit in DDMA for disabling the channel */
2499 //TODO check it everywhere channel is disabled
2500 if (!core_if
->core_params
->dma_desc_enable
)
2504 if (!core_if
->dma_enable
) {
2505 /* Check for space in the request queue to issue the halt. */
2506 if (hc
->ep_type
== DWC_OTG_EP_TYPE_CONTROL
||
2507 hc
->ep_type
== DWC_OTG_EP_TYPE_BULK
) {
2508 nptxsts
.d32
= DWC_READ_REG32(&global_regs
->gnptxsts
);
2509 if (nptxsts
.b
.nptxqspcavail
== 0) {
2514 DWC_READ_REG32(&host_global_regs
->hptxsts
);
2515 if ((hptxsts
.b
.ptxqspcavail
== 0)
2516 || (core_if
->queuing_high_bandwidth
)) {
2521 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
2523 hc
->halt_status
= halt_status
;
2525 if (hcchar
.b
.chen
) {
2526 hc
->halt_pending
= 1;
2527 hc
->halt_on_queue
= 0;
2529 hc
->halt_on_queue
= 1;
2532 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, hc
->hc_num
);
2533 DWC_DEBUGPL(DBG_HCDV
, " hcchar: 0x%08x\n", hcchar
.d32
);
2534 DWC_DEBUGPL(DBG_HCDV
, " halt_pending: %d\n", hc
->halt_pending
);
2535 DWC_DEBUGPL(DBG_HCDV
, " halt_on_queue: %d\n", hc
->halt_on_queue
);
2536 DWC_DEBUGPL(DBG_HCDV
, " halt_status: %d\n", hc
->halt_status
);
2542 * Clears the transfer state for a host channel. This function is normally
2543 * called after a transfer is done and the host channel is being released.
2545 * @param core_if Programming view of DWC_otg controller.
2546 * @param hc Identifies the host channel to clean up.
2548 void dwc_otg_hc_cleanup(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
2550 dwc_otg_hc_regs_t
*hc_regs
;
2552 hc
->xfer_started
= 0;
2555 * Clear channel interrupt enables and any unhandled channel interrupt
2558 hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
2559 DWC_WRITE_REG32(&hc_regs
->hcintmsk
, 0);
2560 DWC_WRITE_REG32(&hc_regs
->hcint
, 0xFFFFFFFF);
2562 DWC_TIMER_CANCEL(core_if
->hc_xfer_timer
[hc
->hc_num
]);
2567 * Sets the channel property that indicates in which frame a periodic transfer
2568 * should occur. This is always set to the _next_ frame. This function has no
2569 * effect on non-periodic transfers.
2571 * @param core_if Programming view of DWC_otg controller.
2572 * @param hc Identifies the host channel to set up and its properties.
2573 * @param hcchar Current value of the HCCHAR register for the specified host
2576 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t
* core_if
,
2577 dwc_hc_t
* hc
, hcchar_data_t
* hcchar
)
2579 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
||
2580 hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
) {
2583 DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hfnum
);
2585 /* 1 if _next_ frame is odd, 0 if it's even */
2586 hcchar
->b
.oddfrm
= (hfnum
.b
.frnum
& 0x1) ? 0 : 1;
2588 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
&& hc
->do_split
2589 && !hc
->complete_split
) {
2590 switch (hfnum
.b
.frnum
& 0x7) {
2592 core_if
->hfnum_7_samples
++;
2593 core_if
->hfnum_7_frrem_accum
+= hfnum
.b
.frrem
;
2596 core_if
->hfnum_0_samples
++;
2597 core_if
->hfnum_0_frrem_accum
+= hfnum
.b
.frrem
;
2600 core_if
->hfnum_other_samples
++;
2601 core_if
->hfnum_other_frrem_accum
+=
2611 void hc_xfer_timeout(void *ptr
)
2613 hc_xfer_info_t
*xfer_info
= NULL
;
2617 xfer_info
= (hc_xfer_info_t
*) ptr
;
2619 if (!xfer_info
->hc
) {
2620 DWC_ERROR("xfer_info->hc = %p\n", xfer_info
->hc
);
2624 hc_num
= xfer_info
->hc
->hc_num
;
2625 DWC_WARN("%s: timeout on channel %d\n", __func__
, hc_num
);
2626 DWC_WARN(" start_hcchar_val 0x%08x\n",
2627 xfer_info
->core_if
->start_hcchar_val
[hc_num
]);
2631 void ep_xfer_timeout(void *ptr
)
2633 ep_xfer_info_t
*xfer_info
= NULL
;
2635 dctl_data_t dctl
= {.d32
= 0 };
2636 gintsts_data_t gintsts
= {.d32
= 0 };
2637 gintmsk_data_t gintmsk
= {.d32
= 0 };
2640 xfer_info
= (ep_xfer_info_t
*) ptr
;
2642 if (!xfer_info
->ep
) {
2643 DWC_ERROR("xfer_info->ep = %p\n", xfer_info
->ep
);
2647 ep_num
= xfer_info
->ep
->num
;
2648 DWC_WARN("%s: timeout on endpoit %d\n", __func__
, ep_num
);
2649 /* Put the sate to 2 as it was time outed */
2650 xfer_info
->state
= 2;
2653 DWC_READ_REG32(&xfer_info
->core_if
->dev_if
->dev_global_regs
->dctl
);
2655 DWC_READ_REG32(&xfer_info
->core_if
->core_global_regs
->gintsts
);
2657 DWC_READ_REG32(&xfer_info
->core_if
->core_global_regs
->gintmsk
);
2659 if (!gintmsk
.b
.goutnakeff
) {
2661 gintmsk
.b
.goutnakeff
= 1;
2662 DWC_WRITE_REG32(&xfer_info
->core_if
->core_global_regs
->gintmsk
,
2667 if (!gintsts
.b
.goutnakeff
) {
2668 dctl
.b
.sgoutnak
= 1;
2670 DWC_WRITE_REG32(&xfer_info
->core_if
->dev_if
->dev_global_regs
->dctl
,
2675 void set_pid_isoc(dwc_hc_t
* hc
)
2677 /* Set up the initial PID for the transfer. */
2678 if (hc
->speed
== DWC_OTG_EP_SPEED_HIGH
) {
2680 if (hc
->multi_count
== 1) {
2681 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA0
;
2682 } else if (hc
->multi_count
== 2) {
2683 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA1
;
2685 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA2
;
2688 if (hc
->multi_count
== 1) {
2689 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA0
;
2691 hc
->data_pid_start
= DWC_OTG_HC_PID_MDATA
;
2695 hc
->data_pid_start
= DWC_OTG_HC_PID_DATA0
;
2700 * This function does the setup for a data transfer for a host channel and
2701 * starts the transfer. May be called in either Slave mode or DMA mode. In
2702 * Slave mode, the caller must ensure that there is sufficient space in the
2703 * request queue and Tx Data FIFO.
2705 * For an OUT transfer in Slave mode, it loads a data packet into the
2706 * appropriate FIFO. If necessary, additional data packets will be loaded in
2709 * For an IN transfer in Slave mode, a data packet is requested. The data
2710 * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2711 * additional data packets are requested in the Host ISR.
2713 * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2714 * register along with a packet count of 1 and the channel is enabled. This
2715 * causes a single PING transaction to occur. Other fields in HCTSIZ are
2716 * simply set to 0 since no data transfer occurs in this case.
2718 * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2719 * all the information required to perform the subsequent data transfer. In
2720 * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2721 * controller performs the entire PING protocol, then starts the data
2724 * @param core_if Programming view of DWC_otg controller.
2725 * @param hc Information needed to initialize the host channel. The xfer_len
2726 * value may be reduced to accommodate the max widths of the XferSize and
2727 * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2728 * to reflect the final xfer_len value.
2730 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
2732 hcchar_data_t hcchar
;
2733 hctsiz_data_t hctsiz
;
2734 uint16_t num_packets
;
2735 uint32_t max_hc_xfer_size
= core_if
->core_params
->max_transfer_size
;
2736 uint16_t max_hc_pkt_count
= core_if
->core_params
->max_packet_count
;
2737 dwc_otg_hc_regs_t
*hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
2742 if (!core_if
->dma_enable
) {
2743 dwc_otg_hc_do_ping(core_if
, hc
);
2744 hc
->xfer_started
= 1;
2754 if (hc
->complete_split
&& !hc
->ep_is_in
) {
2755 /* For CSPLIT OUT Transfer, set the size to 0 so the
2756 * core doesn't expect any data written to the FIFO */
2758 } else if (hc
->ep_is_in
|| (hc
->xfer_len
> hc
->max_packet
)) {
2759 hc
->xfer_len
= hc
->max_packet
;
2760 } else if (!hc
->ep_is_in
&& (hc
->xfer_len
> 188)) {
2764 hctsiz
.b
.xfersize
= hc
->xfer_len
;
2767 * Ensure that the transfer length and packet count will fit
2768 * in the widths allocated for them in the HCTSIZn register.
2770 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
||
2771 hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
) {
2773 * Make sure the transfer size is no larger than one
2774 * (micro)frame's worth of data. (A check was done
2775 * when the periodic transfer was accepted to ensure
2776 * that a (micro)frame's worth of data can be
2777 * programmed into a channel.)
2779 uint32_t max_periodic_len
=
2780 hc
->multi_count
* hc
->max_packet
;
2781 if (hc
->xfer_len
> max_periodic_len
) {
2782 hc
->xfer_len
= max_periodic_len
;
2785 } else if (hc
->xfer_len
> max_hc_xfer_size
) {
2786 /* Make sure that xfer_len is a multiple of max packet size. */
2787 hc
->xfer_len
= max_hc_xfer_size
- hc
->max_packet
+ 1;
2790 if (hc
->xfer_len
> 0) {
2792 (hc
->xfer_len
+ hc
->max_packet
-
2793 1) / hc
->max_packet
;
2794 if (num_packets
> max_hc_pkt_count
) {
2795 num_packets
= max_hc_pkt_count
;
2796 hc
->xfer_len
= num_packets
* hc
->max_packet
;
2799 /* Need 1 packet for transfer length of 0. */
2804 /* Always program an integral # of max packets for IN transfers. */
2805 hc
->xfer_len
= num_packets
* hc
->max_packet
;
2808 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
||
2809 hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
) {
2811 * Make sure that the multi_count field matches the
2812 * actual transfer length.
2814 hc
->multi_count
= num_packets
;
2817 if (hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
)
2820 hctsiz
.b
.xfersize
= hc
->xfer_len
;
2823 hc
->start_pkt_count
= num_packets
;
2824 hctsiz
.b
.pktcnt
= num_packets
;
2825 hctsiz
.b
.pid
= hc
->data_pid_start
;
2826 DWC_WRITE_REG32(&hc_regs
->hctsiz
, hctsiz
.d32
);
2828 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, hc
->hc_num
);
2829 DWC_DEBUGPL(DBG_HCDV
, " Xfer Size: %d\n", hctsiz
.b
.xfersize
);
2830 DWC_DEBUGPL(DBG_HCDV
, " Num Pkts: %d\n", hctsiz
.b
.pktcnt
);
2831 DWC_DEBUGPL(DBG_HCDV
, " Start PID: %d\n", hctsiz
.b
.pid
);
2833 if (core_if
->dma_enable
) {
2835 if (hc
->align_buff
) {
2836 dma_addr
= hc
->align_buff
;
2838 dma_addr
= ((unsigned long)hc
->xfer_buff
& 0xffffffff);
2840 DWC_WRITE_REG32(&hc_regs
->hcdma
, dma_addr
);
2843 /* Start the split */
2845 hcsplt_data_t hcsplt
;
2846 hcsplt
.d32
= DWC_READ_REG32(&hc_regs
->hcsplt
);
2847 hcsplt
.b
.spltena
= 1;
2848 DWC_WRITE_REG32(&hc_regs
->hcsplt
, hcsplt
.d32
);
2851 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2852 hcchar
.b
.multicnt
= hc
->multi_count
;
2853 hc_set_even_odd_frame(core_if
, hc
, &hcchar
);
2855 core_if
->start_hcchar_val
[hc
->hc_num
] = hcchar
.d32
;
2856 if (hcchar
.b
.chdis
) {
2857 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2858 __func__
, hc
->hc_num
, hcchar
.d32
);
2862 /* Set host channel enable after all other setup is complete. */
2865 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
2867 hc
->xfer_started
= 1;
2870 if (!core_if
->dma_enable
&& !hc
->ep_is_in
&& hc
->xfer_len
> 0) {
2871 /* Load OUT packet into the appropriate Tx FIFO. */
2872 dwc_otg_hc_write_packet(core_if
, hc
);
2875 if (hc
->ep_type
!= DWC_OTG_EP_TYPE_INTR
) {
2876 DWC_DEBUGPL(DBG_HCDV
, "transfer %d from core_if %p\n",
2877 hc
->hc_num
, core_if
);//GRAYG
2878 core_if
->hc_xfer_info
[hc
->hc_num
].core_if
= core_if
;
2879 core_if
->hc_xfer_info
[hc
->hc_num
].hc
= hc
;
2881 /* Start a timer for this transfer. */
2882 DWC_TIMER_SCHEDULE(core_if
->hc_xfer_timer
[hc
->hc_num
], 10000);
2888 * This function does the setup for a data transfer for a host channel
2889 * and starts the transfer in Descriptor DMA mode.
2891 * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set.
2892 * Sets PID and NTD values. For periodic transfers
2893 * initializes SCHED_INFO field with micro-frame bitmap.
2895 * Initializes HCDMA register with descriptor list address and CTD value
2896 * then starts the transfer via enabling the channel.
2898 * @param core_if Programming view of DWC_otg controller.
2899 * @param hc Information needed to initialize the host channel.
2901 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
2903 dwc_otg_hc_regs_t
*hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
2904 hcchar_data_t hcchar
;
2905 hctsiz_data_t hctsiz
;
2911 hctsiz
.b_ddma
.dopng
= 1;
2913 if (hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
)
2916 /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
2917 hctsiz
.b_ddma
.pid
= hc
->data_pid_start
;
2918 hctsiz
.b_ddma
.ntd
= hc
->ntd
- 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
2919 hctsiz
.b_ddma
.schinfo
= hc
->schinfo
; /* Non-zero only for high-speed interrupt endpoints */
2921 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, hc
->hc_num
);
2922 DWC_DEBUGPL(DBG_HCDV
, " Start PID: %d\n", hctsiz
.b
.pid
);
2923 DWC_DEBUGPL(DBG_HCDV
, " NTD: %d\n", hctsiz
.b_ddma
.ntd
);
2925 DWC_WRITE_REG32(&hc_regs
->hctsiz
, hctsiz
.d32
);
2928 hcdma
.b
.dma_addr
= ((uint32_t) hc
->desc_list_addr
) >> 11;
2930 /* Always start from first descriptor. */
2932 DWC_WRITE_REG32(&hc_regs
->hcdma
, hcdma
.d32
);
2934 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
2935 hcchar
.b
.multicnt
= hc
->multi_count
;
2938 core_if
->start_hcchar_val
[hc
->hc_num
] = hcchar
.d32
;
2939 if (hcchar
.b
.chdis
) {
2940 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2941 __func__
, hc
->hc_num
, hcchar
.d32
);
2945 /* Set host channel enable after all other setup is complete. */
2949 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
2951 hc
->xfer_started
= 1;
2955 if ((hc
->ep_type
!= DWC_OTG_EP_TYPE_INTR
)
2956 && (hc
->ep_type
!= DWC_OTG_EP_TYPE_ISOC
)) {
2957 DWC_DEBUGPL(DBG_HCDV
, "DMA transfer %d from core_if %p\n",
2958 hc
->hc_num
, core_if
);//GRAYG
2959 core_if
->hc_xfer_info
[hc
->hc_num
].core_if
= core_if
;
2960 core_if
->hc_xfer_info
[hc
->hc_num
].hc
= hc
;
2961 /* Start a timer for this transfer. */
2962 DWC_TIMER_SCHEDULE(core_if
->hc_xfer_timer
[hc
->hc_num
], 10000);
2969 * This function continues a data transfer that was started by previous call
2970 * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
2971 * sufficient space in the request queue and Tx Data FIFO. This function
2972 * should only be called in Slave mode. In DMA mode, the controller acts
2973 * autonomously to complete transfers programmed to a host channel.
2975 * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
2976 * if there is any data remaining to be queued. For an IN transfer, another
2977 * data packet is always requested. For the SETUP phase of a control transfer,
2978 * this function does nothing.
2980 * @return 1 if a new request is queued, 0 if no more requests are required
2981 * for this transfer.
2983 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
2985 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, hc
->hc_num
);
2988 /* SPLITs always queue just once per channel */
2990 } else if (hc
->data_pid_start
== DWC_OTG_HC_PID_SETUP
) {
2991 /* SETUPs are queued only once since they can't be NAKed. */
2993 } else if (hc
->ep_is_in
) {
2995 * Always queue another request for other IN transfers. If
2996 * back-to-back INs are issued and NAKs are received for both,
2997 * the driver may still be processing the first NAK when the
2998 * second NAK is received. When the interrupt handler clears
2999 * the NAK interrupt for the first NAK, the second NAK will
3000 * not be seen. So we can't depend on the NAK interrupt
3001 * handler to requeue a NAKed request. Instead, IN requests
3002 * are issued each time this function is called. When the
3003 * transfer completes, the extra requests for the channel will
3006 hcchar_data_t hcchar
;
3007 dwc_otg_hc_regs_t
*hc_regs
=
3008 core_if
->host_if
->hc_regs
[hc
->hc_num
];
3010 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
3011 hc_set_even_odd_frame(core_if
, hc
, &hcchar
);
3014 DWC_DEBUGPL(DBG_HCDV
, " IN xfer: hcchar = 0x%08x\n",
3016 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
3020 /* OUT transfers. */
3021 if (hc
->xfer_count
< hc
->xfer_len
) {
3022 if (hc
->ep_type
== DWC_OTG_EP_TYPE_INTR
||
3023 hc
->ep_type
== DWC_OTG_EP_TYPE_ISOC
) {
3024 hcchar_data_t hcchar
;
3025 dwc_otg_hc_regs_t
*hc_regs
;
3026 hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
3027 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
3028 hc_set_even_odd_frame(core_if
, hc
, &hcchar
);
3031 /* Load OUT packet into the appropriate Tx FIFO. */
3032 dwc_otg_hc_write_packet(core_if
, hc
);
3042 * Starts a PING transfer. This function should only be called in Slave mode.
3043 * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
3045 void dwc_otg_hc_do_ping(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
3047 hcchar_data_t hcchar
;
3048 hctsiz_data_t hctsiz
;
3049 dwc_otg_hc_regs_t
*hc_regs
= core_if
->host_if
->hc_regs
[hc
->hc_num
];
3051 DWC_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, hc
->hc_num
);
3055 hctsiz
.b
.pktcnt
= 1;
3056 DWC_WRITE_REG32(&hc_regs
->hctsiz
, hctsiz
.d32
);
3058 hcchar
.d32
= DWC_READ_REG32(&hc_regs
->hcchar
);
3061 DWC_WRITE_REG32(&hc_regs
->hcchar
, hcchar
.d32
);
3065 * This function writes a packet into the Tx FIFO associated with the Host
3066 * Channel. For a channel associated with a non-periodic EP, the non-periodic
3067 * Tx FIFO is written. For a channel associated with a periodic EP, the
3068 * periodic Tx FIFO is written. This function should only be called in Slave
3071 * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
3072 * then number of bytes written to the Tx FIFO.
3074 void dwc_otg_hc_write_packet(dwc_otg_core_if_t
* core_if
, dwc_hc_t
* hc
)
3077 uint32_t remaining_count
;
3078 uint32_t byte_count
;
3079 uint32_t dword_count
;
3081 uint32_t *data_buff
= (uint32_t *) (hc
->xfer_buff
);
3082 uint32_t *data_fifo
= core_if
->data_fifo
[hc
->hc_num
];
3084 remaining_count
= hc
->xfer_len
- hc
->xfer_count
;
3085 if (remaining_count
> hc
->max_packet
) {
3086 byte_count
= hc
->max_packet
;
3088 byte_count
= remaining_count
;
3091 dword_count
= (byte_count
+ 3) / 4;
3093 if ((((unsigned long)data_buff
) & 0x3) == 0) {
3094 /* xfer_buff is DWORD aligned. */
3095 for (i
= 0; i
< dword_count
; i
++, data_buff
++) {
3096 DWC_WRITE_REG32(data_fifo
, *data_buff
);
3099 /* xfer_buff is not DWORD aligned. */
3100 for (i
= 0; i
< dword_count
; i
++, data_buff
++) {
3103 (data_buff
[0] | data_buff
[1] << 8 | data_buff
[2] <<
3104 16 | data_buff
[3] << 24);
3105 DWC_WRITE_REG32(data_fifo
, data
);
3109 hc
->xfer_count
+= byte_count
;
3110 hc
->xfer_buff
+= byte_count
;
3114 * Gets the current USB frame number. This is the frame number from the last
3117 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t
* core_if
)
3120 dsts
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dsts
);
3122 /* read current frame/microframe number from DSTS register */
3123 return dsts
.b
.soffn
;
3127 * Calculates and gets the frame Interval value of HFIR register according PHY
3128 * type and speed.The application can modify a value of HFIR register only after
3129 * the Port Enable bit of the Host Port Control and Status register
3130 * (HPRT.PrtEnaPort) has been set.
3133 uint32_t calc_frame_interval(dwc_otg_core_if_t
* core_if
)
3135 gusbcfg_data_t usbcfg
;
3136 hwcfg2_data_t hwcfg2
;
3138 int clock
= 60; // default value
3139 usbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
3140 hwcfg2
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg2
);
3141 hprt0
.d32
= DWC_READ_REG32(core_if
->host_if
->hprt0
);
3142 if (!usbcfg
.b
.physel
&& usbcfg
.b
.ulpi_utmi_sel
&& !usbcfg
.b
.phyif
)
3144 if (usbcfg
.b
.physel
&& hwcfg2
.b
.fs_phy_type
== 3)
3146 if (!usbcfg
.b
.phylpwrclksel
&& !usbcfg
.b
.physel
&&
3147 !usbcfg
.b
.ulpi_utmi_sel
&& usbcfg
.b
.phyif
)
3149 if (!usbcfg
.b
.phylpwrclksel
&& !usbcfg
.b
.physel
&&
3150 !usbcfg
.b
.ulpi_utmi_sel
&& !usbcfg
.b
.phyif
)
3152 if (usbcfg
.b
.phylpwrclksel
&& !usbcfg
.b
.physel
&&
3153 !usbcfg
.b
.ulpi_utmi_sel
&& usbcfg
.b
.phyif
)
3155 if (usbcfg
.b
.physel
&& !usbcfg
.b
.phyif
&& hwcfg2
.b
.fs_phy_type
== 2)
3157 if (usbcfg
.b
.physel
&& hwcfg2
.b
.fs_phy_type
== 1)
3159 if (hprt0
.b
.prtspd
== 0)
3160 /* High speed case */
3161 return 125 * clock
- 1;
3164 return 1000 * clock
- 1;
3168 * This function reads a setup packet from the Rx FIFO into the destination
3169 * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3170 * Interrupt routine when a SETUP packet has been received in Slave mode.
3172 * @param core_if Programming view of DWC_otg controller.
3173 * @param dest Destination buffer for packet data.
3175 void dwc_otg_read_setup_packet(dwc_otg_core_if_t
* core_if
, uint32_t * dest
)
3177 device_grxsts_data_t status
;
3178 /* Get the 8 bytes of a setup transaction data */
3180 /* Pop 2 DWORDS off the receive data FIFO into memory */
3181 dest
[0] = DWC_READ_REG32(core_if
->data_fifo
[0]);
3182 dest
[1] = DWC_READ_REG32(core_if
->data_fifo
[0]);
3183 if (core_if
->snpsid
>= OTG_CORE_REV_3_00a
) {
3185 DWC_READ_REG32(&core_if
->core_global_regs
->grxstsp
);
3186 DWC_DEBUGPL(DBG_ANY
,
3187 "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n",
3188 status
.b
.epnum
, status
.b
.bcnt
, status
.b
.pktsts
,
3189 status
.b
.fn
, status
.b
.fn
);
3194 * This function enables EP0 OUT to receive SETUP packets and configures EP0
3195 * IN for transmitting packets. It is normally called when the
3196 * "Enumeration Done" interrupt occurs.
3198 * @param core_if Programming view of DWC_otg controller.
3199 * @param ep The EP0 data.
3201 void dwc_otg_ep0_activate(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3203 dwc_otg_dev_if_t
*dev_if
= core_if
->dev_if
;
3205 depctl_data_t diepctl
;
3206 depctl_data_t doepctl
;
3207 dctl_data_t dctl
= {.d32
= 0 };
3209 ep
->stp_rollover
= 0;
3210 /* Read the Device Status and Endpoint 0 Control registers */
3211 dsts
.d32
= DWC_READ_REG32(&dev_if
->dev_global_regs
->dsts
);
3212 diepctl
.d32
= DWC_READ_REG32(&dev_if
->in_ep_regs
[0]->diepctl
);
3213 doepctl
.d32
= DWC_READ_REG32(&dev_if
->out_ep_regs
[0]->doepctl
);
3215 /* Set the MPS of the IN EP based on the enumeration speed */
3216 switch (dsts
.b
.enumspd
) {
3217 case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ
:
3218 case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ
:
3219 case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ
:
3220 diepctl
.b
.mps
= DWC_DEP0CTL_MPS_64
;
3222 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ
:
3223 diepctl
.b
.mps
= DWC_DEP0CTL_MPS_8
;
3227 DWC_WRITE_REG32(&dev_if
->in_ep_regs
[0]->diepctl
, diepctl
.d32
);
3229 /* Enable OUT EP for receive */
3230 if (core_if
->snpsid
<= OTG_CORE_REV_2_94a
) {
3231 doepctl
.b
.epena
= 1;
3232 DWC_WRITE_REG32(&dev_if
->out_ep_regs
[0]->doepctl
, doepctl
.d32
);
3235 DWC_DEBUGPL(DBG_PCDV
, "doepctl0=%0x\n",
3236 DWC_READ_REG32(&dev_if
->out_ep_regs
[0]->doepctl
));
3237 DWC_DEBUGPL(DBG_PCDV
, "diepctl0=%0x\n",
3238 DWC_READ_REG32(&dev_if
->in_ep_regs
[0]->diepctl
));
3240 dctl
.b
.cgnpinnak
= 1;
3242 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->dctl
, dctl
.d32
, dctl
.d32
);
3243 DWC_DEBUGPL(DBG_PCDV
, "dctl=%0x\n",
3244 DWC_READ_REG32(&dev_if
->dev_global_regs
->dctl
));
3249 * This function activates an EP. The Device EP control register for
3250 * the EP is configured as defined in the ep structure. Note: This
3251 * function is not used for EP0.
3253 * @param core_if Programming view of DWC_otg controller.
3254 * @param ep The EP to activate.
3256 void dwc_otg_ep_activate(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3258 dwc_otg_dev_if_t
*dev_if
= core_if
->dev_if
;
3259 depctl_data_t depctl
;
3260 volatile uint32_t *addr
;
3261 daint_data_t daintmsk
= {.d32
= 0 };
3265 DWC_DEBUGPL(DBG_PCDV
, "%s() EP%d-%s\n", __func__
, ep
->num
,
3266 (ep
->is_in
? "IN" : "OUT"));
3268 #ifdef DWC_UTE_PER_IO
3269 ep
->xiso_frame_num
= 0xFFFFFFFF;
3270 ep
->xiso_active_xfers
= 0;
3271 ep
->xiso_queued_xfers
= 0;
3273 /* Read DEPCTLn register */
3274 if (ep
->is_in
== 1) {
3275 addr
= &dev_if
->in_ep_regs
[ep
->num
]->diepctl
;
3276 daintmsk
.ep
.in
= 1 << ep
->num
;
3278 addr
= &dev_if
->out_ep_regs
[ep
->num
]->doepctl
;
3279 daintmsk
.ep
.out
= 1 << ep
->num
;
3282 /* If the EP is already active don't change the EP Control
3284 depctl
.d32
= DWC_READ_REG32(addr
);
3285 if (!depctl
.b
.usbactep
) {
3286 depctl
.b
.mps
= ep
->maxpacket
;
3287 depctl
.b
.eptype
= ep
->type
;
3288 depctl
.b
.txfnum
= ep
->tx_fifo_num
;
3290 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
) {
3291 depctl
.b
.setd0pid
= 1; // ???
3293 depctl
.b
.setd0pid
= 1;
3295 depctl
.b
.usbactep
= 1;
3297 /* Update nextep_seq array and EPMSCNT in DCFG*/
3298 if (!(depctl
.b
.eptype
& 1) && (ep
->is_in
== 1)) { // NP IN EP
3299 for (i
= 0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
3300 if (core_if
->nextep_seq
[i
] == core_if
->first_in_nextep_seq
)
3303 core_if
->nextep_seq
[i
] = ep
->num
;
3304 core_if
->nextep_seq
[ep
->num
] = core_if
->first_in_nextep_seq
;
3305 depctl
.b
.nextep
= core_if
->nextep_seq
[ep
->num
];
3306 dcfg
.d32
= DWC_READ_REG32(&dev_if
->dev_global_regs
->dcfg
);
3308 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
3310 DWC_DEBUGPL(DBG_PCDV
,
3311 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3312 __func__
, core_if
->first_in_nextep_seq
);
3313 for (i
=0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
3314 DWC_DEBUGPL(DBG_PCDV
, "%2d\n",
3315 core_if
->nextep_seq
[i
]);
3321 DWC_WRITE_REG32(addr
, depctl
.d32
);
3322 DWC_DEBUGPL(DBG_PCDV
, "DEPCTL=%08x\n", DWC_READ_REG32(addr
));
3325 /* Enable the Interrupt for this EP */
3326 if (core_if
->multiproc_int_enable
) {
3327 if (ep
->is_in
== 1) {
3328 diepmsk_data_t diepmsk
= {.d32
= 0 };
3329 diepmsk
.b
.xfercompl
= 1;
3330 diepmsk
.b
.timeout
= 1;
3331 diepmsk
.b
.epdisabled
= 1;
3332 diepmsk
.b
.ahberr
= 1;
3333 diepmsk
.b
.intknepmis
= 1;
3334 if (!core_if
->en_multiple_tx_fifo
&& core_if
->dma_enable
)
3335 diepmsk
.b
.intknepmis
= 0;
3336 diepmsk
.b
.txfifoundrn
= 1; //?????
3337 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
) {
3344 if (core_if->dma_desc_enable) {
3349 if (core_if->dma_enable) {
3353 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->
3354 diepeachintmsk
[ep
->num
], diepmsk
.d32
);
3357 doepmsk_data_t doepmsk
= {.d32
= 0 };
3358 doepmsk
.b
.xfercompl
= 1;
3359 doepmsk
.b
.ahberr
= 1;
3360 doepmsk
.b
.epdisabled
= 1;
3361 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
)
3362 doepmsk
.b
.outtknepdis
= 1;
3366 if (core_if->dma_desc_enable) {
3371 doepmsk.b.babble = 1;
3375 DWC_WRITE_REG32(&dev_if
->dev_global_regs
->
3376 doepeachintmsk
[ep
->num
], doepmsk
.d32
);
3378 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->deachintmsk
,
3381 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
) {
3383 diepmsk_data_t diepmsk
= {.d32
= 0 };
3385 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->diepmsk
, 0, diepmsk
.d32
);
3387 doepmsk_data_t doepmsk
= {.d32
= 0 };
3388 doepmsk
.b
.outtknepdis
= 1;
3389 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->doepmsk
, 0, doepmsk
.d32
);
3392 DWC_MODIFY_REG32(&dev_if
->dev_global_regs
->daintmsk
,
3396 DWC_DEBUGPL(DBG_PCDV
, "DAINTMSK=%0x\n",
3397 DWC_READ_REG32(&dev_if
->dev_global_regs
->daintmsk
));
3399 ep
->stall_clear_flag
= 0;
3405 * This function deactivates an EP. This is done by clearing the USB Active
3406 * EP bit in the Device EP control register. Note: This function is not used
3407 * for EP0. EP0 cannot be deactivated.
3409 * @param core_if Programming view of DWC_otg controller.
3410 * @param ep The EP to deactivate.
3412 void dwc_otg_ep_deactivate(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3414 depctl_data_t depctl
= {.d32
= 0 };
3415 volatile uint32_t *addr
;
3416 daint_data_t daintmsk
= {.d32
= 0 };
3420 #ifdef DWC_UTE_PER_IO
3421 ep
->xiso_frame_num
= 0xFFFFFFFF;
3422 ep
->xiso_active_xfers
= 0;
3423 ep
->xiso_queued_xfers
= 0;
3426 /* Read DEPCTLn register */
3427 if (ep
->is_in
== 1) {
3428 addr
= &core_if
->dev_if
->in_ep_regs
[ep
->num
]->diepctl
;
3429 daintmsk
.ep
.in
= 1 << ep
->num
;
3431 addr
= &core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepctl
;
3432 daintmsk
.ep
.out
= 1 << ep
->num
;
3435 depctl
.d32
= DWC_READ_REG32(addr
);
3437 depctl
.b
.usbactep
= 0;
3439 /* Update nextep_seq array and EPMSCNT in DCFG*/
3440 if (!(depctl
.b
.eptype
& 1) && ep
->is_in
== 1) { // NP EP IN
3441 for (i
= 0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
3442 if (core_if
->nextep_seq
[i
] == ep
->num
)
3445 core_if
->nextep_seq
[i
] = core_if
->nextep_seq
[ep
->num
];
3446 if (core_if
->first_in_nextep_seq
== ep
->num
)
3447 core_if
->first_in_nextep_seq
= i
;
3448 core_if
->nextep_seq
[ep
->num
] = 0xff;
3449 depctl
.b
.nextep
= 0;
3451 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
3453 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
,
3456 DWC_DEBUGPL(DBG_PCDV
,
3457 "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3458 __func__
, core_if
->first_in_nextep_seq
);
3459 for (i
=0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
3460 DWC_DEBUGPL(DBG_PCDV
, "%2d\n", core_if
->nextep_seq
[i
]);
3465 depctl
.b
.txfnum
= 0;
3467 if (core_if
->dma_desc_enable
)
3470 DWC_WRITE_REG32(addr
, depctl
.d32
);
3471 depctl
.d32
= DWC_READ_REG32(addr
);
3472 if (core_if
->dma_enable
&& ep
->type
== DWC_OTG_EP_TYPE_ISOC
3473 && depctl
.b
.epena
) {
3474 depctl_data_t depctl
= {.d32
= 0};
3476 diepint_data_t diepint
= {.d32
= 0};
3479 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->
3480 diepctl
, depctl
.d32
);
3484 DWC_READ_REG32(&core_if
->
3485 dev_if
->in_ep_regs
[ep
->num
]->
3487 } while (!diepint
.b
.inepnakeff
);
3488 diepint
.b
.inepnakeff
= 1;
3489 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->
3490 diepint
, diepint
.d32
);
3493 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->
3494 diepctl
, depctl
.d32
);
3498 DWC_READ_REG32(&core_if
->
3499 dev_if
->in_ep_regs
[ep
->num
]->
3501 } while (!diepint
.b
.epdisabled
);
3502 diepint
.b
.epdisabled
= 1;
3503 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->
3504 diepint
, diepint
.d32
);
3506 dctl_data_t dctl
= {.d32
= 0};
3507 gintmsk_data_t gintsts
= {.d32
= 0};
3508 doepint_data_t doepint
= {.d32
= 0};
3509 dctl
.b
.sgoutnak
= 1;
3510 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->
3514 gintsts
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gintsts
);
3515 } while (!gintsts
.b
.goutnakeff
);
3517 gintsts
.b
.goutnakeff
= 1;
3518 DWC_WRITE_REG32(&core_if
->core_global_regs
->gintsts
, gintsts
.d32
);
3523 DWC_WRITE_REG32(&core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepctl
, depctl
.d32
);
3527 doepint
.d32
= DWC_READ_REG32(&core_if
->dev_if
->
3528 out_ep_regs
[ep
->num
]->doepint
);
3529 } while (!doepint
.b
.epdisabled
);
3531 doepint
.b
.epdisabled
= 1;
3532 DWC_WRITE_REG32(&core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepint
, doepint
.d32
);
3535 dctl
.b
.cgoutnak
= 1;
3536 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
, 0, dctl
.d32
);
3540 /* Disable the Interrupt for this EP */
3541 if (core_if
->multiproc_int_enable
) {
3542 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->deachintmsk
,
3545 if (ep
->is_in
== 1) {
3546 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->
3547 diepeachintmsk
[ep
->num
], 0);
3549 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->
3550 doepeachintmsk
[ep
->num
], 0);
3553 DWC_MODIFY_REG32(&core_if
->dev_if
->dev_global_regs
->daintmsk
,
3560 * This function initializes dma descriptor chain.
3562 * @param core_if Programming view of DWC_otg controller.
3563 * @param ep The EP to start the transfer on.
3565 static void init_dma_desc_chain(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3567 dwc_otg_dev_dma_desc_t
*dma_desc
;
3571 unsigned maxxfer_local
, total_len
;
3573 if (!ep
->is_in
&& ep
->type
== DWC_OTG_EP_TYPE_INTR
&&
3574 (ep
->maxpacket
%4)) {
3575 maxxfer_local
= ep
->maxpacket
;
3576 total_len
= ep
->xfer_len
;
3578 maxxfer_local
= ep
->maxxfer
;
3579 total_len
= ep
->total_len
;
3582 ep
->desc_cnt
= (total_len
/ maxxfer_local
) +
3583 ((total_len
% maxxfer_local
) ? 1 : 0);
3588 if (ep
->desc_cnt
> MAX_DMA_DESC_CNT
)
3589 ep
->desc_cnt
= MAX_DMA_DESC_CNT
;
3591 dma_desc
= ep
->desc_addr
;
3592 if (maxxfer_local
== ep
->maxpacket
) {
3593 if ((total_len
% maxxfer_local
) &&
3594 (total_len
/maxxfer_local
< MAX_DMA_DESC_CNT
)) {
3595 xfer_est
= (ep
->desc_cnt
- 1) * maxxfer_local
+
3596 (total_len
% maxxfer_local
);
3598 xfer_est
= ep
->desc_cnt
* maxxfer_local
;
3600 xfer_est
= total_len
;
3602 for (i
= 0; i
< ep
->desc_cnt
; ++i
) {
3603 /** DMA Descriptor Setup */
3604 if (xfer_est
> maxxfer_local
) {
3605 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
3606 dma_desc
->status
.b
.l
= 0;
3607 dma_desc
->status
.b
.ioc
= 0;
3608 dma_desc
->status
.b
.sp
= 0;
3609 dma_desc
->status
.b
.bytes
= maxxfer_local
;
3610 dma_desc
->buf
= ep
->dma_addr
+ offset
;
3611 dma_desc
->status
.b
.sts
= 0;
3612 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
3614 xfer_est
-= maxxfer_local
;
3615 offset
+= maxxfer_local
;
3617 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
3618 dma_desc
->status
.b
.l
= 1;
3619 dma_desc
->status
.b
.ioc
= 1;
3621 dma_desc
->status
.b
.sp
=
3623 ep
->maxpacket
) ? 1 : ((ep
->
3625 dma_desc
->status
.b
.bytes
= xfer_est
;
3627 if (maxxfer_local
== ep
->maxpacket
)
3628 dma_desc
->status
.b
.bytes
= xfer_est
;
3630 dma_desc
->status
.b
.bytes
=
3631 xfer_est
+ ((4 - (xfer_est
& 0x3)) & 0x3);
3634 dma_desc
->buf
= ep
->dma_addr
+ offset
;
3635 dma_desc
->status
.b
.sts
= 0;
3636 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
3642 * This function is called when to write ISOC data into appropriate dedicated
3645 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* dwc_ep
)
3647 dwc_otg_dev_if_t
*dev_if
= core_if
->dev_if
;
3648 dwc_otg_dev_in_ep_regs_t
*ep_regs
;
3649 dtxfsts_data_t txstatus
= {.d32
= 0 };
3651 int epnum
= dwc_ep
->num
;
3654 DWC_DEBUGPL(DBG_PCD
, "Dedicated TxFifo Empty: %d \n", epnum
);
3656 ep_regs
= core_if
->dev_if
->in_ep_regs
[epnum
];
3658 len
= dwc_ep
->xfer_len
- dwc_ep
->xfer_count
;
3660 if (len
> dwc_ep
->maxpacket
) {
3661 len
= dwc_ep
->maxpacket
;
3664 dwords
= (len
+ 3) / 4;
3666 /* While there is space in the queue and space in the FIFO and
3667 * More data to tranfer, Write packets to the Tx FIFO */
3668 txstatus
.d32
= DWC_READ_REG32(&dev_if
->in_ep_regs
[epnum
]->dtxfsts
);
3669 DWC_DEBUGPL(DBG_PCDV
, "b4 dtxfsts[%d]=0x%08x\n", epnum
, txstatus
.d32
);
3671 while (txstatus
.b
.txfspcavail
> dwords
&&
3672 dwc_ep
->xfer_count
< dwc_ep
->xfer_len
&& dwc_ep
->xfer_len
!= 0) {
3673 /* Write the FIFO */
3674 dwc_otg_ep_write_packet(core_if
, dwc_ep
, 0);
3676 len
= dwc_ep
->xfer_len
- dwc_ep
->xfer_count
;
3677 if (len
> dwc_ep
->maxpacket
) {
3678 len
= dwc_ep
->maxpacket
;
3681 dwords
= (len
+ 3) / 4;
3683 DWC_READ_REG32(&dev_if
->in_ep_regs
[epnum
]->dtxfsts
);
3684 DWC_DEBUGPL(DBG_PCDV
, "dtxfsts[%d]=0x%08x\n", epnum
,
3688 DWC_DEBUGPL(DBG_PCDV
, "b4 dtxfsts[%d]=0x%08x\n", epnum
,
3689 DWC_READ_REG32(&dev_if
->in_ep_regs
[epnum
]->dtxfsts
));
3694 * This function does the setup for a data transfer for an EP and
3695 * starts the transfer. For an IN transfer, the packets will be
3696 * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3697 * the packets are unloaded from the Rx FIFO in the ISR. the ISR.
3699 * @param core_if Programming view of DWC_otg controller.
3700 * @param ep The EP to start the transfer on.
3703 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3705 depctl_data_t depctl
;
3706 deptsiz_data_t deptsiz
;
3707 gintmsk_data_t intr_mask
= {.d32
= 0 };
3709 DWC_DEBUGPL((DBG_PCDV
| DBG_CILV
), "%s()\n", __func__
);
3710 DWC_DEBUGPL(DBG_PCD
, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3711 "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
3712 ep
->num
, (ep
->is_in
? "IN" : "OUT"), ep
->xfer_len
,
3713 ep
->xfer_count
, ep
->xfer_buff
, ep
->start_xfer_buff
,
3716 if (ep
->is_in
== 1) {
3717 dwc_otg_dev_in_ep_regs_t
*in_regs
=
3718 core_if
->dev_if
->in_ep_regs
[ep
->num
];
3720 gnptxsts_data_t gtxstatus
;
3723 DWC_READ_REG32(&core_if
->core_global_regs
->gnptxsts
);
3725 if (core_if
->en_multiple_tx_fifo
== 0
3726 && gtxstatus
.b
.nptxqspcavail
== 0 && !core_if
->dma_enable
) {
3728 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus
.d32
);
3733 depctl
.d32
= DWC_READ_REG32(&(in_regs
->diepctl
));
3734 deptsiz
.d32
= DWC_READ_REG32(&(in_regs
->dieptsiz
));
3736 if (ep
->maxpacket
> ep
->maxxfer
/ MAX_PKT_CNT
)
3737 ep
->xfer_len
+= (ep
->maxxfer
< (ep
->total_len
- ep
->xfer_len
)) ?
3738 ep
->maxxfer
: (ep
->total_len
- ep
->xfer_len
);
3740 ep
->xfer_len
+= (MAX_PKT_CNT
* ep
->maxpacket
< (ep
->total_len
- ep
->xfer_len
)) ?
3741 MAX_PKT_CNT
* ep
->maxpacket
: (ep
->total_len
- ep
->xfer_len
);
3744 /* Zero Length Packet? */
3745 if ((ep
->xfer_len
- ep
->xfer_count
) == 0) {
3746 deptsiz
.b
.xfersize
= 0;
3747 deptsiz
.b
.pktcnt
= 1;
3749 /* Program the transfer size and packet count
3750 * as follows: xfersize = N * maxpacket +
3751 * short_packet pktcnt = N + (short_packet
3754 deptsiz
.b
.xfersize
= ep
->xfer_len
- ep
->xfer_count
;
3756 (ep
->xfer_len
- ep
->xfer_count
- 1 +
3757 ep
->maxpacket
) / ep
->maxpacket
;
3758 if (deptsiz
.b
.pktcnt
> MAX_PKT_CNT
) {
3759 deptsiz
.b
.pktcnt
= MAX_PKT_CNT
;
3760 deptsiz
.b
.xfersize
= deptsiz
.b
.pktcnt
* ep
->maxpacket
;
3762 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
)
3763 deptsiz
.b
.mc
= deptsiz
.b
.pktcnt
;
3766 /* Write the DMA register */
3767 if (core_if
->dma_enable
) {
3768 if (core_if
->dma_desc_enable
== 0) {
3769 if (ep
->type
!= DWC_OTG_EP_TYPE_ISOC
)
3771 DWC_WRITE_REG32(&in_regs
->dieptsiz
,
3773 DWC_WRITE_REG32(&(in_regs
->diepdma
),
3774 (uint32_t) ep
->dma_addr
);
3777 /* The descriptor chain should be already initialized by now */
3778 if (ep
->buff_mode
!= BM_STANDARD
) {
3779 DWC_WRITE_REG32(&in_regs
->diepdma
,
3780 ep
->descs_dma_addr
);
3783 init_dma_desc_chain(core_if
, ep
);
3784 /** DIEPDMAn Register write */
3785 DWC_WRITE_REG32(&in_regs
->diepdma
,
3792 DWC_WRITE_REG32(&in_regs
->dieptsiz
, deptsiz
.d32
);
3793 if (ep
->type
!= DWC_OTG_EP_TYPE_ISOC
) {
3795 * Enable the Non-Periodic Tx FIFO empty interrupt,
3796 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3797 * the data will be written into the fifo by the ISR.
3799 if (core_if
->en_multiple_tx_fifo
== 0) {
3800 intr_mask
.b
.nptxfempty
= 1;
3802 (&core_if
->core_global_regs
->gintmsk
,
3803 intr_mask
.d32
, intr_mask
.d32
);
3805 /* Enable the Tx FIFO Empty Interrupt for this EP */
3806 if (ep
->xfer_len
> 0) {
3807 uint32_t fifoemptymsk
= 0;
3808 fifoemptymsk
= 1 << ep
->num
;
3810 (&core_if
->dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
,
3816 write_isoc_tx_fifo(core_if
, ep
);
3819 if (!core_if
->core_params
->en_multiple_tx_fifo
&& core_if
->dma_enable
)
3820 depctl
.b
.nextep
= core_if
->nextep_seq
[ep
->num
];
3822 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
) {
3823 dsts_data_t dsts
= {.d32
= 0};
3824 if (ep
->bInterval
== 1) {
3826 DWC_READ_REG32(&core_if
->dev_if
->
3827 dev_global_regs
->dsts
);
3828 ep
->frame_num
= dsts
.b
.soffn
+ ep
->bInterval
;
3829 if (ep
->frame_num
> 0x3FFF) {
3830 ep
->frm_overrun
= 1;
3831 ep
->frame_num
&= 0x3FFF;
3833 ep
->frm_overrun
= 0;
3834 if (ep
->frame_num
& 0x1) {
3835 depctl
.b
.setd1pid
= 1;
3837 depctl
.b
.setd0pid
= 1;
3841 /* EP enable, IN data in FIFO */
3844 DWC_WRITE_REG32(&in_regs
->diepctl
, depctl
.d32
);
3848 dwc_otg_dev_out_ep_regs_t
*out_regs
=
3849 core_if
->dev_if
->out_ep_regs
[ep
->num
];
3851 depctl
.d32
= DWC_READ_REG32(&(out_regs
->doepctl
));
3852 deptsiz
.d32
= DWC_READ_REG32(&(out_regs
->doeptsiz
));
3854 if (!core_if
->dma_desc_enable
) {
3855 if (ep
->maxpacket
> ep
->maxxfer
/ MAX_PKT_CNT
)
3856 ep
->xfer_len
+= (ep
->maxxfer
< (ep
->total_len
- ep
->xfer_len
)) ?
3857 ep
->maxxfer
: (ep
->total_len
- ep
->xfer_len
);
3859 ep
->xfer_len
+= (MAX_PKT_CNT
* ep
->maxpacket
< (ep
->total_len
3860 - ep
->xfer_len
)) ? MAX_PKT_CNT
* ep
->maxpacket
: (ep
->total_len
- ep
->xfer_len
);
3863 /* Program the transfer size and packet count as follows:
3866 * xfersize = N * maxpacket
3868 if ((ep
->xfer_len
- ep
->xfer_count
) == 0) {
3869 /* Zero Length Packet */
3870 deptsiz
.b
.xfersize
= ep
->maxpacket
;
3871 deptsiz
.b
.pktcnt
= 1;
3874 (ep
->xfer_len
- ep
->xfer_count
+
3875 (ep
->maxpacket
- 1)) / ep
->maxpacket
;
3876 if (deptsiz
.b
.pktcnt
> MAX_PKT_CNT
) {
3877 deptsiz
.b
.pktcnt
= MAX_PKT_CNT
;
3879 if (!core_if
->dma_desc_enable
) {
3881 deptsiz
.b
.pktcnt
* ep
->maxpacket
+ ep
->xfer_count
;
3883 deptsiz
.b
.xfersize
= ep
->xfer_len
- ep
->xfer_count
;
3886 DWC_DEBUGPL(DBG_PCDV
, "ep%d xfersize=%d pktcnt=%d\n",
3887 ep
->num
, deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
);
3889 if (core_if
->dma_enable
) {
3890 if (!core_if
->dma_desc_enable
) {
3891 DWC_WRITE_REG32(&out_regs
->doeptsiz
,
3894 DWC_WRITE_REG32(&(out_regs
->doepdma
),
3895 (uint32_t) ep
->dma_addr
);
3898 /* The descriptor chain should be already initialized by now */
3899 if (ep
->buff_mode
!= BM_STANDARD
) {
3900 DWC_WRITE_REG32(&out_regs
->doepdma
,
3901 ep
->descs_dma_addr
);
3904 /** This is used for interrupt out transfers*/
3906 ep
->xfer_len
= ep
->total_len
;
3907 init_dma_desc_chain(core_if
, ep
);
3909 if (core_if
->core_params
->dev_out_nak
) {
3910 if (ep
->type
== DWC_OTG_EP_TYPE_BULK
) {
3911 deptsiz
.b
.pktcnt
= (ep
->total_len
+
3912 (ep
->maxpacket
- 1)) / ep
->maxpacket
;
3913 deptsiz
.b
.xfersize
= ep
->total_len
;
3914 /* Remember initial value of doeptsiz */
3915 core_if
->start_doeptsiz_val
[ep
->num
] = deptsiz
.d32
;
3916 DWC_WRITE_REG32(&out_regs
->doeptsiz
,
3920 /** DOEPDMAn Register write */
3921 DWC_WRITE_REG32(&out_regs
->doepdma
,
3928 DWC_WRITE_REG32(&out_regs
->doeptsiz
, deptsiz
.d32
);
3931 if (ep
->type
== DWC_OTG_EP_TYPE_ISOC
) {
3932 dsts_data_t dsts
= {.d32
= 0};
3933 if (ep
->bInterval
== 1) {
3935 DWC_READ_REG32(&core_if
->dev_if
->
3936 dev_global_regs
->dsts
);
3937 ep
->frame_num
= dsts
.b
.soffn
+ ep
->bInterval
;
3938 if (ep
->frame_num
> 0x3FFF) {
3939 ep
->frm_overrun
= 1;
3940 ep
->frame_num
&= 0x3FFF;
3942 ep
->frm_overrun
= 0;
3944 if (ep
->frame_num
& 0x1) {
3945 depctl
.b
.setd1pid
= 1;
3947 depctl
.b
.setd0pid
= 1;
3956 DWC_WRITE_REG32(&out_regs
->doepctl
, depctl
.d32
);
3958 DWC_DEBUGPL(DBG_PCD
, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3959 DWC_READ_REG32(&out_regs
->doepctl
),
3960 DWC_READ_REG32(&out_regs
->doeptsiz
));
3961 DWC_DEBUGPL(DBG_PCD
, "DAINTMSK=%08x GINTMSK=%08x\n",
3962 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->
3964 DWC_READ_REG32(&core_if
->core_global_regs
->
3967 /* Timer is scheduling only for out bulk transfers for
3968 * "Device DDMA OUT NAK Enhancement" feature to inform user
3969 * about received data payload in case of timeout
3971 if (core_if
->core_params
->dev_out_nak
) {
3972 if (ep
->type
== DWC_OTG_EP_TYPE_BULK
) {
3973 core_if
->ep_xfer_info
[ep
->num
].core_if
= core_if
;
3974 core_if
->ep_xfer_info
[ep
->num
].ep
= ep
;
3975 core_if
->ep_xfer_info
[ep
->num
].state
= 1;
3977 /* Start a timer for this transfer. */
3978 DWC_TIMER_SCHEDULE(core_if
->ep_xfer_timer
[ep
->num
], 10000);
3985 * This function setup a zero length transfer in Buffer DMA and
3986 * Slave modes for usb requests with zero field set
3988 * @param core_if Programming view of DWC_otg controller.
3989 * @param ep The EP to start the transfer on.
3992 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
3995 depctl_data_t depctl
;
3996 deptsiz_data_t deptsiz
;
3997 gintmsk_data_t intr_mask
= {.d32
= 0 };
3999 DWC_DEBUGPL((DBG_PCDV
| DBG_CILV
), "%s()\n", __func__
);
4000 DWC_PRINTF("zero length transfer is called\n");
4003 if (ep
->is_in
== 1) {
4004 dwc_otg_dev_in_ep_regs_t
*in_regs
=
4005 core_if
->dev_if
->in_ep_regs
[ep
->num
];
4007 depctl
.d32
= DWC_READ_REG32(&(in_regs
->diepctl
));
4008 deptsiz
.d32
= DWC_READ_REG32(&(in_regs
->dieptsiz
));
4010 deptsiz
.b
.xfersize
= 0;
4011 deptsiz
.b
.pktcnt
= 1;
4013 /* Write the DMA register */
4014 if (core_if
->dma_enable
) {
4015 if (core_if
->dma_desc_enable
== 0) {
4017 DWC_WRITE_REG32(&in_regs
->dieptsiz
,
4019 DWC_WRITE_REG32(&(in_regs
->diepdma
),
4020 (uint32_t) ep
->dma_addr
);
4023 DWC_WRITE_REG32(&in_regs
->dieptsiz
, deptsiz
.d32
);
4025 * Enable the Non-Periodic Tx FIFO empty interrupt,
4026 * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4027 * the data will be written into the fifo by the ISR.
4029 if (core_if
->en_multiple_tx_fifo
== 0) {
4030 intr_mask
.b
.nptxfempty
= 1;
4031 DWC_MODIFY_REG32(&core_if
->
4032 core_global_regs
->gintmsk
,
4033 intr_mask
.d32
, intr_mask
.d32
);
4035 /* Enable the Tx FIFO Empty Interrupt for this EP */
4036 if (ep
->xfer_len
> 0) {
4037 uint32_t fifoemptymsk
= 0;
4038 fifoemptymsk
= 1 << ep
->num
;
4039 DWC_MODIFY_REG32(&core_if
->
4040 dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
,
4046 if (!core_if
->core_params
->en_multiple_tx_fifo
&& core_if
->dma_enable
)
4047 depctl
.b
.nextep
= core_if
->nextep_seq
[ep
->num
];
4048 /* EP enable, IN data in FIFO */
4051 DWC_WRITE_REG32(&in_regs
->diepctl
, depctl
.d32
);
4055 dwc_otg_dev_out_ep_regs_t
*out_regs
=
4056 core_if
->dev_if
->out_ep_regs
[ep
->num
];
4058 depctl
.d32
= DWC_READ_REG32(&(out_regs
->doepctl
));
4059 deptsiz
.d32
= DWC_READ_REG32(&(out_regs
->doeptsiz
));
4061 /* Zero Length Packet */
4062 deptsiz
.b
.xfersize
= ep
->maxpacket
;
4063 deptsiz
.b
.pktcnt
= 1;
4065 if (core_if
->dma_enable
) {
4066 if (!core_if
->dma_desc_enable
) {
4067 DWC_WRITE_REG32(&out_regs
->doeptsiz
,
4070 DWC_WRITE_REG32(&(out_regs
->doepdma
),
4071 (uint32_t) ep
->dma_addr
);
4074 DWC_WRITE_REG32(&out_regs
->doeptsiz
, deptsiz
.d32
);
4081 DWC_WRITE_REG32(&out_regs
->doepctl
, depctl
.d32
);
4087 * This function does the setup for a data transfer for EP0 and starts
4088 * the transfer. For an IN transfer, the packets will be loaded into
4089 * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
4090 * unloaded from the Rx FIFO in the ISR.
4092 * @param core_if Programming view of DWC_otg controller.
4093 * @param ep The EP0 data.
4095 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
4097 depctl_data_t depctl
;
4098 deptsiz0_data_t deptsiz
;
4099 gintmsk_data_t intr_mask
= {.d32
= 0 };
4100 dwc_otg_dev_dma_desc_t
*dma_desc
;
4102 DWC_DEBUGPL(DBG_PCD
, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4103 "xfer_buff=%p start_xfer_buff=%p \n",
4104 ep
->num
, (ep
->is_in
? "IN" : "OUT"), ep
->xfer_len
,
4105 ep
->xfer_count
, ep
->xfer_buff
, ep
->start_xfer_buff
);
4107 ep
->total_len
= ep
->xfer_len
;
4110 if (ep
->is_in
== 1) {
4111 dwc_otg_dev_in_ep_regs_t
*in_regs
=
4112 core_if
->dev_if
->in_ep_regs
[0];
4114 gnptxsts_data_t gtxstatus
;
4116 if (core_if
->snpsid
>= OTG_CORE_REV_3_00a
) {
4117 depctl
.d32
= DWC_READ_REG32(&in_regs
->diepctl
);
4123 DWC_READ_REG32(&core_if
->core_global_regs
->gnptxsts
);
4125 /* If dedicated FIFO every time flush fifo before enable ep*/
4126 if (core_if
->en_multiple_tx_fifo
&& core_if
->snpsid
>= OTG_CORE_REV_3_00a
)
4127 dwc_otg_flush_tx_fifo(core_if
, ep
->tx_fifo_num
);
4129 if (core_if
->en_multiple_tx_fifo
== 0
4130 && gtxstatus
.b
.nptxqspcavail
== 0
4131 && !core_if
->dma_enable
) {
4133 deptsiz
.d32
= DWC_READ_REG32(&in_regs
->dieptsiz
);
4134 DWC_DEBUGPL(DBG_PCD
, "DIEPCTL0=%0x\n",
4135 DWC_READ_REG32(&in_regs
->diepctl
));
4136 DWC_DEBUGPL(DBG_PCD
, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
4138 deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
);
4139 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4145 depctl
.d32
= DWC_READ_REG32(&in_regs
->diepctl
);
4146 deptsiz
.d32
= DWC_READ_REG32(&in_regs
->dieptsiz
);
4148 /* Zero Length Packet? */
4149 if (ep
->xfer_len
== 0) {
4150 deptsiz
.b
.xfersize
= 0;
4151 deptsiz
.b
.pktcnt
= 1;
4153 /* Program the transfer size and packet count
4154 * as follows: xfersize = N * maxpacket +
4155 * short_packet pktcnt = N + (short_packet
4158 if (ep
->xfer_len
> ep
->maxpacket
) {
4159 ep
->xfer_len
= ep
->maxpacket
;
4160 deptsiz
.b
.xfersize
= ep
->maxpacket
;
4162 deptsiz
.b
.xfersize
= ep
->xfer_len
;
4164 deptsiz
.b
.pktcnt
= 1;
4167 DWC_DEBUGPL(DBG_PCDV
,
4168 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4169 ep
->xfer_len
, deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
,
4172 /* Write the DMA register */
4173 if (core_if
->dma_enable
) {
4174 if (core_if
->dma_desc_enable
== 0) {
4175 DWC_WRITE_REG32(&in_regs
->dieptsiz
,
4178 DWC_WRITE_REG32(&(in_regs
->diepdma
),
4179 (uint32_t) ep
->dma_addr
);
4181 dma_desc
= core_if
->dev_if
->in_desc_addr
;
4183 /** DMA Descriptor Setup */
4184 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
4185 dma_desc
->status
.b
.l
= 1;
4186 dma_desc
->status
.b
.ioc
= 1;
4187 dma_desc
->status
.b
.sp
=
4188 (ep
->xfer_len
== ep
->maxpacket
) ? 0 : 1;
4189 dma_desc
->status
.b
.bytes
= ep
->xfer_len
;
4190 dma_desc
->buf
= ep
->dma_addr
;
4191 dma_desc
->status
.b
.sts
= 0;
4192 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
4194 /** DIEPDMA0 Register write */
4195 DWC_WRITE_REG32(&in_regs
->diepdma
,
4197 dev_if
->dma_in_desc_addr
);
4200 DWC_WRITE_REG32(&in_regs
->dieptsiz
, deptsiz
.d32
);
4203 if (!core_if
->core_params
->en_multiple_tx_fifo
&& core_if
->dma_enable
)
4204 depctl
.b
.nextep
= core_if
->nextep_seq
[ep
->num
];
4205 /* EP enable, IN data in FIFO */
4208 DWC_WRITE_REG32(&in_regs
->diepctl
, depctl
.d32
);
4211 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4212 * data will be written into the fifo by the ISR.
4214 if (!core_if
->dma_enable
) {
4215 if (core_if
->en_multiple_tx_fifo
== 0) {
4216 intr_mask
.b
.nptxfempty
= 1;
4217 DWC_MODIFY_REG32(&core_if
->
4218 core_global_regs
->gintmsk
,
4219 intr_mask
.d32
, intr_mask
.d32
);
4221 /* Enable the Tx FIFO Empty Interrupt for this EP */
4222 if (ep
->xfer_len
> 0) {
4223 uint32_t fifoemptymsk
= 0;
4224 fifoemptymsk
|= 1 << ep
->num
;
4225 DWC_MODIFY_REG32(&core_if
->
4226 dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
,
4233 dwc_otg_dev_out_ep_regs_t
*out_regs
=
4234 core_if
->dev_if
->out_ep_regs
[0];
4236 depctl
.d32
= DWC_READ_REG32(&out_regs
->doepctl
);
4237 deptsiz
.d32
= DWC_READ_REG32(&out_regs
->doeptsiz
);
4239 /* Program the transfer size and packet count as follows:
4240 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4242 /* Zero Length Packet */
4243 deptsiz
.b
.xfersize
= ep
->maxpacket
;
4244 deptsiz
.b
.pktcnt
= 1;
4245 if (core_if
->snpsid
>= OTG_CORE_REV_3_00a
)
4246 deptsiz
.b
.supcnt
= 3;
4248 DWC_DEBUGPL(DBG_PCDV
, "len=%d xfersize=%d pktcnt=%d\n",
4249 ep
->xfer_len
, deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
);
4251 if (core_if
->dma_enable
) {
4252 if (!core_if
->dma_desc_enable
) {
4253 DWC_WRITE_REG32(&out_regs
->doeptsiz
,
4256 DWC_WRITE_REG32(&(out_regs
->doepdma
),
4257 (uint32_t) ep
->dma_addr
);
4259 dma_desc
= core_if
->dev_if
->out_desc_addr
;
4261 /** DMA Descriptor Setup */
4262 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
4263 if (core_if
->snpsid
>= OTG_CORE_REV_3_00a
) {
4264 dma_desc
->status
.b
.mtrf
= 0;
4265 dma_desc
->status
.b
.sr
= 0;
4267 dma_desc
->status
.b
.l
= 1;
4268 dma_desc
->status
.b
.ioc
= 1;
4269 dma_desc
->status
.b
.bytes
= ep
->maxpacket
;
4270 dma_desc
->buf
= ep
->dma_addr
;
4271 dma_desc
->status
.b
.sts
= 0;
4272 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
4274 /** DOEPDMA0 Register write */
4275 DWC_WRITE_REG32(&out_regs
->doepdma
,
4280 DWC_WRITE_REG32(&out_regs
->doeptsiz
, deptsiz
.d32
);
4286 DWC_WRITE_REG32(&(out_regs
->doepctl
), depctl
.d32
);
4291 * This function continues control IN transfers started by
4292 * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
4293 * single packet. NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
4294 * bit for the packet count.
4296 * @param core_if Programming view of DWC_otg controller.
4297 * @param ep The EP0 data.
4299 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
4301 depctl_data_t depctl
;
4302 deptsiz0_data_t deptsiz
;
4303 gintmsk_data_t intr_mask
= {.d32
= 0 };
4304 dwc_otg_dev_dma_desc_t
*dma_desc
;
4306 if (ep
->is_in
== 1) {
4307 dwc_otg_dev_in_ep_regs_t
*in_regs
=
4308 core_if
->dev_if
->in_ep_regs
[0];
4309 gnptxsts_data_t tx_status
= {.d32
= 0 };
4312 DWC_READ_REG32(&core_if
->core_global_regs
->gnptxsts
);
4313 /** @todo Should there be check for room in the Tx
4314 * Status Queue. If not remove the code above this comment. */
4316 depctl
.d32
= DWC_READ_REG32(&in_regs
->diepctl
);
4317 deptsiz
.d32
= DWC_READ_REG32(&in_regs
->dieptsiz
);
4319 /* Program the transfer size and packet count
4320 * as follows: xfersize = N * maxpacket +
4321 * short_packet pktcnt = N + (short_packet
4325 if (core_if
->dma_desc_enable
== 0) {
4326 deptsiz
.b
.xfersize
=
4327 (ep
->total_len
- ep
->xfer_count
) >
4328 ep
->maxpacket
? ep
->maxpacket
: (ep
->total_len
-
4330 deptsiz
.b
.pktcnt
= 1;
4331 if (core_if
->dma_enable
== 0) {
4332 ep
->xfer_len
+= deptsiz
.b
.xfersize
;
4334 ep
->xfer_len
= deptsiz
.b
.xfersize
;
4336 DWC_WRITE_REG32(&in_regs
->dieptsiz
, deptsiz
.d32
);
4339 (ep
->total_len
- ep
->xfer_count
) >
4340 ep
->maxpacket
? ep
->maxpacket
: (ep
->total_len
-
4343 dma_desc
= core_if
->dev_if
->in_desc_addr
;
4345 /** DMA Descriptor Setup */
4346 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
4347 dma_desc
->status
.b
.l
= 1;
4348 dma_desc
->status
.b
.ioc
= 1;
4349 dma_desc
->status
.b
.sp
=
4350 (ep
->xfer_len
== ep
->maxpacket
) ? 0 : 1;
4351 dma_desc
->status
.b
.bytes
= ep
->xfer_len
;
4352 dma_desc
->buf
= ep
->dma_addr
;
4353 dma_desc
->status
.b
.sts
= 0;
4354 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
4356 /** DIEPDMA0 Register write */
4357 DWC_WRITE_REG32(&in_regs
->diepdma
,
4358 core_if
->dev_if
->dma_in_desc_addr
);
4361 DWC_DEBUGPL(DBG_PCDV
,
4362 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4363 ep
->xfer_len
, deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
,
4366 /* Write the DMA register */
4367 if (core_if
->hwcfg2
.b
.architecture
== DWC_INT_DMA_ARCH
) {
4368 if (core_if
->dma_desc_enable
== 0)
4369 DWC_WRITE_REG32(&(in_regs
->diepdma
),
4370 (uint32_t) ep
->dma_addr
);
4372 if (!core_if
->core_params
->en_multiple_tx_fifo
&& core_if
->dma_enable
)
4373 depctl
.b
.nextep
= core_if
->nextep_seq
[ep
->num
];
4374 /* EP enable, IN data in FIFO */
4377 DWC_WRITE_REG32(&in_regs
->diepctl
, depctl
.d32
);
4380 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4381 * data will be written into the fifo by the ISR.
4383 if (!core_if
->dma_enable
) {
4384 if (core_if
->en_multiple_tx_fifo
== 0) {
4385 /* First clear it from GINTSTS */
4386 intr_mask
.b
.nptxfempty
= 1;
4387 DWC_MODIFY_REG32(&core_if
->
4388 core_global_regs
->gintmsk
,
4389 intr_mask
.d32
, intr_mask
.d32
);
4392 /* Enable the Tx FIFO Empty Interrupt for this EP */
4393 if (ep
->xfer_len
> 0) {
4394 uint32_t fifoemptymsk
= 0;
4395 fifoemptymsk
|= 1 << ep
->num
;
4396 DWC_MODIFY_REG32(&core_if
->
4397 dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
,
4403 dwc_otg_dev_out_ep_regs_t
*out_regs
=
4404 core_if
->dev_if
->out_ep_regs
[0];
4406 depctl
.d32
= DWC_READ_REG32(&out_regs
->doepctl
);
4407 deptsiz
.d32
= DWC_READ_REG32(&out_regs
->doeptsiz
);
4409 /* Program the transfer size and packet count
4410 * as follows: xfersize = N * maxpacket +
4411 * short_packet pktcnt = N + (short_packet
4414 deptsiz
.b
.xfersize
= ep
->maxpacket
;
4415 deptsiz
.b
.pktcnt
= 1;
4417 if (core_if
->dma_desc_enable
== 0) {
4418 DWC_WRITE_REG32(&out_regs
->doeptsiz
, deptsiz
.d32
);
4420 dma_desc
= core_if
->dev_if
->out_desc_addr
;
4422 /** DMA Descriptor Setup */
4423 dma_desc
->status
.b
.bs
= BS_HOST_BUSY
;
4424 dma_desc
->status
.b
.l
= 1;
4425 dma_desc
->status
.b
.ioc
= 1;
4426 dma_desc
->status
.b
.bytes
= ep
->maxpacket
;
4427 dma_desc
->buf
= ep
->dma_addr
;
4428 dma_desc
->status
.b
.sts
= 0;
4429 dma_desc
->status
.b
.bs
= BS_HOST_READY
;
4431 /** DOEPDMA0 Register write */
4432 DWC_WRITE_REG32(&out_regs
->doepdma
,
4433 core_if
->dev_if
->dma_out_desc_addr
);
4436 DWC_DEBUGPL(DBG_PCDV
,
4437 "IN len=%d xfersize=%d pktcnt=%d [%08x]\n",
4438 ep
->xfer_len
, deptsiz
.b
.xfersize
, deptsiz
.b
.pktcnt
,
4441 /* Write the DMA register */
4442 if (core_if
->hwcfg2
.b
.architecture
== DWC_INT_DMA_ARCH
) {
4443 if (core_if
->dma_desc_enable
== 0)
4444 DWC_WRITE_REG32(&(out_regs
->doepdma
),
4445 (uint32_t) ep
->dma_addr
);
4449 /* EP enable, IN data in FIFO */
4452 DWC_WRITE_REG32(&out_regs
->doepctl
, depctl
.d32
);
4458 void dump_msg(const u8
* buf
, unsigned int length
)
4460 unsigned int start
, num
, i
;
4466 while (length
> 0) {
4467 num
= length
< 16u ? length
: 16u;
4469 for (i
= 0; i
< num
; ++i
) {
4472 DWC_SPRINTF(p
, " %02x", buf
[i
]);
4476 DWC_PRINTF("%6x: %s\n", start
, line
);
4483 static inline void dump_msg(const u8
* buf
, unsigned int length
)
4489 * This function writes a packet into the Tx FIFO associated with the
4490 * EP. For non-periodic EPs the non-periodic Tx FIFO is written. For
4491 * periodic EPs the periodic Tx FIFO associated with the EP is written
4492 * with all packets for the next micro-frame.
4494 * @param core_if Programming view of DWC_otg controller.
4495 * @param ep The EP to write packet for.
4496 * @param dma Indicates if DMA is being used.
4498 void dwc_otg_ep_write_packet(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
,
4502 * The buffer is padded to DWORD on a per packet basis in
4503 * slave/dma mode if the MPS is not DWORD aligned. The last
4504 * packet, if short, is also padded to a multiple of DWORD.
4506 * ep->xfer_buff always starts DWORD aligned in memory and is a
4507 * multiple of DWORD in length
4509 * ep->xfer_len can be any number of bytes
4511 * ep->xfer_count is a multiple of ep->maxpacket until the last
4514 * FIFO access is DWORD */
4517 uint32_t byte_count
;
4518 uint32_t dword_count
;
4520 uint32_t *data_buff
= (uint32_t *) ep
->xfer_buff
;
4522 DWC_DEBUGPL((DBG_PCDV
| DBG_CILV
), "%s(%p,%p)\n", __func__
, core_if
,
4524 if (ep
->xfer_count
>= ep
->xfer_len
) {
4525 DWC_WARN("%s() No data for EP%d!!!\n", __func__
, ep
->num
);
4529 /* Find the byte length of the packet either short packet or MPS */
4530 if ((ep
->xfer_len
- ep
->xfer_count
) < ep
->maxpacket
) {
4531 byte_count
= ep
->xfer_len
- ep
->xfer_count
;
4533 byte_count
= ep
->maxpacket
;
4536 /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4537 * is not a multiple of DWORD */
4538 dword_count
= (byte_count
+ 3) / 4;
4541 dump_msg(ep
->xfer_buff
, byte_count
);
4544 /**@todo NGS Where are the Periodic Tx FIFO addresses
4545 * intialized? What should this be? */
4547 fifo
= core_if
->data_fifo
[ep
->num
];
4549 DWC_DEBUGPL((DBG_PCDV
| DBG_CILV
), "fifo=%p buff=%p *p=%08x bc=%d\n",
4550 fifo
, data_buff
, *data_buff
, byte_count
);
4553 for (i
= 0; i
< dword_count
; i
++, data_buff
++) {
4554 DWC_WRITE_REG32(fifo
, *data_buff
);
4558 ep
->xfer_count
+= byte_count
;
4559 ep
->xfer_buff
+= byte_count
;
4560 ep
->dma_addr
+= byte_count
;
4566 * @param core_if Programming view of DWC_otg controller.
4567 * @param ep The EP to set the stall on.
4569 void dwc_otg_ep_set_stall(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
4571 depctl_data_t depctl
;
4572 volatile uint32_t *depctl_addr
;
4574 DWC_DEBUGPL(DBG_PCD
, "%s ep%d-%s\n", __func__
, ep
->num
,
4575 (ep
->is_in
? "IN" : "OUT"));
4577 if (ep
->is_in
== 1) {
4578 depctl_addr
= &(core_if
->dev_if
->in_ep_regs
[ep
->num
]->diepctl
);
4579 depctl
.d32
= DWC_READ_REG32(depctl_addr
);
4581 /* set the disable and stall bits */
4582 if (depctl
.b
.epena
) {
4586 DWC_WRITE_REG32(depctl_addr
, depctl
.d32
);
4588 depctl_addr
= &(core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepctl
);
4589 depctl
.d32
= DWC_READ_REG32(depctl_addr
);
4591 /* set the stall bit */
4593 DWC_WRITE_REG32(depctl_addr
, depctl
.d32
);
4596 DWC_DEBUGPL(DBG_PCD
, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr
));
4602 * Clear the EP STALL.
4604 * @param core_if Programming view of DWC_otg controller.
4605 * @param ep The EP to clear stall from.
4607 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
4609 depctl_data_t depctl
;
4610 volatile uint32_t *depctl_addr
;
4612 DWC_DEBUGPL(DBG_PCD
, "%s ep%d-%s\n", __func__
, ep
->num
,
4613 (ep
->is_in
? "IN" : "OUT"));
4615 if (ep
->is_in
== 1) {
4616 depctl_addr
= &(core_if
->dev_if
->in_ep_regs
[ep
->num
]->diepctl
);
4618 depctl_addr
= &(core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepctl
);
4621 depctl
.d32
= DWC_READ_REG32(depctl_addr
);
4623 /* clear the stall bits */
4627 * USB Spec 9.4.5: For endpoints using data toggle, regardless
4628 * of whether an endpoint has the Halt feature set, a
4629 * ClearFeature(ENDPOINT_HALT) request always results in the
4630 * data toggle being reinitialized to DATA0.
4632 if (ep
->type
== DWC_OTG_EP_TYPE_INTR
||
4633 ep
->type
== DWC_OTG_EP_TYPE_BULK
) {
4634 depctl
.b
.setd0pid
= 1; /* DATA0 */
4637 DWC_WRITE_REG32(depctl_addr
, depctl
.d32
);
4638 DWC_DEBUGPL(DBG_PCD
, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr
));
4643 * This function reads a packet from the Rx FIFO into the destination
4644 * buffer. To read SETUP data use dwc_otg_read_setup_packet.
4646 * @param core_if Programming view of DWC_otg controller.
4647 * @param dest Destination buffer for the packet.
4648 * @param bytes Number of bytes to copy to the destination.
4650 void dwc_otg_read_packet(dwc_otg_core_if_t
* core_if
,
4651 uint8_t * dest
, uint16_t bytes
)
4654 int word_count
= (bytes
+ 3) / 4;
4656 volatile uint32_t *fifo
= core_if
->data_fifo
[0];
4657 uint32_t *data_buff
= (uint32_t *) dest
;
4660 * @todo Account for the case where _dest is not dword aligned. This
4661 * requires reading data from the FIFO into a uint32_t temp buffer,
4662 * then moving it into the data buffer.
4665 DWC_DEBUGPL((DBG_PCDV
| DBG_CILV
), "%s(%p,%p,%d)\n", __func__
,
4666 core_if
, dest
, bytes
);
4668 for (i
= 0; i
< word_count
; i
++, data_buff
++) {
4669 *data_buff
= DWC_READ_REG32(fifo
);
4676 * This functions reads the device registers and prints them
4678 * @param core_if Programming view of DWC_otg controller.
4680 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t
* core_if
)
4683 volatile uint32_t *addr
;
4685 DWC_PRINTF("Device Global Registers\n");
4686 addr
= &core_if
->dev_if
->dev_global_regs
->dcfg
;
4687 DWC_PRINTF("DCFG @0x%08lX : 0x%08X\n",
4688 (unsigned long)addr
, DWC_READ_REG32(addr
));
4689 addr
= &core_if
->dev_if
->dev_global_regs
->dctl
;
4690 DWC_PRINTF("DCTL @0x%08lX : 0x%08X\n",
4691 (unsigned long)addr
, DWC_READ_REG32(addr
));
4692 addr
= &core_if
->dev_if
->dev_global_regs
->dsts
;
4693 DWC_PRINTF("DSTS @0x%08lX : 0x%08X\n",
4694 (unsigned long)addr
, DWC_READ_REG32(addr
));
4695 addr
= &core_if
->dev_if
->dev_global_regs
->diepmsk
;
4696 DWC_PRINTF("DIEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4697 DWC_READ_REG32(addr
));
4698 addr
= &core_if
->dev_if
->dev_global_regs
->doepmsk
;
4699 DWC_PRINTF("DOEPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4700 DWC_READ_REG32(addr
));
4701 addr
= &core_if
->dev_if
->dev_global_regs
->daint
;
4702 DWC_PRINTF("DAINT @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4703 DWC_READ_REG32(addr
));
4704 addr
= &core_if
->dev_if
->dev_global_regs
->daintmsk
;
4705 DWC_PRINTF("DAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4706 DWC_READ_REG32(addr
));
4707 addr
= &core_if
->dev_if
->dev_global_regs
->dtknqr1
;
4708 DWC_PRINTF("DTKNQR1 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4709 DWC_READ_REG32(addr
));
4710 if (core_if
->hwcfg2
.b
.dev_token_q_depth
> 6) {
4711 addr
= &core_if
->dev_if
->dev_global_regs
->dtknqr2
;
4712 DWC_PRINTF("DTKNQR2 @0x%08lX : 0x%08X\n",
4713 (unsigned long)addr
, DWC_READ_REG32(addr
));
4716 addr
= &core_if
->dev_if
->dev_global_regs
->dvbusdis
;
4717 DWC_PRINTF("DVBUSID @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4718 DWC_READ_REG32(addr
));
4720 addr
= &core_if
->dev_if
->dev_global_regs
->dvbuspulse
;
4721 DWC_PRINTF("DVBUSPULSE @0x%08lX : 0x%08X\n",
4722 (unsigned long)addr
, DWC_READ_REG32(addr
));
4724 addr
= &core_if
->dev_if
->dev_global_regs
->dtknqr3_dthrctl
;
4725 DWC_PRINTF("DTKNQR3_DTHRCTL @0x%08lX : 0x%08X\n",
4726 (unsigned long)addr
, DWC_READ_REG32(addr
));
4728 if (core_if
->hwcfg2
.b
.dev_token_q_depth
> 22) {
4729 addr
= &core_if
->dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
;
4730 DWC_PRINTF("DTKNQR4 @0x%08lX : 0x%08X\n",
4731 (unsigned long)addr
, DWC_READ_REG32(addr
));
4734 addr
= &core_if
->dev_if
->dev_global_regs
->dtknqr4_fifoemptymsk
;
4735 DWC_PRINTF("FIFOEMPMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4736 DWC_READ_REG32(addr
));
4738 if (core_if
->hwcfg2
.b
.multi_proc_int
) {
4740 addr
= &core_if
->dev_if
->dev_global_regs
->deachint
;
4741 DWC_PRINTF("DEACHINT @0x%08lX : 0x%08X\n",
4742 (unsigned long)addr
, DWC_READ_REG32(addr
));
4743 addr
= &core_if
->dev_if
->dev_global_regs
->deachintmsk
;
4744 DWC_PRINTF("DEACHINTMSK @0x%08lX : 0x%08X\n",
4745 (unsigned long)addr
, DWC_READ_REG32(addr
));
4747 for (i
= 0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
4750 dev_global_regs
->diepeachintmsk
[i
];
4751 DWC_PRINTF("DIEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4752 i
, (unsigned long)addr
,
4753 DWC_READ_REG32(addr
));
4756 for (i
= 0; i
<= core_if
->dev_if
->num_out_eps
; i
++) {
4759 dev_global_regs
->doepeachintmsk
[i
];
4760 DWC_PRINTF("DOEPEACHINTMSK[%d] @0x%08lX : 0x%08X\n",
4761 i
, (unsigned long)addr
,
4762 DWC_READ_REG32(addr
));
4766 for (i
= 0; i
<= core_if
->dev_if
->num_in_eps
; i
++) {
4767 DWC_PRINTF("Device IN EP %d Registers\n", i
);
4768 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->diepctl
;
4769 DWC_PRINTF("DIEPCTL @0x%08lX : 0x%08X\n",
4770 (unsigned long)addr
, DWC_READ_REG32(addr
));
4771 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->diepint
;
4772 DWC_PRINTF("DIEPINT @0x%08lX : 0x%08X\n",
4773 (unsigned long)addr
, DWC_READ_REG32(addr
));
4774 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->dieptsiz
;
4775 DWC_PRINTF("DIETSIZ @0x%08lX : 0x%08X\n",
4776 (unsigned long)addr
, DWC_READ_REG32(addr
));
4777 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->diepdma
;
4778 DWC_PRINTF("DIEPDMA @0x%08lX : 0x%08X\n",
4779 (unsigned long)addr
, DWC_READ_REG32(addr
));
4780 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->dtxfsts
;
4781 DWC_PRINTF("DTXFSTS @0x%08lX : 0x%08X\n",
4782 (unsigned long)addr
, DWC_READ_REG32(addr
));
4783 addr
= &core_if
->dev_if
->in_ep_regs
[i
]->diepdmab
;
4784 DWC_PRINTF("DIEPDMAB @0x%08lX : 0x%08X\n",
4785 (unsigned long)addr
, 0 /*DWC_READ_REG32(addr) */ );
4788 for (i
= 0; i
<= core_if
->dev_if
->num_out_eps
; i
++) {
4789 DWC_PRINTF("Device OUT EP %d Registers\n", i
);
4790 addr
= &core_if
->dev_if
->out_ep_regs
[i
]->doepctl
;
4791 DWC_PRINTF("DOEPCTL @0x%08lX : 0x%08X\n",
4792 (unsigned long)addr
, DWC_READ_REG32(addr
));
4793 addr
= &core_if
->dev_if
->out_ep_regs
[i
]->doepint
;
4794 DWC_PRINTF("DOEPINT @0x%08lX : 0x%08X\n",
4795 (unsigned long)addr
, DWC_READ_REG32(addr
));
4796 addr
= &core_if
->dev_if
->out_ep_regs
[i
]->doeptsiz
;
4797 DWC_PRINTF("DOETSIZ @0x%08lX : 0x%08X\n",
4798 (unsigned long)addr
, DWC_READ_REG32(addr
));
4799 addr
= &core_if
->dev_if
->out_ep_regs
[i
]->doepdma
;
4800 DWC_PRINTF("DOEPDMA @0x%08lX : 0x%08X\n",
4801 (unsigned long)addr
, DWC_READ_REG32(addr
));
4802 if (core_if
->dma_enable
) { /* Don't access this register in SLAVE mode */
4803 addr
= &core_if
->dev_if
->out_ep_regs
[i
]->doepdmab
;
4804 DWC_PRINTF("DOEPDMAB @0x%08lX : 0x%08X\n",
4805 (unsigned long)addr
, DWC_READ_REG32(addr
));
4812 * This functions reads the SPRAM and prints its content
4814 * @param core_if Programming view of DWC_otg controller.
4816 void dwc_otg_dump_spram(dwc_otg_core_if_t
* core_if
)
4818 volatile uint8_t *addr
, *start_addr
, *end_addr
;
4820 DWC_PRINTF("SPRAM Data:\n");
4821 start_addr
= (void *)core_if
->core_global_regs
;
4822 DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr
);
4823 start_addr
+= 0x00028000;
4824 end_addr
= (void *)core_if
->core_global_regs
;
4825 end_addr
+= 0x000280e0;
4827 for (addr
= start_addr
; addr
< end_addr
; addr
+= 16) {
4829 ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
4830 (unsigned long)addr
, addr
[0], addr
[1], addr
[2], addr
[3],
4831 addr
[4], addr
[5], addr
[6], addr
[7], addr
[8], addr
[9],
4832 addr
[10], addr
[11], addr
[12], addr
[13], addr
[14], addr
[15]
4840 * This function reads the host registers and prints them
4842 * @param core_if Programming view of DWC_otg controller.
4844 void dwc_otg_dump_host_registers(dwc_otg_core_if_t
* core_if
)
4847 volatile uint32_t *addr
;
4849 DWC_PRINTF("Host Global Registers\n");
4850 addr
= &core_if
->host_if
->host_global_regs
->hcfg
;
4851 DWC_PRINTF("HCFG @0x%08lX : 0x%08X\n",
4852 (unsigned long)addr
, DWC_READ_REG32(addr
));
4853 addr
= &core_if
->host_if
->host_global_regs
->hfir
;
4854 DWC_PRINTF("HFIR @0x%08lX : 0x%08X\n",
4855 (unsigned long)addr
, DWC_READ_REG32(addr
));
4856 addr
= &core_if
->host_if
->host_global_regs
->hfnum
;
4857 DWC_PRINTF("HFNUM @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4858 DWC_READ_REG32(addr
));
4859 addr
= &core_if
->host_if
->host_global_regs
->hptxsts
;
4860 DWC_PRINTF("HPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4861 DWC_READ_REG32(addr
));
4862 addr
= &core_if
->host_if
->host_global_regs
->haint
;
4863 DWC_PRINTF("HAINT @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4864 DWC_READ_REG32(addr
));
4865 addr
= &core_if
->host_if
->host_global_regs
->haintmsk
;
4866 DWC_PRINTF("HAINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4867 DWC_READ_REG32(addr
));
4868 if (core_if
->dma_desc_enable
) {
4869 addr
= &core_if
->host_if
->host_global_regs
->hflbaddr
;
4870 DWC_PRINTF("HFLBADDR @0x%08lX : 0x%08X\n",
4871 (unsigned long)addr
, DWC_READ_REG32(addr
));
4874 addr
= core_if
->host_if
->hprt0
;
4875 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4876 DWC_READ_REG32(addr
));
4878 for (i
= 0; i
< core_if
->core_params
->host_channels
; i
++) {
4879 DWC_PRINTF("Host Channel %d Specific Registers\n", i
);
4880 addr
= &core_if
->host_if
->hc_regs
[i
]->hcchar
;
4881 DWC_PRINTF("HCCHAR @0x%08lX : 0x%08X\n",
4882 (unsigned long)addr
, DWC_READ_REG32(addr
));
4883 addr
= &core_if
->host_if
->hc_regs
[i
]->hcsplt
;
4884 DWC_PRINTF("HCSPLT @0x%08lX : 0x%08X\n",
4885 (unsigned long)addr
, DWC_READ_REG32(addr
));
4886 addr
= &core_if
->host_if
->hc_regs
[i
]->hcint
;
4887 DWC_PRINTF("HCINT @0x%08lX : 0x%08X\n",
4888 (unsigned long)addr
, DWC_READ_REG32(addr
));
4889 addr
= &core_if
->host_if
->hc_regs
[i
]->hcintmsk
;
4890 DWC_PRINTF("HCINTMSK @0x%08lX : 0x%08X\n",
4891 (unsigned long)addr
, DWC_READ_REG32(addr
));
4892 addr
= &core_if
->host_if
->hc_regs
[i
]->hctsiz
;
4893 DWC_PRINTF("HCTSIZ @0x%08lX : 0x%08X\n",
4894 (unsigned long)addr
, DWC_READ_REG32(addr
));
4895 addr
= &core_if
->host_if
->hc_regs
[i
]->hcdma
;
4896 DWC_PRINTF("HCDMA @0x%08lX : 0x%08X\n",
4897 (unsigned long)addr
, DWC_READ_REG32(addr
));
4898 if (core_if
->dma_desc_enable
) {
4899 addr
= &core_if
->host_if
->hc_regs
[i
]->hcdmab
;
4900 DWC_PRINTF("HCDMAB @0x%08lX : 0x%08X\n",
4901 (unsigned long)addr
, DWC_READ_REG32(addr
));
4909 * This function reads the core global registers and prints them
4911 * @param core_if Programming view of DWC_otg controller.
4913 void dwc_otg_dump_global_registers(dwc_otg_core_if_t
* core_if
)
4916 volatile uint32_t *addr
;
4919 DWC_PRINTF("Core Global Registers\n");
4920 addr
= &core_if
->core_global_regs
->gotgctl
;
4921 DWC_PRINTF("GOTGCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4922 DWC_READ_REG32(addr
));
4923 addr
= &core_if
->core_global_regs
->gotgint
;
4924 DWC_PRINTF("GOTGINT @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4925 DWC_READ_REG32(addr
));
4926 addr
= &core_if
->core_global_regs
->gahbcfg
;
4927 DWC_PRINTF("GAHBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4928 DWC_READ_REG32(addr
));
4929 addr
= &core_if
->core_global_regs
->gusbcfg
;
4930 DWC_PRINTF("GUSBCFG @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4931 DWC_READ_REG32(addr
));
4932 addr
= &core_if
->core_global_regs
->grstctl
;
4933 DWC_PRINTF("GRSTCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4934 DWC_READ_REG32(addr
));
4935 addr
= &core_if
->core_global_regs
->gintsts
;
4936 DWC_PRINTF("GINTSTS @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4937 DWC_READ_REG32(addr
));
4938 addr
= &core_if
->core_global_regs
->gintmsk
;
4939 DWC_PRINTF("GINTMSK @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4940 DWC_READ_REG32(addr
));
4941 addr
= &core_if
->core_global_regs
->grxstsr
;
4942 DWC_PRINTF("GRXSTSR @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4943 DWC_READ_REG32(addr
));
4944 addr
= &core_if
->core_global_regs
->grxfsiz
;
4945 DWC_PRINTF("GRXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4946 DWC_READ_REG32(addr
));
4947 addr
= &core_if
->core_global_regs
->gnptxfsiz
;
4948 DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4949 DWC_READ_REG32(addr
));
4950 addr
= &core_if
->core_global_regs
->gnptxsts
;
4951 DWC_PRINTF("GNPTXSTS @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4952 DWC_READ_REG32(addr
));
4953 addr
= &core_if
->core_global_regs
->gi2cctl
;
4954 DWC_PRINTF("GI2CCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4955 DWC_READ_REG32(addr
));
4956 addr
= &core_if
->core_global_regs
->gpvndctl
;
4957 DWC_PRINTF("GPVNDCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4958 DWC_READ_REG32(addr
));
4959 addr
= &core_if
->core_global_regs
->ggpio
;
4960 DWC_PRINTF("GGPIO @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4961 DWC_READ_REG32(addr
));
4962 addr
= &core_if
->core_global_regs
->guid
;
4963 DWC_PRINTF("GUID @0x%08lX : 0x%08X\n",
4964 (unsigned long)addr
, DWC_READ_REG32(addr
));
4965 addr
= &core_if
->core_global_regs
->gsnpsid
;
4966 DWC_PRINTF("GSNPSID @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4967 DWC_READ_REG32(addr
));
4968 addr
= &core_if
->core_global_regs
->ghwcfg1
;
4969 DWC_PRINTF("GHWCFG1 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4970 DWC_READ_REG32(addr
));
4971 addr
= &core_if
->core_global_regs
->ghwcfg2
;
4972 DWC_PRINTF("GHWCFG2 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4973 DWC_READ_REG32(addr
));
4974 addr
= &core_if
->core_global_regs
->ghwcfg3
;
4975 DWC_PRINTF("GHWCFG3 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4976 DWC_READ_REG32(addr
));
4977 addr
= &core_if
->core_global_regs
->ghwcfg4
;
4978 DWC_PRINTF("GHWCFG4 @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4979 DWC_READ_REG32(addr
));
4980 addr
= &core_if
->core_global_regs
->glpmcfg
;
4981 DWC_PRINTF("GLPMCFG @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4982 DWC_READ_REG32(addr
));
4983 addr
= &core_if
->core_global_regs
->gpwrdn
;
4984 DWC_PRINTF("GPWRDN @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4985 DWC_READ_REG32(addr
));
4986 addr
= &core_if
->core_global_regs
->gdfifocfg
;
4987 DWC_PRINTF("GDFIFOCFG @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4988 DWC_READ_REG32(addr
));
4989 addr
= &core_if
->core_global_regs
->adpctl
;
4990 DWC_PRINTF("ADPCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4991 dwc_otg_adp_read_reg(core_if
));
4992 addr
= &core_if
->core_global_regs
->hptxfsiz
;
4993 DWC_PRINTF("HPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr
,
4994 DWC_READ_REG32(addr
));
4996 if (core_if
->en_multiple_tx_fifo
== 0) {
4997 ep_num
= core_if
->hwcfg4
.b
.num_dev_perio_in_ep
;
4998 txfsiz
= "DPTXFSIZ";
5000 ep_num
= core_if
->hwcfg4
.b
.num_in_eps
;
5001 txfsiz
= "DIENPTXF";
5003 for (i
= 0; i
< ep_num
; i
++) {
5004 addr
= &core_if
->core_global_regs
->dtxfsiz
[i
];
5005 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz
, i
+ 1,
5006 (unsigned long)addr
, DWC_READ_REG32(addr
));
5008 addr
= core_if
->pcgcctl
;
5009 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr
,
5010 DWC_READ_REG32(addr
));
5016 * @param core_if Programming view of DWC_otg controller.
5017 * @param num Tx FIFO to flush.
5019 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t
* core_if
, const int num
)
5021 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
5022 volatile grstctl_t greset
= {.d32
= 0 };
5025 DWC_DEBUGPL((DBG_CIL
| DBG_PCDV
), "Flush Tx FIFO %d\n", num
);
5027 greset
.b
.txfflsh
= 1;
5028 greset
.b
.txfnum
= num
;
5029 DWC_WRITE_REG32(&global_regs
->grstctl
, greset
.d32
);
5032 greset
.d32
= DWC_READ_REG32(&global_regs
->grstctl
);
5033 if (++count
> 10000) {
5034 DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5035 __func__
, greset
.d32
,
5036 DWC_READ_REG32(&global_regs
->gnptxsts
));
5040 } while (greset
.b
.txfflsh
== 1);
5042 /* Wait for 3 PHY Clocks */
5049 * @param core_if Programming view of DWC_otg controller.
5051 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t
* core_if
)
5053 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
5054 volatile grstctl_t greset
= {.d32
= 0 };
5057 DWC_DEBUGPL((DBG_CIL
| DBG_PCDV
), "%s\n", __func__
);
5061 greset
.b
.rxfflsh
= 1;
5062 DWC_WRITE_REG32(&global_regs
->grstctl
, greset
.d32
);
5065 greset
.d32
= DWC_READ_REG32(&global_regs
->grstctl
);
5066 if (++count
> 10000) {
5067 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__
,
5072 } while (greset
.b
.rxfflsh
== 1);
5074 /* Wait for 3 PHY Clocks */
5079 * Do core a soft reset of the core. Be careful with this because it
5080 * resets all the internal state machines of the core.
5082 void dwc_otg_core_reset(dwc_otg_core_if_t
* core_if
)
5084 dwc_otg_core_global_regs_t
*global_regs
= core_if
->core_global_regs
;
5085 volatile grstctl_t greset
= {.d32
= 0 };
5088 DWC_DEBUGPL(DBG_CILV
, "%s\n", __func__
);
5089 /* Wait for AHB master IDLE state. */
5092 greset
.d32
= DWC_READ_REG32(&global_regs
->grstctl
);
5093 if (++count
> 100000) {
5094 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__
,
5099 while (greset
.b
.ahbidle
== 0);
5101 /* Core Soft Reset */
5103 greset
.b
.csftrst
= 1;
5104 DWC_WRITE_REG32(&global_regs
->grstctl
, greset
.d32
);
5106 greset
.d32
= DWC_READ_REG32(&global_regs
->grstctl
);
5107 if (++count
> 10000) {
5108 DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5109 __func__
, greset
.d32
);
5114 while (greset
.b
.csftrst
== 1);
5116 /* Wait for 3 PHY Clocks */
5120 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t
* _core_if
)
5122 return (dwc_otg_mode(_core_if
) != DWC_HOST_MODE
);
5125 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t
* _core_if
)
5127 return (dwc_otg_mode(_core_if
) == DWC_HOST_MODE
);
5131 * Register HCD callbacks. The callbacks are used to start and stop
5132 * the HCD for interrupt processing.
5134 * @param core_if Programming view of DWC_otg controller.
5135 * @param cb the HCD callback structure.
5136 * @param p pointer to be passed to callback function (usb_hcd*).
5138 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t
* core_if
,
5139 dwc_otg_cil_callbacks_t
* cb
, void *p
)
5141 core_if
->hcd_cb
= cb
;
5146 * Register PCD callbacks. The callbacks are used to start and stop
5147 * the PCD for interrupt processing.
5149 * @param core_if Programming view of DWC_otg controller.
5150 * @param cb the PCD callback structure.
5151 * @param p pointer to be passed to callback function (pcd*).
5153 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t
* core_if
,
5154 dwc_otg_cil_callbacks_t
* cb
, void *p
)
5156 core_if
->pcd_cb
= cb
;
5163 * This function writes isoc data per 1 (micro)frame into tx fifo
5165 * @param core_if Programming view of DWC_otg controller.
5166 * @param ep The EP to start the transfer on.
5169 void write_isoc_frame_data(dwc_otg_core_if_t
* core_if
, dwc_ep_t
* ep
)
5171 dwc_otg_dev_in_ep_regs_t
*ep_regs
;
5172 dtxfsts_data_t txstatus
= {.d32
= 0 };
5176 ep
->xfer_len
= ep
->data_per_frame
;
5179 ep_regs
= core_if
->dev_if
->in_ep_regs
[ep
->num
];
5181 len
= ep
->xfer_len
- ep
->xfer_count
;
5183 if (len
> ep
->maxpacket
) {
5184 len
= ep
->maxpacket
;
5187 dwords
= (len
+ 3) / 4;
5189 /* While there is space in the queue and space in the FIFO and
5190 * More data to tranfer, Write packets to the Tx FIFO */
5192 DWC_READ_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->dtxfsts
);
5193 DWC_DEBUGPL(DBG_PCDV
, "b4 dtxfsts[%d]=0x%08x\n", ep
->num
, txstatus
.d32
);
5195 while (txstatus
.b
.txfspcavail
> dwords
&&
5196 ep
->xfer_count
< ep
->xfer_len
&& ep
->xfer_len
!= 0) {
5197 /* Write the FIFO */
5198 dwc_otg_ep_write_packet(core_if
, ep
, 0);
5200 len
= ep
->xfer_len
- ep
->xfer_count
;
5201 if (len
> ep
->maxpacket
) {
5202 len
= ep
->maxpacket
;
5205 dwords
= (len
+ 3) / 4;
5207 DWC_READ_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->
5209 DWC_DEBUGPL(DBG_PCDV
, "dtxfsts[%d]=0x%08x\n", ep
->num
,
5215 * This function initializes a descriptor chain for Isochronous transfer
5217 * @param core_if Programming view of DWC_otg controller.
5218 * @param ep The EP to start the transfer on.
5221 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t
* core_if
,
5224 deptsiz_data_t deptsiz
= {.d32
= 0 };
5225 depctl_data_t depctl
= {.d32
= 0 };
5226 dsts_data_t dsts
= {.d32
= 0 };
5227 volatile uint32_t *addr
;
5230 addr
= &core_if
->dev_if
->in_ep_regs
[ep
->num
]->diepctl
;
5232 addr
= &core_if
->dev_if
->out_ep_regs
[ep
->num
]->doepctl
;
5235 ep
->xfer_len
= ep
->data_per_frame
;
5237 ep
->xfer_buff
= ep
->cur_pkt_addr
;
5238 ep
->dma_addr
= ep
->cur_pkt_dma_addr
;
5241 /* Program the transfer size and packet count
5242 * as follows: xfersize = N * maxpacket +
5243 * short_packet pktcnt = N + (short_packet
5246 deptsiz
.b
.xfersize
= ep
->xfer_len
;
5248 (ep
->xfer_len
- 1 + ep
->maxpacket
) / ep
->maxpacket
;
5249 deptsiz
.b
.mc
= deptsiz
.b
.pktcnt
;
5250 DWC_WRITE_REG32(&core_if
->dev_if
->in_ep_regs
[ep
->num
]->dieptsiz
,
5253 /* Write the DMA register */
5254 if (core_if
->dma_enable
) {
5256 (core_if
->dev_if
->in_ep_regs
[ep
->num
]->
5257 diepdma
), (uint32_t) ep
->dma_addr
);
5261 (ep
->xfer_len
+ (ep
->maxpacket
- 1)) / ep
->maxpacket
;
5262 deptsiz
.b
.xfersize
= deptsiz
.b
.pktcnt
* ep
->maxpacket
;
5264 DWC_WRITE_REG32(&core_if
->dev_if
->
5265 out_ep_regs
[ep
->num
]->doeptsiz
, deptsiz
.d32
);
5267 if (core_if
->dma_enable
) {
5270 out_ep_regs
[ep
->num
]->doepdma
),
5271 (uint32_t) ep
->dma_addr
);
5275 /** Enable endpoint, clear nak */
5278 if (ep
->bInterval
== 1) {
5280 DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dsts
);
5281 ep
->next_frame
= dsts
.b
.soffn
+ ep
->bInterval
;
5283 if (ep
->next_frame
& 0x1) {
5284 depctl
.b
.setd1pid
= 1;
5286 depctl
.b
.setd0pid
= 1;
5289 ep
->next_frame
+= ep
->bInterval
;
5291 if (ep
->next_frame
& 0x1) {
5292 depctl
.b
.setd1pid
= 1;
5294 depctl
.b
.setd0pid
= 1;
5300 DWC_MODIFY_REG32(addr
, 0, depctl
.d32
);
5301 depctl
.d32
= DWC_READ_REG32(addr
);
5303 if (ep
->is_in
&& core_if
->dma_enable
== 0) {
5304 write_isoc_frame_data(core_if
, ep
);
5308 #endif /* DWC_EN_ISOC */
5310 static void dwc_otg_set_uninitialized(int32_t * p
, int size
)
5313 for (i
= 0; i
< size
; i
++) {
5318 static int dwc_otg_param_initialized(int32_t val
)
5323 static int dwc_otg_setup_params(dwc_otg_core_if_t
* core_if
)
5326 core_if
->core_params
= DWC_ALLOC(sizeof(*core_if
->core_params
));
5327 if (!core_if
->core_params
) {
5328 return -DWC_E_NO_MEMORY
;
5330 dwc_otg_set_uninitialized((int32_t *) core_if
->core_params
,
5331 sizeof(*core_if
->core_params
) /
5333 DWC_PRINTF("Setting default values for core params\n");
5334 dwc_otg_set_param_otg_cap(core_if
, dwc_param_otg_cap_default
);
5335 dwc_otg_set_param_dma_enable(core_if
, dwc_param_dma_enable_default
);
5336 dwc_otg_set_param_dma_desc_enable(core_if
,
5337 dwc_param_dma_desc_enable_default
);
5338 dwc_otg_set_param_opt(core_if
, dwc_param_opt_default
);
5339 dwc_otg_set_param_dma_burst_size(core_if
,
5340 dwc_param_dma_burst_size_default
);
5341 dwc_otg_set_param_host_support_fs_ls_low_power(core_if
,
5342 dwc_param_host_support_fs_ls_low_power_default
);
5343 dwc_otg_set_param_enable_dynamic_fifo(core_if
,
5344 dwc_param_enable_dynamic_fifo_default
);
5345 dwc_otg_set_param_data_fifo_size(core_if
,
5346 dwc_param_data_fifo_size_default
);
5347 dwc_otg_set_param_dev_rx_fifo_size(core_if
,
5348 dwc_param_dev_rx_fifo_size_default
);
5349 dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if
,
5350 dwc_param_dev_nperio_tx_fifo_size_default
);
5351 dwc_otg_set_param_host_rx_fifo_size(core_if
,
5352 dwc_param_host_rx_fifo_size_default
);
5353 dwc_otg_set_param_host_nperio_tx_fifo_size(core_if
,
5354 dwc_param_host_nperio_tx_fifo_size_default
);
5355 dwc_otg_set_param_host_perio_tx_fifo_size(core_if
,
5356 dwc_param_host_perio_tx_fifo_size_default
);
5357 dwc_otg_set_param_max_transfer_size(core_if
,
5358 dwc_param_max_transfer_size_default
);
5359 dwc_otg_set_param_max_packet_count(core_if
,
5360 dwc_param_max_packet_count_default
);
5361 dwc_otg_set_param_host_channels(core_if
,
5362 dwc_param_host_channels_default
);
5363 dwc_otg_set_param_dev_endpoints(core_if
,
5364 dwc_param_dev_endpoints_default
);
5365 dwc_otg_set_param_phy_type(core_if
, dwc_param_phy_type_default
);
5366 dwc_otg_set_param_speed(core_if
, dwc_param_speed_default
);
5367 dwc_otg_set_param_host_ls_low_power_phy_clk(core_if
,
5368 dwc_param_host_ls_low_power_phy_clk_default
);
5369 dwc_otg_set_param_phy_ulpi_ddr(core_if
, dwc_param_phy_ulpi_ddr_default
);
5370 dwc_otg_set_param_phy_ulpi_ext_vbus(core_if
,
5371 dwc_param_phy_ulpi_ext_vbus_default
);
5372 dwc_otg_set_param_phy_utmi_width(core_if
,
5373 dwc_param_phy_utmi_width_default
);
5374 dwc_otg_set_param_ts_dline(core_if
, dwc_param_ts_dline_default
);
5375 dwc_otg_set_param_i2c_enable(core_if
, dwc_param_i2c_enable_default
);
5376 dwc_otg_set_param_ulpi_fs_ls(core_if
, dwc_param_ulpi_fs_ls_default
);
5377 dwc_otg_set_param_en_multiple_tx_fifo(core_if
,
5378 dwc_param_en_multiple_tx_fifo_default
);
5379 for (i
= 0; i
< 15; i
++) {
5380 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if
,
5381 dwc_param_dev_perio_tx_fifo_size_default
,
5385 for (i
= 0; i
< 15; i
++) {
5386 dwc_otg_set_param_dev_tx_fifo_size(core_if
,
5387 dwc_param_dev_tx_fifo_size_default
,
5390 dwc_otg_set_param_thr_ctl(core_if
, dwc_param_thr_ctl_default
);
5391 dwc_otg_set_param_mpi_enable(core_if
, dwc_param_mpi_enable_default
);
5392 dwc_otg_set_param_pti_enable(core_if
, dwc_param_pti_enable_default
);
5393 dwc_otg_set_param_lpm_enable(core_if
, dwc_param_lpm_enable_default
);
5394 dwc_otg_set_param_ic_usb_cap(core_if
, dwc_param_ic_usb_cap_default
);
5395 dwc_otg_set_param_tx_thr_length(core_if
,
5396 dwc_param_tx_thr_length_default
);
5397 dwc_otg_set_param_rx_thr_length(core_if
,
5398 dwc_param_rx_thr_length_default
);
5399 dwc_otg_set_param_ahb_thr_ratio(core_if
,
5400 dwc_param_ahb_thr_ratio_default
);
5401 dwc_otg_set_param_power_down(core_if
, dwc_param_power_down_default
);
5402 dwc_otg_set_param_reload_ctl(core_if
, dwc_param_reload_ctl_default
);
5403 dwc_otg_set_param_dev_out_nak(core_if
, dwc_param_dev_out_nak_default
);
5404 dwc_otg_set_param_cont_on_bna(core_if
, dwc_param_cont_on_bna_default
);
5405 dwc_otg_set_param_ahb_single(core_if
, dwc_param_ahb_single_default
);
5406 dwc_otg_set_param_otg_ver(core_if
, dwc_param_otg_ver_default
);
5407 dwc_otg_set_param_adp_enable(core_if
, dwc_param_adp_enable_default
);
5408 DWC_PRINTF("Finished setting default values for core params\n");
5413 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t
* core_if
)
5415 return core_if
->dma_enable
;
5418 /* Checks if the parameter is outside of its valid range of values */
5419 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
5420 (((_param_) < (_low_)) || \
5421 ((_param_) > (_high_)))
5423 /* Parameter access functions */
5424 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t
* core_if
, int32_t val
)
5428 if (DWC_OTG_PARAM_TEST(val
, 0, 2)) {
5429 DWC_WARN("Wrong value for otg_cap parameter\n");
5430 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
5431 retval
= -DWC_E_INVALID
;
5437 case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE
:
5438 if (core_if
->hwcfg2
.b
.op_mode
!=
5439 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG
)
5442 case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE
:
5443 if ((core_if
->hwcfg2
.b
.op_mode
!=
5444 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG
)
5445 && (core_if
->hwcfg2
.b
.op_mode
!=
5446 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG
)
5447 && (core_if
->hwcfg2
.b
.op_mode
!=
5448 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE
)
5449 && (core_if
->hwcfg2
.b
.op_mode
!=
5450 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST
)) {
5454 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
:
5459 if (dwc_otg_param_initialized(core_if
->core_params
->otg_cap
)) {
5461 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5465 (((core_if
->hwcfg2
.b
.op_mode
==
5466 DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG
)
5467 || (core_if
->hwcfg2
.b
.op_mode
==
5468 DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG
)
5469 || (core_if
->hwcfg2
.b
.op_mode
==
5470 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE
)
5471 || (core_if
->hwcfg2
.b
.op_mode
==
5472 DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST
)) ?
5473 DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE
:
5474 DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE
);
5475 retval
= -DWC_E_INVALID
;
5478 core_if
->core_params
->otg_cap
= val
;
5483 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t
* core_if
)
5485 return core_if
->core_params
->otg_cap
;
5488 int dwc_otg_set_param_opt(dwc_otg_core_if_t
* core_if
, int32_t val
)
5490 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5491 DWC_WARN("Wrong value for opt parameter\n");
5492 return -DWC_E_INVALID
;
5494 core_if
->core_params
->opt
= val
;
5498 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t
* core_if
)
5500 return core_if
->core_params
->opt
;
5503 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
5506 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5507 DWC_WARN("Wrong value for dma enable\n");
5508 return -DWC_E_INVALID
;
5511 if ((val
== 1) && (core_if
->hwcfg2
.b
.architecture
== 0)) {
5512 if (dwc_otg_param_initialized(core_if
->core_params
->dma_enable
)) {
5514 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5518 retval
= -DWC_E_INVALID
;
5521 core_if
->core_params
->dma_enable
= val
;
5523 dwc_otg_set_param_dma_desc_enable(core_if
, 0);
5528 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t
* core_if
)
5530 return core_if
->core_params
->dma_enable
;
5533 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
5536 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5537 DWC_WARN("Wrong value for dma_enable\n");
5538 DWC_WARN("dma_desc_enable must be 0 or 1\n");
5539 return -DWC_E_INVALID
;
5543 && ((dwc_otg_get_param_dma_enable(core_if
) == 0)
5544 || (core_if
->hwcfg4
.b
.desc_dma
== 0))) {
5545 if (dwc_otg_param_initialized
5546 (core_if
->core_params
->dma_desc_enable
)) {
5548 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5552 retval
= -DWC_E_INVALID
;
5554 core_if
->core_params
->dma_desc_enable
= val
;
5558 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t
* core_if
)
5560 return core_if
->core_params
->dma_desc_enable
;
5563 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t
* core_if
,
5566 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5567 DWC_WARN("Wrong value for host_support_fs_low_power\n");
5568 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
5569 return -DWC_E_INVALID
;
5571 core_if
->core_params
->host_support_fs_ls_low_power
= val
;
5575 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t
*
5578 return core_if
->core_params
->host_support_fs_ls_low_power
;
5581 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t
* core_if
,
5585 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5586 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
5587 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
5588 return -DWC_E_INVALID
;
5591 if ((val
== 1) && (core_if
->hwcfg2
.b
.dynamic_fifo
== 0)) {
5592 if (dwc_otg_param_initialized
5593 (core_if
->core_params
->enable_dynamic_fifo
)) {
5595 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
5599 retval
= -DWC_E_INVALID
;
5601 core_if
->core_params
->enable_dynamic_fifo
= val
;
5605 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t
* core_if
)
5607 return core_if
->core_params
->enable_dynamic_fifo
;
5610 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t
* core_if
, int32_t val
)
5613 if (DWC_OTG_PARAM_TEST(val
, 32, 32768)) {
5614 DWC_WARN("Wrong value for data_fifo_size\n");
5615 DWC_WARN("data_fifo_size must be 32-32768\n");
5616 return -DWC_E_INVALID
;
5619 if (val
> core_if
->hwcfg3
.b
.dfifo_depth
) {
5620 if (dwc_otg_param_initialized
5621 (core_if
->core_params
->data_fifo_size
)) {
5623 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
5626 val
= core_if
->hwcfg3
.b
.dfifo_depth
;
5627 retval
= -DWC_E_INVALID
;
5630 core_if
->core_params
->data_fifo_size
= val
;
5634 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t
* core_if
)
5636 return core_if
->core_params
->data_fifo_size
;
5639 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t
* core_if
, int32_t val
)
5642 if (DWC_OTG_PARAM_TEST(val
, 16, 32768)) {
5643 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
5644 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
5645 return -DWC_E_INVALID
;
5648 if (val
> DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
)) {
5649 if (dwc_otg_param_initialized(core_if
->core_params
->dev_rx_fifo_size
)) {
5650 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val
);
5652 val
= DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
);
5653 retval
= -DWC_E_INVALID
;
5656 core_if
->core_params
->dev_rx_fifo_size
= val
;
5660 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t
* core_if
)
5662 return core_if
->core_params
->dev_rx_fifo_size
;
5665 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
5670 if (DWC_OTG_PARAM_TEST(val
, 16, 32768)) {
5671 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
5672 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
5673 return -DWC_E_INVALID
;
5676 if (val
> (DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
) >> 16)) {
5677 if (dwc_otg_param_initialized
5678 (core_if
->core_params
->dev_nperio_tx_fifo_size
)) {
5680 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
5684 (DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
) >>
5686 retval
= -DWC_E_INVALID
;
5689 core_if
->core_params
->dev_nperio_tx_fifo_size
= val
;
5693 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t
* core_if
)
5695 return core_if
->core_params
->dev_nperio_tx_fifo_size
;
5698 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t
* core_if
,
5703 if (DWC_OTG_PARAM_TEST(val
, 16, 32768)) {
5704 DWC_WARN("Wrong value for host_rx_fifo_size\n");
5705 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
5706 return -DWC_E_INVALID
;
5709 if (val
> DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
)) {
5710 if (dwc_otg_param_initialized
5711 (core_if
->core_params
->host_rx_fifo_size
)) {
5713 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
5716 val
= DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
);
5717 retval
= -DWC_E_INVALID
;
5720 core_if
->core_params
->host_rx_fifo_size
= val
;
5725 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t
* core_if
)
5727 return core_if
->core_params
->host_rx_fifo_size
;
5730 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
5735 if (DWC_OTG_PARAM_TEST(val
, 16, 32768)) {
5736 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
5737 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
5738 return -DWC_E_INVALID
;
5741 if (val
> (DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
) >> 16)) {
5742 if (dwc_otg_param_initialized
5743 (core_if
->core_params
->host_nperio_tx_fifo_size
)) {
5745 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
5749 (DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
) >>
5751 retval
= -DWC_E_INVALID
;
5754 core_if
->core_params
->host_nperio_tx_fifo_size
= val
;
5758 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t
* core_if
)
5760 return core_if
->core_params
->host_nperio_tx_fifo_size
;
5763 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
5767 if (DWC_OTG_PARAM_TEST(val
, 16, 32768)) {
5768 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
5769 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
5770 return -DWC_E_INVALID
;
5773 if (val
> ((core_if
->hptxfsiz
.d32
) >> 16)) {
5774 if (dwc_otg_param_initialized
5775 (core_if
->core_params
->host_perio_tx_fifo_size
)) {
5777 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
5780 val
= (core_if
->hptxfsiz
.d32
) >> 16;
5781 retval
= -DWC_E_INVALID
;
5784 core_if
->core_params
->host_perio_tx_fifo_size
= val
;
5788 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t
* core_if
)
5790 return core_if
->core_params
->host_perio_tx_fifo_size
;
5793 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t
* core_if
,
5798 if (DWC_OTG_PARAM_TEST(val
, 2047, 524288)) {
5799 DWC_WARN("Wrong value for max_transfer_size\n");
5800 DWC_WARN("max_transfer_size must be 2047-524288\n");
5801 return -DWC_E_INVALID
;
5804 if (val
>= (1 << (core_if
->hwcfg3
.b
.xfer_size_cntr_width
+ 11))) {
5805 if (dwc_otg_param_initialized
5806 (core_if
->core_params
->max_transfer_size
)) {
5808 ("%d invalid for max_transfer_size. Check HW configuration.\n",
5812 ((1 << (core_if
->hwcfg3
.b
.packet_size_cntr_width
+ 11)) -
5814 retval
= -DWC_E_INVALID
;
5817 core_if
->core_params
->max_transfer_size
= val
;
5821 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t
* core_if
)
5823 return core_if
->core_params
->max_transfer_size
;
5826 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t
* core_if
, int32_t val
)
5830 if (DWC_OTG_PARAM_TEST(val
, 15, 511)) {
5831 DWC_WARN("Wrong value for max_packet_count\n");
5832 DWC_WARN("max_packet_count must be 15-511\n");
5833 return -DWC_E_INVALID
;
5836 if (val
> (1 << (core_if
->hwcfg3
.b
.packet_size_cntr_width
+ 4))) {
5837 if (dwc_otg_param_initialized
5838 (core_if
->core_params
->max_packet_count
)) {
5840 ("%d invalid for max_packet_count. Check HW configuration.\n",
5844 ((1 << (core_if
->hwcfg3
.b
.packet_size_cntr_width
+ 4)) - 1);
5845 retval
= -DWC_E_INVALID
;
5848 core_if
->core_params
->max_packet_count
= val
;
5852 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t
* core_if
)
5854 return core_if
->core_params
->max_packet_count
;
5857 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t
* core_if
, int32_t val
)
5861 if (DWC_OTG_PARAM_TEST(val
, 1, 16)) {
5862 DWC_WARN("Wrong value for host_channels\n");
5863 DWC_WARN("host_channels must be 1-16\n");
5864 return -DWC_E_INVALID
;
5867 if (val
> (core_if
->hwcfg2
.b
.num_host_chan
+ 1)) {
5868 if (dwc_otg_param_initialized
5869 (core_if
->core_params
->host_channels
)) {
5871 ("%d invalid for host_channels. Check HW configurations.\n",
5874 val
= (core_if
->hwcfg2
.b
.num_host_chan
+ 1);
5875 retval
= -DWC_E_INVALID
;
5878 core_if
->core_params
->host_channels
= val
;
5882 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t
* core_if
)
5884 return core_if
->core_params
->host_channels
;
5887 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t
* core_if
, int32_t val
)
5891 if (DWC_OTG_PARAM_TEST(val
, 1, 15)) {
5892 DWC_WARN("Wrong value for dev_endpoints\n");
5893 DWC_WARN("dev_endpoints must be 1-15\n");
5894 return -DWC_E_INVALID
;
5897 if (val
> (core_if
->hwcfg2
.b
.num_dev_ep
)) {
5898 if (dwc_otg_param_initialized
5899 (core_if
->core_params
->dev_endpoints
)) {
5901 ("%d invalid for dev_endpoints. Check HW configurations.\n",
5904 val
= core_if
->hwcfg2
.b
.num_dev_ep
;
5905 retval
= -DWC_E_INVALID
;
5908 core_if
->core_params
->dev_endpoints
= val
;
5912 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t
* core_if
)
5914 return core_if
->core_params
->dev_endpoints
;
5917 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t
* core_if
, int32_t val
)
5922 if (DWC_OTG_PARAM_TEST(val
, 0, 2)) {
5923 DWC_WARN("Wrong value for phy_type\n");
5924 DWC_WARN("phy_type must be 0,1 or 2\n");
5925 return -DWC_E_INVALID
;
5927 #ifndef NO_FS_PHY_HW_CHECKS
5928 if ((val
== DWC_PHY_TYPE_PARAM_UTMI
) &&
5929 ((core_if
->hwcfg2
.b
.hs_phy_type
== 1) ||
5930 (core_if
->hwcfg2
.b
.hs_phy_type
== 3))) {
5932 } else if ((val
== DWC_PHY_TYPE_PARAM_ULPI
) &&
5933 ((core_if
->hwcfg2
.b
.hs_phy_type
== 2) ||
5934 (core_if
->hwcfg2
.b
.hs_phy_type
== 3))) {
5936 } else if ((val
== DWC_PHY_TYPE_PARAM_FS
) &&
5937 (core_if
->hwcfg2
.b
.fs_phy_type
== 1)) {
5941 if (dwc_otg_param_initialized(core_if
->core_params
->phy_type
)) {
5943 ("%d invalid for phy_type. Check HW configurations.\n",
5946 if (core_if
->hwcfg2
.b
.hs_phy_type
) {
5947 if ((core_if
->hwcfg2
.b
.hs_phy_type
== 3) ||
5948 (core_if
->hwcfg2
.b
.hs_phy_type
== 1)) {
5949 val
= DWC_PHY_TYPE_PARAM_UTMI
;
5951 val
= DWC_PHY_TYPE_PARAM_ULPI
;
5954 retval
= -DWC_E_INVALID
;
5957 core_if
->core_params
->phy_type
= val
;
5961 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t
* core_if
)
5963 return core_if
->core_params
->phy_type
;
5966 int dwc_otg_set_param_speed(dwc_otg_core_if_t
* core_if
, int32_t val
)
5969 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
5970 DWC_WARN("Wrong value for speed parameter\n");
5971 DWC_WARN("max_speed parameter must be 0 or 1\n");
5972 return -DWC_E_INVALID
;
5975 && dwc_otg_get_param_phy_type(core_if
) == DWC_PHY_TYPE_PARAM_FS
) {
5976 if (dwc_otg_param_initialized(core_if
->core_params
->speed
)) {
5978 ("%d invalid for speed paremter. Check HW configuration.\n",
5982 (dwc_otg_get_param_phy_type(core_if
) ==
5983 DWC_PHY_TYPE_PARAM_FS
? 1 : 0);
5984 retval
= -DWC_E_INVALID
;
5986 core_if
->core_params
->speed
= val
;
5990 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t
* core_if
)
5992 return core_if
->core_params
->speed
;
5995 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t
* core_if
,
6000 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6002 ("Wrong value for host_ls_low_power_phy_clk parameter\n");
6003 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
6004 return -DWC_E_INVALID
;
6007 if ((val
== DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ
)
6008 && (dwc_otg_get_param_phy_type(core_if
) == DWC_PHY_TYPE_PARAM_FS
)) {
6009 if (dwc_otg_param_initialized
6010 (core_if
->core_params
->host_ls_low_power_phy_clk
)) {
6012 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6016 (dwc_otg_get_param_phy_type(core_if
) ==
6017 DWC_PHY_TYPE_PARAM_FS
) ?
6018 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ
:
6019 DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ
;
6020 retval
= -DWC_E_INVALID
;
6023 core_if
->core_params
->host_ls_low_power_phy_clk
= val
;
6027 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t
* core_if
)
6029 return core_if
->core_params
->host_ls_low_power_phy_clk
;
6032 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t
* core_if
, int32_t val
)
6034 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6035 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
6036 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
6037 return -DWC_E_INVALID
;
6040 core_if
->core_params
->phy_ulpi_ddr
= val
;
6044 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t
* core_if
)
6046 return core_if
->core_params
->phy_ulpi_ddr
;
6049 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t
* core_if
,
6052 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6053 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
6054 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
6055 return -DWC_E_INVALID
;
6058 core_if
->core_params
->phy_ulpi_ext_vbus
= val
;
6062 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t
* core_if
)
6064 return core_if
->core_params
->phy_ulpi_ext_vbus
;
6067 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t
* core_if
, int32_t val
)
6069 if (DWC_OTG_PARAM_TEST(val
, 8, 8) && DWC_OTG_PARAM_TEST(val
, 16, 16)) {
6070 DWC_WARN("Wrong valaue for phy_utmi_width\n");
6071 DWC_WARN("phy_utmi_width must be 8 or 16\n");
6072 return -DWC_E_INVALID
;
6075 core_if
->core_params
->phy_utmi_width
= val
;
6079 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t
* core_if
)
6081 return core_if
->core_params
->phy_utmi_width
;
6084 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t
* core_if
, int32_t val
)
6086 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6087 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
6088 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
6089 return -DWC_E_INVALID
;
6092 core_if
->core_params
->ulpi_fs_ls
= val
;
6096 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t
* core_if
)
6098 return core_if
->core_params
->ulpi_fs_ls
;
6101 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t
* core_if
, int32_t val
)
6103 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6104 DWC_WARN("Wrong valaue for ts_dline\n");
6105 DWC_WARN("ts_dline must be 0 or 1\n");
6106 return -DWC_E_INVALID
;
6109 core_if
->core_params
->ts_dline
= val
;
6113 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t
* core_if
)
6115 return core_if
->core_params
->ts_dline
;
6118 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
6121 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6122 DWC_WARN("Wrong valaue for i2c_enable\n");
6123 DWC_WARN("i2c_enable must be 0 or 1\n");
6124 return -DWC_E_INVALID
;
6126 #ifndef NO_FS_PHY_HW_CHECK
6127 if (val
== 1 && core_if
->hwcfg3
.b
.i2c
== 0) {
6128 if (dwc_otg_param_initialized(core_if
->core_params
->i2c_enable
)) {
6130 ("%d invalid for i2c_enable. Check HW configuration.\n",
6134 retval
= -DWC_E_INVALID
;
6138 core_if
->core_params
->i2c_enable
= val
;
6142 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t
* core_if
)
6144 return core_if
->core_params
->i2c_enable
;
6147 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
6148 int32_t val
, int fifo_num
)
6152 if (DWC_OTG_PARAM_TEST(val
, 4, 768)) {
6153 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
6154 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
6155 return -DWC_E_INVALID
;
6159 (DWC_READ_REG32(&core_if
->core_global_regs
->dtxfsiz
[fifo_num
]))) {
6160 if (dwc_otg_param_initialized
6161 (core_if
->core_params
->dev_perio_tx_fifo_size
[fifo_num
])) {
6163 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6166 val
= (DWC_READ_REG32(&core_if
->core_global_regs
->dtxfsiz
[fifo_num
]));
6167 retval
= -DWC_E_INVALID
;
6170 core_if
->core_params
->dev_perio_tx_fifo_size
[fifo_num
] = val
;
6174 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
6177 return core_if
->core_params
->dev_perio_tx_fifo_size
[fifo_num
];
6180 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t
* core_if
,
6184 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6185 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
6186 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
6187 return -DWC_E_INVALID
;
6190 if (val
== 1 && core_if
->hwcfg4
.b
.ded_fifo_en
== 0) {
6191 if (dwc_otg_param_initialized
6192 (core_if
->core_params
->en_multiple_tx_fifo
)) {
6194 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6198 retval
= -DWC_E_INVALID
;
6201 core_if
->core_params
->en_multiple_tx_fifo
= val
;
6205 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t
* core_if
)
6207 return core_if
->core_params
->en_multiple_tx_fifo
;
6210 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t
* core_if
, int32_t val
,
6215 if (DWC_OTG_PARAM_TEST(val
, 4, 768)) {
6216 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
6217 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
6218 return -DWC_E_INVALID
;
6222 (DWC_READ_REG32(&core_if
->core_global_regs
->dtxfsiz
[fifo_num
]))) {
6223 if (dwc_otg_param_initialized
6224 (core_if
->core_params
->dev_tx_fifo_size
[fifo_num
])) {
6226 ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
6229 val
= (DWC_READ_REG32(&core_if
->core_global_regs
->dtxfsiz
[fifo_num
]));
6230 retval
= -DWC_E_INVALID
;
6233 core_if
->core_params
->dev_tx_fifo_size
[fifo_num
] = val
;
6237 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t
* core_if
,
6240 return core_if
->core_params
->dev_tx_fifo_size
[fifo_num
];
6243 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t
* core_if
, int32_t val
)
6247 if (DWC_OTG_PARAM_TEST(val
, 0, 7)) {
6248 DWC_WARN("Wrong value for thr_ctl\n");
6249 DWC_WARN("thr_ctl must be 0-7\n");
6250 return -DWC_E_INVALID
;
6254 (!dwc_otg_get_param_dma_enable(core_if
) ||
6255 !core_if
->hwcfg4
.b
.ded_fifo_en
)) {
6256 if (dwc_otg_param_initialized(core_if
->core_params
->thr_ctl
)) {
6258 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6262 retval
= -DWC_E_INVALID
;
6265 core_if
->core_params
->thr_ctl
= val
;
6269 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t
* core_if
)
6271 return core_if
->core_params
->thr_ctl
;
6274 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
6278 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6279 DWC_WARN("Wrong value for lpm_enable\n");
6280 DWC_WARN("lpm_enable must be 0 or 1\n");
6281 return -DWC_E_INVALID
;
6284 if (val
&& !core_if
->hwcfg3
.b
.otg_lpm_en
) {
6285 if (dwc_otg_param_initialized(core_if
->core_params
->lpm_enable
)) {
6287 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6291 retval
= -DWC_E_INVALID
;
6294 core_if
->core_params
->lpm_enable
= val
;
6298 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t
* core_if
)
6300 return core_if
->core_params
->lpm_enable
;
6303 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t
* core_if
, int32_t val
)
6305 if (DWC_OTG_PARAM_TEST(val
, 8, 128)) {
6306 DWC_WARN("Wrong valaue for tx_thr_length\n");
6307 DWC_WARN("tx_thr_length must be 8 - 128\n");
6308 return -DWC_E_INVALID
;
6311 core_if
->core_params
->tx_thr_length
= val
;
6315 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t
* core_if
)
6317 return core_if
->core_params
->tx_thr_length
;
6320 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t
* core_if
, int32_t val
)
6322 if (DWC_OTG_PARAM_TEST(val
, 8, 128)) {
6323 DWC_WARN("Wrong valaue for rx_thr_length\n");
6324 DWC_WARN("rx_thr_length must be 8 - 128\n");
6325 return -DWC_E_INVALID
;
6328 core_if
->core_params
->rx_thr_length
= val
;
6332 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t
* core_if
)
6334 return core_if
->core_params
->rx_thr_length
;
6337 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t
* core_if
, int32_t val
)
6339 if (DWC_OTG_PARAM_TEST(val
, 1, 1) &&
6340 DWC_OTG_PARAM_TEST(val
, 4, 4) &&
6341 DWC_OTG_PARAM_TEST(val
, 8, 8) &&
6342 DWC_OTG_PARAM_TEST(val
, 16, 16) &&
6343 DWC_OTG_PARAM_TEST(val
, 32, 32) &&
6344 DWC_OTG_PARAM_TEST(val
, 64, 64) &&
6345 DWC_OTG_PARAM_TEST(val
, 128, 128) &&
6346 DWC_OTG_PARAM_TEST(val
, 256, 256)) {
6347 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val
);
6348 return -DWC_E_INVALID
;
6350 core_if
->core_params
->dma_burst_size
= val
;
6354 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t
* core_if
)
6356 return core_if
->core_params
->dma_burst_size
;
6359 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
6362 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6363 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val
);
6364 return -DWC_E_INVALID
;
6366 if (val
&& (core_if
->snpsid
< OTG_CORE_REV_2_72a
)) {
6367 if (dwc_otg_param_initialized(core_if
->core_params
->pti_enable
)) {
6369 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6372 retval
= -DWC_E_INVALID
;
6375 core_if
->core_params
->pti_enable
= val
;
6379 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t
* core_if
)
6381 return core_if
->core_params
->pti_enable
;
6384 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
6387 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6388 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val
);
6389 return -DWC_E_INVALID
;
6391 if (val
&& (core_if
->hwcfg2
.b
.multi_proc_int
== 0)) {
6392 if (dwc_otg_param_initialized(core_if
->core_params
->mpi_enable
)) {
6394 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6397 retval
= -DWC_E_INVALID
;
6400 core_if
->core_params
->mpi_enable
= val
;
6404 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t
* core_if
)
6406 return core_if
->core_params
->mpi_enable
;
6409 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t
* core_if
, int32_t val
)
6412 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6413 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val
);
6414 return -DWC_E_INVALID
;
6416 if (val
&& (core_if
->hwcfg3
.b
.adp_supp
== 0)) {
6417 if (dwc_otg_param_initialized
6418 (core_if
->core_params
->adp_supp_enable
)) {
6420 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6423 retval
= -DWC_E_INVALID
;
6426 core_if
->core_params
->adp_supp_enable
= val
;
6427 /*Set OTG version 2.0 in case of enabling ADP*/
6429 dwc_otg_set_param_otg_ver(core_if
, 1);
6434 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t
* core_if
)
6436 return core_if
->core_params
->adp_supp_enable
;
6439 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t
* core_if
, int32_t val
)
6442 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6443 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val
);
6444 DWC_WARN("ic_usb_cap must be 0 or 1\n");
6445 return -DWC_E_INVALID
;
6448 if (val
&& (core_if
->hwcfg2
.b
.otg_enable_ic_usb
== 0)) {
6449 if (dwc_otg_param_initialized(core_if
->core_params
->ic_usb_cap
)) {
6451 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6454 retval
= -DWC_E_INVALID
;
6457 core_if
->core_params
->ic_usb_cap
= val
;
6461 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t
* core_if
)
6463 return core_if
->core_params
->ic_usb_cap
;
6466 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t
* core_if
, int32_t val
)
6471 if (DWC_OTG_PARAM_TEST(val
, 0, 3)) {
6472 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val
);
6473 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
6474 return -DWC_E_INVALID
;
6478 && (core_if
->snpsid
< OTG_CORE_REV_2_81a
6479 || !dwc_otg_get_param_thr_ctl(core_if
))) {
6482 && ((dwc_otg_get_param_tx_thr_length(core_if
) / (1 << val
)) <
6487 if (dwc_otg_param_initialized
6488 (core_if
->core_params
->ahb_thr_ratio
)) {
6490 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6493 retval
= -DWC_E_INVALID
;
6497 core_if
->core_params
->ahb_thr_ratio
= val
;
6501 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t
* core_if
)
6503 return core_if
->core_params
->ahb_thr_ratio
;
6506 int dwc_otg_set_param_power_down(dwc_otg_core_if_t
* core_if
, int32_t val
)
6510 hwcfg4_data_t hwcfg4
= {.d32
= 0 };
6511 hwcfg4
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->ghwcfg4
);
6513 if (DWC_OTG_PARAM_TEST(val
, 0, 3)) {
6514 DWC_WARN("`%d' invalid for parameter `power_down'\n", val
);
6515 DWC_WARN("power_down must be 0 - 2\n");
6516 return -DWC_E_INVALID
;
6519 if ((val
== 2) && (core_if
->snpsid
< OTG_CORE_REV_2_91a
)) {
6523 && ((core_if
->snpsid
< OTG_CORE_REV_3_00a
)
6524 || (hwcfg4
.b
.xhiber
== 0))) {
6528 if (dwc_otg_param_initialized(core_if
->core_params
->power_down
)) {
6530 ("%d invalid for parameter power_down. Check HW configuration.\n",
6533 retval
= -DWC_E_INVALID
;
6536 core_if
->core_params
->power_down
= val
;
6540 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t
* core_if
)
6542 return core_if
->core_params
->power_down
;
6545 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t
* core_if
, int32_t val
)
6550 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6551 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val
);
6552 DWC_WARN("reload_ctl must be 0 or 1\n");
6553 return -DWC_E_INVALID
;
6556 if ((val
== 1) && (core_if
->snpsid
< OTG_CORE_REV_2_92a
)) {
6560 if (dwc_otg_param_initialized(core_if
->core_params
->reload_ctl
)) {
6561 DWC_ERROR("%d invalid for parameter reload_ctl."
6562 "Check HW configuration.\n", val
);
6564 retval
= -DWC_E_INVALID
;
6567 core_if
->core_params
->reload_ctl
= val
;
6571 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t
* core_if
)
6573 return core_if
->core_params
->reload_ctl
;
6576 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t
* core_if
, int32_t val
)
6581 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6582 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val
);
6583 DWC_WARN("dev_out_nak must be 0 or 1\n");
6584 return -DWC_E_INVALID
;
6587 if ((val
== 1) && ((core_if
->snpsid
< OTG_CORE_REV_2_93a
) ||
6588 !(core_if
->core_params
->dma_desc_enable
))) {
6592 if (dwc_otg_param_initialized(core_if
->core_params
->dev_out_nak
)) {
6593 DWC_ERROR("%d invalid for parameter dev_out_nak."
6594 "Check HW configuration.\n", val
);
6596 retval
= -DWC_E_INVALID
;
6599 core_if
->core_params
->dev_out_nak
= val
;
6603 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t
* core_if
)
6605 return core_if
->core_params
->dev_out_nak
;
6608 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t
* core_if
, int32_t val
)
6613 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6614 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val
);
6615 DWC_WARN("cont_on_bna must be 0 or 1\n");
6616 return -DWC_E_INVALID
;
6619 if ((val
== 1) && ((core_if
->snpsid
< OTG_CORE_REV_2_94a
) ||
6620 !(core_if
->core_params
->dma_desc_enable
))) {
6624 if (dwc_otg_param_initialized(core_if
->core_params
->cont_on_bna
)) {
6625 DWC_ERROR("%d invalid for parameter cont_on_bna."
6626 "Check HW configuration.\n", val
);
6628 retval
= -DWC_E_INVALID
;
6631 core_if
->core_params
->cont_on_bna
= val
;
6635 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t
* core_if
)
6637 return core_if
->core_params
->cont_on_bna
;
6640 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t
* core_if
, int32_t val
)
6645 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6646 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val
);
6647 DWC_WARN("ahb_single must be 0 or 1\n");
6648 return -DWC_E_INVALID
;
6651 if ((val
== 1) && (core_if
->snpsid
< OTG_CORE_REV_2_94a
)) {
6655 if (dwc_otg_param_initialized(core_if
->core_params
->ahb_single
)) {
6656 DWC_ERROR("%d invalid for parameter ahb_single."
6657 "Check HW configuration.\n", val
);
6659 retval
= -DWC_E_INVALID
;
6662 core_if
->core_params
->ahb_single
= val
;
6666 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t
* core_if
)
6668 return core_if
->core_params
->ahb_single
;
6671 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t
* core_if
, int32_t val
)
6675 if (DWC_OTG_PARAM_TEST(val
, 0, 1)) {
6676 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val
);
6678 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
6679 return -DWC_E_INVALID
;
6682 core_if
->core_params
->otg_ver
= val
;
6686 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t
* core_if
)
6688 return core_if
->core_params
->otg_ver
;
6691 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t
* core_if
)
6693 gotgctl_data_t otgctl
;
6694 otgctl
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gotgctl
);
6695 return otgctl
.b
.hstnegscs
;
6698 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t
* core_if
)
6700 gotgctl_data_t otgctl
;
6701 otgctl
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gotgctl
);
6702 return otgctl
.b
.sesreqscs
;
6705 void dwc_otg_set_hnpreq(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6707 if(core_if
->otg_ver
== 0) {
6708 gotgctl_data_t otgctl
;
6709 otgctl
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gotgctl
);
6710 otgctl
.b
.hnpreq
= val
;
6711 DWC_WRITE_REG32(&core_if
->core_global_regs
->gotgctl
, otgctl
.d32
);
6713 core_if
->otg_sts
= val
;
6717 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t
* core_if
)
6719 return core_if
->snpsid
;
6722 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t
* core_if
)
6724 gintsts_data_t gintsts
;
6725 gintsts
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gintsts
);
6726 return gintsts
.b
.curmode
;
6729 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t
* core_if
)
6731 gusbcfg_data_t usbcfg
;
6732 usbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
6733 return usbcfg
.b
.hnpcap
;
6736 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6738 gusbcfg_data_t usbcfg
;
6739 usbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
6740 usbcfg
.b
.hnpcap
= val
;
6741 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, usbcfg
.d32
);
6744 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t
* core_if
)
6746 gusbcfg_data_t usbcfg
;
6747 usbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
6748 return usbcfg
.b
.srpcap
;
6751 void dwc_otg_set_srpcapable(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6753 gusbcfg_data_t usbcfg
;
6754 usbcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
6755 usbcfg
.b
.srpcap
= val
;
6756 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, usbcfg
.d32
);
6759 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t
* core_if
)
6762 /* originally: dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); */
6764 dcfg
.d32
= -1; //GRAYG
6765 DWC_DEBUGPL(DBG_CILV
, "%s - core_if(%p)\n", __func__
, core_if
);
6766 if (NULL
== core_if
)
6767 DWC_ERROR("reg request with NULL core_if\n");
6768 DWC_DEBUGPL(DBG_CILV
, "%s - core_if(%p)->dev_if(%p)\n", __func__
,
6769 core_if
, core_if
->dev_if
);
6770 if (NULL
== core_if
->dev_if
)
6771 DWC_ERROR("reg request with NULL dev_if\n");
6772 DWC_DEBUGPL(DBG_CILV
, "%s - core_if(%p)->dev_if(%p)->"
6773 "dev_global_regs(%p)\n", __func__
,
6774 core_if
, core_if
->dev_if
,
6775 core_if
->dev_if
->dev_global_regs
);
6776 if (NULL
== core_if
->dev_if
->dev_global_regs
)
6777 DWC_ERROR("reg request with NULL dev_global_regs\n");
6779 DWC_DEBUGPL(DBG_CILV
, "%s - &core_if(%p)->dev_if(%p)->"
6780 "dev_global_regs(%p)->dcfg = %p\n", __func__
,
6781 core_if
, core_if
->dev_if
,
6782 core_if
->dev_if
->dev_global_regs
,
6783 &core_if
->dev_if
->dev_global_regs
->dcfg
);
6784 dcfg
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
6786 return dcfg
.b
.devspd
;
6789 void dwc_otg_set_devspeed(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6792 dcfg
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
);
6793 dcfg
.b
.devspd
= val
;
6794 DWC_WRITE_REG32(&core_if
->dev_if
->dev_global_regs
->dcfg
, dcfg
.d32
);
6797 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t
* core_if
)
6800 hprt0
.d32
= DWC_READ_REG32(core_if
->host_if
->hprt0
);
6801 return hprt0
.b
.prtconnsts
;
6804 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t
* core_if
)
6807 dsts
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dsts
);
6808 return dsts
.b
.enumspd
;
6811 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t
* core_if
)
6814 hprt0
.d32
= DWC_READ_REG32(core_if
->host_if
->hprt0
);
6815 return hprt0
.b
.prtpwr
;
6819 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t
* core_if
)
6821 return core_if
->hibernation_suspend
;
6824 void dwc_otg_set_prtpower(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6827 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
6828 hprt0
.b
.prtpwr
= val
;
6829 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
6832 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t
* core_if
)
6835 hprt0
.d32
= DWC_READ_REG32(core_if
->host_if
->hprt0
);
6836 return hprt0
.b
.prtsusp
;
6840 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6843 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
6844 hprt0
.b
.prtsusp
= val
;
6845 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
6848 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t
* core_if
)
6851 hfir
.d32
= DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hfir
);
6852 return hfir
.b
.frint
;
6856 void dwc_otg_set_fr_interval(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6860 fram_int
= calc_frame_interval(core_if
);
6861 hfir
.d32
= DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hfir
);
6862 if (!core_if
->core_params
->reload_ctl
) {
6863 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
6864 "not set to 1.\nShould load driver with reload_ctl=1"
6865 " module parameter\n");
6870 if ((val
< 3350) || (val
> 4150)) {
6871 DWC_WARN("HFIR interval for HS core and 30 MHz"
6872 "clock freq should be from 3350 to 4150\n");
6877 if ((val
< 26820) || (val
> 33180)) {
6878 DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
6879 "clock freq should be from 26820 to 33180\n");
6884 if ((val
< 5360) || (val
> 6640)) {
6885 DWC_WARN("HFIR interval for HS core and 48 MHz"
6886 "clock freq should be from 5360 to 6640\n");
6891 if ((val
< 42912) || (val
> 53088)) {
6892 DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
6893 "clock freq should be from 42912 to 53088\n");
6898 if ((val
< 6700) || (val
> 8300)) {
6899 DWC_WARN("HFIR interval for HS core and 60 MHz"
6900 "clock freq should be from 6700 to 8300\n");
6905 if ((val
< 53640) || (val
> 65536)) {
6906 DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
6907 "clock freq should be from 53640 to 65536\n");
6912 DWC_WARN("Unknown frame interval\n");
6918 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hfir
, hfir
.d32
);
6921 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t
* core_if
)
6924 hcfg
.d32
= DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hcfg
);
6925 return hcfg
.b
.modechtimen
;
6929 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6932 hcfg
.d32
= DWC_READ_REG32(&core_if
->host_if
->host_global_regs
->hcfg
);
6933 hcfg
.b
.modechtimen
= val
;
6934 DWC_WRITE_REG32(&core_if
->host_if
->host_global_regs
->hcfg
, hcfg
.d32
);
6937 void dwc_otg_set_prtresume(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6940 hprt0
.d32
= dwc_otg_read_hprt0(core_if
);
6941 hprt0
.b
.prtres
= val
;
6942 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, hprt0
.d32
);
6945 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t
* core_if
)
6948 dctl
.d32
= DWC_READ_REG32(&core_if
->dev_if
->dev_global_regs
->dctl
);
6949 return dctl
.b
.rmtwkupsig
;
6952 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t
* core_if
)
6954 glpmcfg_data_t lpmcfg
;
6955 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6958 ((core_if
->lx_state
== DWC_OTG_L1
) ^ lpmcfg
.b
.prt_sleep_sts
),
6959 "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
6960 core_if
->lx_state
, lpmcfg
.b
.prt_sleep_sts
);
6962 return lpmcfg
.b
.prt_sleep_sts
;
6965 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t
* core_if
)
6967 glpmcfg_data_t lpmcfg
;
6968 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6969 return lpmcfg
.b
.rem_wkup_en
;
6972 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t
* core_if
)
6974 glpmcfg_data_t lpmcfg
;
6975 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6976 return lpmcfg
.b
.appl_resp
;
6979 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6981 glpmcfg_data_t lpmcfg
;
6982 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6983 lpmcfg
.b
.appl_resp
= val
;
6984 DWC_WRITE_REG32(&core_if
->core_global_regs
->glpmcfg
, lpmcfg
.d32
);
6987 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t
* core_if
)
6989 glpmcfg_data_t lpmcfg
;
6990 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6991 return lpmcfg
.b
.hsic_connect
;
6994 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t
* core_if
, uint32_t val
)
6996 glpmcfg_data_t lpmcfg
;
6997 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
6998 lpmcfg
.b
.hsic_connect
= val
;
6999 DWC_WRITE_REG32(&core_if
->core_global_regs
->glpmcfg
, lpmcfg
.d32
);
7002 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t
* core_if
)
7004 glpmcfg_data_t lpmcfg
;
7005 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
7006 return lpmcfg
.b
.inv_sel_hsic
;
7010 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7012 glpmcfg_data_t lpmcfg
;
7013 lpmcfg
.d32
= DWC_READ_REG32(&core_if
->core_global_regs
->glpmcfg
);
7014 lpmcfg
.b
.inv_sel_hsic
= val
;
7015 DWC_WRITE_REG32(&core_if
->core_global_regs
->glpmcfg
, lpmcfg
.d32
);
7018 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t
* core_if
)
7020 return DWC_READ_REG32(&core_if
->core_global_regs
->gotgctl
);
7023 void dwc_otg_set_gotgctl(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7025 DWC_WRITE_REG32(&core_if
->core_global_regs
->gotgctl
, val
);
7028 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t
* core_if
)
7030 return DWC_READ_REG32(&core_if
->core_global_regs
->gusbcfg
);
7033 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7035 DWC_WRITE_REG32(&core_if
->core_global_regs
->gusbcfg
, val
);
7038 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t
* core_if
)
7040 return DWC_READ_REG32(&core_if
->core_global_regs
->grxfsiz
);
7043 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7045 DWC_WRITE_REG32(&core_if
->core_global_regs
->grxfsiz
, val
);
7048 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t
* core_if
)
7050 return DWC_READ_REG32(&core_if
->core_global_regs
->gnptxfsiz
);
7053 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7055 DWC_WRITE_REG32(&core_if
->core_global_regs
->gnptxfsiz
, val
);
7058 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t
* core_if
)
7060 return DWC_READ_REG32(&core_if
->core_global_regs
->gpvndctl
);
7063 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7065 DWC_WRITE_REG32(&core_if
->core_global_regs
->gpvndctl
, val
);
7068 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t
* core_if
)
7070 return DWC_READ_REG32(&core_if
->core_global_regs
->ggpio
);
7073 void dwc_otg_set_ggpio(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7075 DWC_WRITE_REG32(&core_if
->core_global_regs
->ggpio
, val
);
7078 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t
* core_if
)
7080 return DWC_READ_REG32(core_if
->host_if
->hprt0
);
7084 void dwc_otg_set_hprt0(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7086 DWC_WRITE_REG32(core_if
->host_if
->hprt0
, val
);
7089 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t
* core_if
)
7091 return DWC_READ_REG32(&core_if
->core_global_regs
->guid
);
7094 void dwc_otg_set_guid(dwc_otg_core_if_t
* core_if
, uint32_t val
)
7096 DWC_WRITE_REG32(&core_if
->core_global_regs
->guid
, val
);
7099 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t
* core_if
)
7101 return DWC_READ_REG32(&core_if
->core_global_regs
->hptxfsiz
);
7104 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t
* core_if
)
7106 return ((core_if
->otg_ver
== 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7110 * Start the SRP timer to detect when the SRP does not complete within
7113 * @param core_if the pointer to core_if strucure.
7115 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t
* core_if
)
7117 core_if
->srp_timer_started
= 1;
7118 DWC_TIMER_SCHEDULE(core_if
->srp_timer
, 6000 /* 6 secs */ );
7121 void dwc_otg_initiate_srp(dwc_otg_core_if_t
* core_if
)
7123 uint32_t *addr
= (uint32_t *) & (core_if
->core_global_regs
->gotgctl
);
7127 val
.d32
= DWC_READ_REG32(addr
);
7129 DWC_ERROR("Session Request Already active!\n");
7133 DWC_INFO("Session Request Initated\n"); //NOTICE
7134 mem
.d32
= DWC_READ_REG32(addr
);
7136 DWC_WRITE_REG32(addr
, mem
.d32
);
7138 /* Start the SRP timer */
7139 dwc_otg_pcd_start_srp_timer(core_if
);