]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blob - drivers/usb/host/dwc_otg/dwc_otg_cil.c
Add dwc_otg driver
[mirror_ubuntu-artful-kernel.git] / drivers / usb / host / dwc_otg / dwc_otg_cil.c
1 /* ==========================================================================
2 * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
3 * $Revision: #191 $
4 * $Date: 2012/08/10 $
5 * $Change: 2047372 $
6 *
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.
10 *
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.
20 *
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
31 * DAMAGE.
32 * ========================================================================== */
33
34 /** @file
35 *
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.
39 *
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
50 * hardware.
51 *
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
56 * or macros.
57 *
58 */
59
60 #include "dwc_os.h"
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
63
64 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
65
66 /**
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
73 * configured.
74 *
75 * @param reg_base_addr Base address of DWC_otg core registers
76 *
77 */
78 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
79 {
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;
84 int i = 0;
85
86 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
87
88 core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
89
90 if (core_if == NULL) {
91 DWC_DEBUGPL(DBG_CIL,
92 "Allocation of dwc_otg_core_if_t failed\n");
93 return 0;
94 }
95 core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
96
97 /*
98 * Allocate the Device Mode structures.
99 */
100 dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
101
102 if (dev_if == NULL) {
103 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
104 DWC_FREE(core_if);
105 return 0;
106 }
107
108 dev_if->dev_global_regs =
109 (dwc_otg_device_global_regs_t *) (reg_base +
110 DWC_DEV_GLOBAL_REG_OFFSET);
111
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));
116
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);
124 }
125
126 dev_if->speed = 0; // unknown
127
128 core_if->dev_if = dev_if;
129
130 /*
131 * Allocate the Host Mode structures.
132 */
133 host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
134
135 if (host_if == NULL) {
136 DWC_DEBUGPL(DBG_CIL,
137 "Allocation of dwc_otg_host_if_t failed\n");
138 DWC_FREE(dev_if);
139 DWC_FREE(core_if);
140 return 0;
141 }
142
143 host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
144 (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
145
146 host_if->hprt0 =
147 (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
148
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);
155 }
156
157 host_if->num_host_channels = MAX_EPS_CHANNELS;
158 core_if->host_if = host_if;
159
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]);
166 }
167
168 core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
169
170 /* Initiate lx_state to L3 disconnected state */
171 core_if->lx_state = DWC_OTG_L3;
172 /*
173 * Store the contents of the hardware configuration registers here for
174 * easy access later.
175 */
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);
184
185 /* Force host mode to get HPTXFSIZ exact power on value */
186 {
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);
191 dwc_mdelay(100);
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);
197 dwc_mdelay(100);
198 }
199
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);
204
205 core_if->hcfg.d32 =
206 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
207 core_if->dcfg.d32 =
208 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
209
210 DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
211 DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
212
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);
224
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);
229
230 /*
231 * Set the SRP sucess bit for FS-I2c
232 */
233 core_if->srp_success = 0;
234 core_if->srp_timer_started = 0;
235
236 /*
237 * Create new workqueue and init works
238 */
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");
242 DWC_FREE(host_if);
243 DWC_FREE(dev_if);
244 DWC_FREE(core_if);
245 return 0;
246 }
247
248 core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
249
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));
254
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");
259 DWC_FREE(host_if);
260 DWC_FREE(dev_if);
261 DWC_WORKQ_FREE(core_if->wq_otg);
262 DWC_FREE(core_if);
263 return 0;
264 }
265
266 if (dwc_otg_setup_params(core_if)) {
267 DWC_WARN("Error while setting core params\n");
268 }
269
270 core_if->hibernation_suspend = 0;
271
272 /** ADP initialization */
273 dwc_otg_adp_init(core_if);
274
275 return core_if;
276 }
277
278 /**
279 * This function frees the structures allocated by dwc_otg_cil_init().
280 *
281 * @param core_if The core interface pointer returned from
282 * dwc_otg_cil_init().
283 *
284 */
285 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
286 {
287 dctl_data_t dctl = {.d32 = 0 };
288 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
289
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);
293
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,
297 dctl.d32);
298 }
299
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);
303 }
304 if (core_if->dev_if) {
305 DWC_FREE(core_if->dev_if);
306 }
307 if (core_if->host_if) {
308 DWC_FREE(core_if->host_if);
309 }
310
311 /** Remove ADP Stuff */
312 dwc_otg_adp_remove(core_if);
313 if (core_if->core_params) {
314 DWC_FREE(core_if->core_params);
315 }
316 if (core_if->wkp_timer) {
317 DWC_TIMER_FREE(core_if->wkp_timer);
318 }
319 if (core_if->srp_timer) {
320 DWC_TIMER_FREE(core_if->srp_timer);
321 }
322 DWC_FREE(core_if);
323 }
324
325 /**
326 * This function enables the controller's Global Interrupt in the AHB Config
327 * register.
328 *
329 * @param core_if Programming view of DWC_otg controller.
330 */
331 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
332 {
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);
336 }
337
338 /**
339 * This function disables the controller's Global Interrupt in the AHB Config
340 * register.
341 *
342 * @param core_if Programming view of DWC_otg controller.
343 */
344 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
345 {
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);
349 }
350
351 /**
352 * This function initializes the commmon interrupts, used in both
353 * device and host modes.
354 *
355 * @param core_if Programming view of the DWC_otg controller
356 *
357 */
358 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
359 {
360 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
361 gintmsk_data_t intr_mask = {.d32 = 0 };
362
363 /* Clear any pending OTG Interrupts */
364 DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
365
366 /* Clear any pending interrupts */
367 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
368
369 /*
370 * Enable the interrupts in the GINTMSK.
371 */
372 intr_mask.b.modemismatch = 1;
373 intr_mask.b.otgintr = 1;
374
375 if (!core_if->dma_enable) {
376 intr_mask.b.rxstsqlvl = 1;
377 }
378
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;
387 }
388 #endif
389 DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
390 }
391
392 /*
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.
399 */
400 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
401 int rem_wakeup, int reset)
402 {
403 gpwrdn_data_t gpwrdn = {.d32 = 0 };
404 pcgcctl_data_t pcgcctl = {.d32 = 0 };
405 dctl_data_t dctl = {.d32 = 0 };
406
407 int timeout = 2000;
408
409 if (!core_if->hibernation_suspend) {
410 DWC_PRINTF("Already exited from Hibernation\n");
411 return 1;
412 }
413
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);
418 dwc_udelay(10);
419
420 /* Reset core */
421 gpwrdn.d32 = 0;
422 gpwrdn.b.pwrdnrstn = 1;
423 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
424 dwc_udelay(10);
425
426 /* Assert Restore signal */
427 gpwrdn.d32 = 0;
428 gpwrdn.b.restore = 1;
429 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
430 dwc_udelay(10);
431
432 /* Disable power clamps */
433 gpwrdn.d32 = 0;
434 gpwrdn.b.pwrdnclmp = 1;
435 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
436
437 if (rem_wakeup) {
438 dwc_udelay(70);
439 }
440
441 /* Deassert Reset core */
442 gpwrdn.d32 = 0;
443 gpwrdn.b.pwrdnrstn = 1;
444 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
445 dwc_udelay(10);
446
447 /* Disable PMU interrupt */
448 gpwrdn.d32 = 0;
449 gpwrdn.b.pmuintsel = 1;
450 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
451
452 /* Mask interrupts from gpwrdn */
453 gpwrdn.d32 = 0;
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);
460
461 /* Indicates that we are going out from hibernation */
462 core_if->hibernation_suspend = 0;
463
464 /*
465 * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
466 * indicates restore from remote_wakeup
467 */
468 restore_essential_regs(core_if, rem_wakeup, 0);
469
470 /*
471 * Wait a little for seeing new value of variable hibernation_suspend if
472 * Restore done interrupt received before polling
473 */
474 dwc_udelay(10);
475
476 if (core_if->hibernation_suspend == 0) {
477 /*
478 * Wait For Restore_done Interrupt. This mechanism of polling the
479 * interrupt is introduced to avoid any possible race conditions
480 */
481 do {
482 gintsts_data_t gintsts;
483 gintsts.d32 =
484 DWC_READ_REG32(&core_if->core_global_regs->gintsts);
485 if (gintsts.b.restoredone) {
486 gintsts.d32 = 0;
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");
491 break;
492 }
493 dwc_udelay(10);
494 } while (--timeout);
495 if (!timeout) {
496 DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
497 }
498 }
499 /* Clear all pending interupts */
500 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
501
502 /* De-assert Restore */
503 gpwrdn.d32 = 0;
504 gpwrdn.b.restore = 1;
505 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
506 dwc_udelay(10);
507
508 if (!rem_wakeup) {
509 pcgcctl.d32 = 0;
510 pcgcctl.b.rstpdwnmodule = 1;
511 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
512 }
513
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);
519
520 /* De-assert Wakeup Logic */
521 gpwrdn.d32 = 0;
522 gpwrdn.b.pmuactv = 1;
523 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
524 dwc_udelay(10);
525
526 if (!rem_wakeup) {
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);
530 } else {
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);
535 }
536
537 dwc_mdelay(2);
538 /* Clear all pending interupts */
539 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
540
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);
545
546 if (rem_wakeup) {
547 dwc_mdelay(7);
548 dctl.d32 = 0;
549 dctl.b.rmtwkupsig = 1;
550 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
551 }
552
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");
557
558 return 1;
559 }
560
561 /*
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.
568 */
569 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
570 int rem_wakeup, int reset)
571 {
572 gpwrdn_data_t gpwrdn = {.d32 = 0 };
573 hprt0_data_t hprt0 = {.d32 = 0 };
574
575 int timeout = 2000;
576
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);
581 dwc_udelay(10);
582
583 /* Reset core */
584 gpwrdn.d32 = 0;
585 gpwrdn.b.pwrdnrstn = 1;
586 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
587 dwc_udelay(10);
588
589 /* Assert Restore signal */
590 gpwrdn.d32 = 0;
591 gpwrdn.b.restore = 1;
592 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
593 dwc_udelay(10);
594
595 /* Disable power clamps */
596 gpwrdn.d32 = 0;
597 gpwrdn.b.pwrdnclmp = 1;
598 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
599
600 if (!rem_wakeup) {
601 dwc_udelay(50);
602 }
603
604 /* Deassert Reset core */
605 gpwrdn.d32 = 0;
606 gpwrdn.b.pwrdnrstn = 1;
607 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
608 dwc_udelay(10);
609
610 /* Disable PMU interrupt */
611 gpwrdn.d32 = 0;
612 gpwrdn.b.pmuintsel = 1;
613 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
614
615 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);
622
623 /* Indicates that we are going out from hibernation */
624 core_if->hibernation_suspend = 0;
625
626 /* Set Restore Essential Regs bit in PCGCCTL register */
627 restore_essential_regs(core_if, rem_wakeup, 1);
628
629 /* Wait a little for seeing new value of variable hibernation_suspend if
630 * Restore done interrupt received before polling */
631 dwc_udelay(10);
632
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
636 */
637 do {
638 gintsts_data_t gintsts;
639 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
640 if (gintsts.b.restoredone) {
641 gintsts.d32 = 0;
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");
645 break;
646 }
647 dwc_udelay(10);
648 } while (--timeout);
649 if (!timeout) {
650 DWC_WARN("Restore Done interrupt wasn't generated\n");
651 }
652 }
653
654 /* Set the flag's value to 0 again after receiving restore done interrupt */
655 core_if->hibernation_suspend = 0;
656
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) */
660 dwc_mdelay(100);
661
662 /* Clear all pending interrupts */
663 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
664
665 /* De-assert Restore */
666 gpwrdn.d32 = 0;
667 gpwrdn.b.restore = 1;
668 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
669 dwc_udelay(10);
670
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);
676
677 /* De-assert Wakeup Logic */
678 gpwrdn.d32 = 0;
679 gpwrdn.b.pmuactv = 1;
680 DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
681 dwc_udelay(10);
682
683 /* Start the Resume operation by programming HPRT0 */
684 hprt0.d32 = core_if->hr_backup->hprt0_local;
685 hprt0.b.prtpwr = 1;
686 hprt0.b.prtena = 0;
687 hprt0.b.prtsusp = 0;
688 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
689
690 DWC_PRINTF("Resume Starts Now\n");
691 if (!reset) { // Indicates it is Resume Operation
692 hprt0.d32 = core_if->hr_backup->hprt0_local;
693 hprt0.b.prtres = 1;
694 hprt0.b.prtpwr = 1;
695 hprt0.b.prtena = 0;
696 hprt0.b.prtsusp = 0;
697 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
698
699 if (!rem_wakeup)
700 hprt0.b.prtres = 0;
701 /* Wait for Resume time and then program HPRT again */
702 dwc_mdelay(100);
703 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
704
705 } else { // Indicates it is Reset Operation
706 hprt0.d32 = core_if->hr_backup->hprt0_local;
707 hprt0.b.prtrst = 1;
708 hprt0.b.prtpwr = 1;
709 hprt0.b.prtena = 0;
710 hprt0.b.prtsusp = 0;
711 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
712 /* Wait for Reset time and then program HPRT again */
713 dwc_mdelay(60);
714 hprt0.b.prtrst = 0;
715 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
716 }
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);
722
723 /* Clear all pending interupts */
724 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
725
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);
730
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");
734 return 0;
735 }
736
737 /** Saves some register values into system memory. */
738 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
739 {
740 struct dwc_otg_global_regs_backup *gr;
741 int i;
742
743 gr = core_if->gr_backup;
744 if (!gr) {
745 gr = DWC_ALLOC(sizeof(*gr));
746 if (!gr) {
747 return -DWC_E_NO_MEMORY;
748 }
749 core_if->gr_backup = gr;
750 }
751
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);
761 #endif
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]));
769 }
770
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",
780 gr->hptxfsiz_local);
781 #ifdef CONFIG_USB_DWC_OTG_LPM
782 DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg = %08x\n", gr->glpmcfg_local);
783 #endif
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);
787
788 return 0;
789 }
790
791 /** Saves GINTMSK register before setting the msk bits. */
792 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
793 {
794 struct dwc_otg_global_regs_backup *gr;
795
796 gr = core_if->gr_backup;
797 if (!gr) {
798 gr = DWC_ALLOC(sizeof(*gr));
799 if (!gr) {
800 return -DWC_E_NO_MEMORY;
801 }
802 core_if->gr_backup = gr;
803 }
804
805 gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
806
807 DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
808 DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk = %08x\n", gr->gintmsk_local);
809
810 return 0;
811 }
812
813 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
814 {
815 struct dwc_otg_dev_regs_backup *dr;
816 int i;
817
818 dr = core_if->dr_backup;
819 if (!dr) {
820 dr = DWC_ALLOC(sizeof(*dr));
821 if (!dr) {
822 return -DWC_E_NO_MEMORY;
823 }
824 core_if->dr_backup = dr;
825 }
826
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);
829 dr->daintmsk =
830 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
831 dr->diepmsk =
832 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
833 dr->doepmsk =
834 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
835
836 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
837 dr->diepctl[i] =
838 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
839 dr->dieptsiz[i] =
840 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
841 dr->diepdma[i] =
842 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
843 }
844
845 DWC_DEBUGPL(DBG_ANY,
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",
850 dr->daintmsk);
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,
855 dr->diepctl[i]);
856 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d] = %08x\n",
857 i, dr->dieptsiz[i]);
858 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d] = %08x\n", i,
859 dr->diepdma[i]);
860 }
861
862 return 0;
863 }
864
865 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
866 {
867 struct dwc_otg_host_regs_backup *hr;
868 int i;
869
870 hr = core_if->hr_backup;
871 if (!hr) {
872 hr = DWC_ALLOC(sizeof(*hr));
873 if (!hr) {
874 return -DWC_E_NO_MEMORY;
875 }
876 core_if->hr_backup = hr;
877 }
878
879 hr->hcfg_local =
880 DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
881 hr->haintmsk_local =
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);
886 }
887 hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
888 hr->hfir_local =
889 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
890
891 DWC_DEBUGPL(DBG_ANY,
892 "=============Backing Host registers===============\n");
893 DWC_DEBUGPL(DBG_ANY, "Backed up hcfg = %08x\n",
894 hr->hcfg_local);
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]);
899 }
900 DWC_DEBUGPL(DBG_ANY, "Backed up hprt0 = %08x\n",
901 hr->hprt0_local);
902 DWC_DEBUGPL(DBG_ANY, "Backed up hfir = %08x\n",
903 hr->hfir_local);
904
905 return 0;
906 }
907
908 int dwc_otg_restore_global_regs(dwc_otg_core_if_t *core_if)
909 {
910 struct dwc_otg_global_regs_backup *gr;
911 int i;
912
913 gr = core_if->gr_backup;
914 if (!gr) {
915 return -DWC_E_INVALID;
916 }
917
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,
926 gr->hptxfsiz_local);
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]);
932 }
933
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));
938 return 0;
939 }
940
941 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
942 {
943 struct dwc_otg_dev_regs_backup *dr;
944 int i;
945
946 dr = core_if->dr_backup;
947
948 if (!dr) {
949 return -DWC_E_INVALID;
950 }
951
952 if (!rem_wakeup) {
953 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
954 dr->dctl);
955 }
956
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);
960
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]);
965 }
966
967 return 0;
968 }
969
970 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
971 {
972 struct dwc_otg_host_regs_backup *hr;
973 int i;
974 hr = core_if->hr_backup;
975
976 if (!hr) {
977 return -DWC_E_INVALID;
978 }
979
980 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
981 //if (!reset)
982 //{
983 // DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
984 //}
985
986 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
987 hr->haintmsk_local);
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]);
991 }
992
993 return 0;
994 }
995
996 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
997 {
998 struct dwc_otg_global_regs_backup *gr;
999
1000 gr = core_if->gr_backup;
1001
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);
1005 #endif
1006 DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
1007
1008 return 0;
1009 }
1010
1011 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
1012 {
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 };
1018
1019 /* Restore LPM and I2C registers */
1020 restore_lpm_i2c_regs(core_if);
1021
1022 /* Set PCGCCTL to 0 */
1023 DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
1024
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));
1029
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);
1034
1035 /* Clear all pending interupts */
1036 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
1037
1038 /* Unmask restore done interrupt */
1039 gintmsk.b.restoredone = 1;
1040 DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1041
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);
1045
1046 if (is_host) {
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,
1050 hcfg.d32);
1051
1052 /* Load restore values for [31:14] bits */
1053 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1054 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1055
1056 if (rmode)
1057 pcgcctl.b.restoremode = 1;
1058 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1059 dwc_udelay(10);
1060
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;
1065 if (rmode)
1066 pcgcctl.b.restoremode = 1;
1067 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1068 } else {
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);
1072
1073 /* Load restore values for [31:14] bits */
1074 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1075 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1076 if (!rmode) {
1077 pcgcctl.d32 |= 0x208;
1078 }
1079 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1080 dwc_udelay(10);
1081
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;
1086 if (!rmode)
1087 pcgcctl.d32 |= 0x208;
1088 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1089 }
1090
1091 return 0;
1092 }
1093
1094 /**
1095 * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1096 * type.
1097 */
1098 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
1099 {
1100 uint32_t val;
1101 hcfg_data_t hcfg;
1102
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;
1109 } else {
1110 /* High speed PHY running at full speed or high speed */
1111 val = DWC_HCFG_30_60_MHZ;
1112 }
1113
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);
1118 }
1119
1120 /**
1121 * Initializes the DevSpd field of the DCFG register depending on the PHY type
1122 * and the enumeration speed of the device.
1123 */
1124 static void init_devspd(dwc_otg_core_if_t * core_if)
1125 {
1126 uint32_t val;
1127 dcfg_data_t dcfg;
1128
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 */
1134 val = 0x3;
1135 } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1136 /* High speed PHY running at full speed */
1137 val = 0x1;
1138 } else {
1139 /* High speed PHY running at high speed */
1140 val = 0x0;
1141 }
1142
1143 DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1144
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);
1148 }
1149
1150 /**
1151 * This function calculates the number of IN EPS
1152 * using GHWCFG1 and GHWCFG2 registers values
1153 *
1154 * @param core_if Programming view of the DWC_otg controller
1155 */
1156 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
1157 {
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;
1162 int i;
1163
1164 for (i = 0; i < num_eps; ++i) {
1165 if (!(hwcfg1 & 0x1))
1166 num_in_eps++;
1167
1168 hwcfg1 >>= 2;
1169 }
1170
1171 if (core_if->hwcfg4.b.ded_fifo_en) {
1172 num_in_eps =
1173 (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1174 }
1175
1176 return num_in_eps;
1177 }
1178
1179 /**
1180 * This function calculates the number of OUT EPS
1181 * using GHWCFG1 and GHWCFG2 registers values
1182 *
1183 * @param core_if Programming view of the DWC_otg controller
1184 */
1185 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
1186 {
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;
1190 int i;
1191
1192 for (i = 0; i < num_eps; ++i) {
1193 if (!(hwcfg1 & 0x1))
1194 num_out_eps++;
1195
1196 hwcfg1 >>= 2;
1197 }
1198 return num_out_eps;
1199 }
1200
1201 /**
1202 * This function initializes the DWC_otg controller registers and
1203 * prepares the core for device mode or host mode operation.
1204 *
1205 * @param core_if Programming view of the DWC_otg controller
1206 *
1207 */
1208 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
1209 {
1210 int i = 0;
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 };
1216
1217 DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p) regs at %p\n",
1218 core_if, global_regs);
1219
1220 /* Common Initialization */
1221 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1222
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;
1227
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);
1232
1233 /* Reset the Controller */
1234 dwc_otg_core_reset(core_if);
1235
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;
1239
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);
1243
1244 DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1245 core_if->hwcfg4.b.num_dev_perio_in_ep);
1246
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]);
1252 }
1253
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]);
1259 }
1260
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;
1265
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);
1270
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 */
1276
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);
1285
1286 /* Reset after a PHY select */
1287 dwc_otg_core_reset(core_if);
1288 }
1289
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
1292 * host_init). */
1293 if (dwc_otg_is_host_mode(core_if)) {
1294 init_fslspclksel(core_if);
1295 } else {
1296 init_devspd(core_if);
1297 }
1298
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);
1305
1306 /* Program GI2CCTL.I2CEn */
1307 i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1308 i2cctl.b.i2cdevaddr = 1;
1309 i2cctl.b.i2cen = 0;
1310 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1311 i2cctl.b.i2cen = 1;
1312 DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1313 }
1314
1315 } /* endif speed == DWC_SPEED_PARAM_FULL */
1316 else {
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. */
1323
1324 if (core_if->core_params->phy_type == 2) {
1325 /* ULPI interface */
1326 usbcfg.b.ulpi_utmi_sel = 1;
1327 usbcfg.b.phyif = 0;
1328 usbcfg.b.ddrsel =
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) {
1334 usbcfg.b.phyif = 1;
1335
1336 } else {
1337 usbcfg.b.phyif = 0;
1338 }
1339 } else {
1340 DWC_ERROR("FS PHY TYPE\n");
1341 }
1342 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1343 /* Reset after setting the PHY parameters */
1344 dwc_otg_core_reset(core_if);
1345 }
1346 }
1347
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);
1356 } else {
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);
1361 }
1362
1363 /* Program the GAHBCFG Register. */
1364 switch (core_if->hwcfg2.b.architecture) {
1365
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;
1373 break;
1374
1375 case DWC_EXT_DMA_ARCH:
1376 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1377 {
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++;
1382 brst_sz >>= 1;
1383 }
1384 }
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);
1388 break;
1389
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);
1399 break;
1400
1401 }
1402 if (core_if->dma_enable) {
1403 if (core_if->dma_desc_enable) {
1404 DWC_PRINTF("Using Descriptor DMA mode\n");
1405 } else {
1406 DWC_PRINTF("Using Buffer DMA mode\n");
1407
1408 }
1409 } else {
1410 DWC_PRINTF("Using Slave mode\n");
1411 core_if->dma_desc_enable = 0;
1412 }
1413
1414 if (core_if->core_params->ahb_single) {
1415 ahbcfg.b.ahbsingle = 1;
1416 }
1417
1418 ahbcfg.b.dmaenable = core_if->dma_enable;
1419 DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1420
1421 core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1422
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"));
1429
1430 /*
1431 * Program the GUSBCFG register.
1432 */
1433 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1434
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);
1441 break;
1442
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);
1447 break;
1448
1449 case DWC_MODE_NO_HNP_SRP_CAPABLE:
1450 usbcfg.b.hnpcap = 0;
1451 usbcfg.b.srpcap = 0;
1452 break;
1453
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);
1458 break;
1459
1460 case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1461 usbcfg.b.hnpcap = 0;
1462 usbcfg.b.srpcap = 0;
1463 break;
1464
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);
1469 break;
1470
1471 case DWC_MODE_NO_SRP_CAPABLE_HOST:
1472 usbcfg.b.hnpcap = 0;
1473 usbcfg.b.srpcap = 0;
1474 break;
1475 }
1476
1477 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1478
1479 #ifdef CONFIG_USB_DWC_OTG_LPM
1480 if (core_if->core_params->lpm_enable) {
1481 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1482
1483 /* To enable LPM support set lpm_cap_en bit */
1484 lpmcfg.b.lpm_cap_en = 1;
1485
1486 /* Make AppL1Res ACK */
1487 lpmcfg.b.appl_resp = 1;
1488
1489 /* Retry 3 times */
1490 lpmcfg.b.retry_count = 3;
1491
1492 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1493 0, lpmcfg.d32);
1494
1495 }
1496 #endif
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,
1501 0, gusbcfg.d32);
1502 }
1503 {
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,
1507 gotgctl.d32);
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);
1512 }
1513
1514
1515 /* Enable common interrupts */
1516 dwc_otg_enable_common_interrupts(core_if);
1517
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;
1523 } else {
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);
1528 #endif
1529 }
1530 }
1531
1532 /**
1533 * This function enables the Device mode interrupts.
1534 *
1535 * @param core_if Programming view of DWC_otg controller
1536 */
1537 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
1538 {
1539 gintmsk_data_t intr_mask = {.d32 = 0 };
1540 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1541
1542 DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1543
1544 /* Disable all interrupts. */
1545 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
1546
1547 /* Clear any pending interrupts */
1548 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
1549
1550 /* Enable the common interrupts */
1551 dwc_otg_enable_common_interrupts(core_if);
1552
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;
1558
1559 if (!core_if->multiproc_int_enable) {
1560 intr_mask.b.inepintr = 1;
1561 intr_mask.b.outepintr = 1;
1562 }
1563
1564 intr_mask.b.erlysuspend = 1;
1565
1566 if (core_if->en_multiple_tx_fifo == 0) {
1567 intr_mask.b.epmismatch = 1;
1568 }
1569
1570 //intr_mask.b.incomplisoout = 1;
1571 intr_mask.b.incomplisoin = 1;
1572
1573 /* Enable the ignore frame number for ISOC xfers - MAS */
1574 /* Disable to support high bandwith ISOC transfers - manukz */
1575 #if 0
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));
1586 }
1587 }
1588 #endif
1589 #endif
1590 #ifdef DWC_EN_ISOC
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 };
1595 dctl.b.ifrmnum = 1;
1596 DWC_MODIFY_REG32(&core_if->
1597 dev_if->dev_global_regs->dctl,
1598 0, dctl.d32);
1599 } else {
1600 intr_mask.b.incomplisoin = 1;
1601 intr_mask.b.incomplisoout = 1;
1602 }
1603 }
1604 } else {
1605 intr_mask.b.incomplisoin = 1;
1606 intr_mask.b.incomplisoout = 1;
1607 }
1608 #endif /* DWC_EN_ISOC */
1609
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;
1616 #endif
1617
1618 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1619
1620 DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1621 DWC_READ_REG32(&global_regs->gintmsk));
1622 }
1623
1624 /**
1625 * This function initializes the DWC_otg controller registers for
1626 * device mode.
1627 *
1628 * @param core_if Programming view of DWC_otg controller
1629 *
1630 */
1631 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
1632 {
1633 int i;
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 };
1648
1649 /* Restart the Phy Clock */
1650 DWC_WRITE_REG32(core_if->pcgcctl, 0);
1651
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;
1660 }
1661
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);
1666 }
1667
1668
1669 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1670
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);
1679
1680 /* Rx FIFO */
1681 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1682 DWC_READ_REG32(&global_regs->grxfsiz));
1683
1684 #ifdef DWC_UTE_CFI
1685 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
1686 core_if->init_rxfsiz = params->dev_rx_fifo_size;
1687 #endif
1688 rx_fifo_size = params->dev_rx_fifo_size;
1689 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
1690
1691 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1692 DWC_READ_REG32(&global_regs->grxfsiz));
1693
1694 /** Set Periodic Tx FIFO Mask all bits 0 */
1695 core_if->p_tx_msk = 0;
1696
1697 /** Set Tx FIFO Mask all bits 0 */
1698 core_if->tx_msk = 0;
1699
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));
1704
1705 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1706 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1707
1708 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1709 nptxfifosize.d32);
1710
1711 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1712 DWC_READ_REG32(&global_regs->gnptxfsiz));
1713
1714 /**@todo NGS: Fix Periodic FIFO Sizing! */
1715 /*
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.
1720 */
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
1730 [i]));
1731 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1732 ptxfifosize.d32);
1733 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
1734 i,
1735 DWC_READ_REG32(&global_regs->dtxfsiz
1736 [i]));
1737 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
1738 }
1739 } else {
1740 /*
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.
1745 */
1746
1747 /* Non-periodic Tx FIFO */
1748 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1749 DWC_READ_REG32(&global_regs->gnptxfsiz));
1750
1751 #ifdef DWC_UTE_CFI
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;
1756 #endif
1757 nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1758 nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1759
1760 DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1761 nptxfifosize.d32);
1762
1763 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1764 DWC_READ_REG32(&global_regs->gnptxfsiz));
1765
1766 txfifosize.b.startaddr =
1767 nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1768
1769 for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1770
1771 txfifosize.b.depth =
1772 params->dev_tx_fifo_size[i];
1773
1774 DWC_DEBUGPL(DBG_CIL,
1775 "initial dtxfsiz[%d]=%08x\n",
1776 i,
1777 DWC_READ_REG32(&global_regs->dtxfsiz
1778 [i]));
1779
1780 #ifdef DWC_UTE_CFI
1781 core_if->pwron_txfsiz[i] =
1782 (DWC_READ_REG32
1783 (&global_regs->dtxfsiz[i]) >> 16);
1784 core_if->init_txfsiz[i] =
1785 params->dev_tx_fifo_size[i];
1786 #endif
1787 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1788 txfifosize.d32);
1789
1790 DWC_DEBUGPL(DBG_CIL,
1791 "new dtxfsiz[%d]=%08x\n",
1792 i,
1793 DWC_READ_REG32(&global_regs->dtxfsiz
1794 [i]));
1795
1796 txfifosize.b.startaddr += txfifosize.b.depth;
1797 }
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);
1808 }
1809 }
1810
1811 /* Flush the FIFOs */
1812 dwc_otg_flush_tx_fifo(core_if, 0x10); /* all Tx FIFOs */
1813 dwc_otg_flush_rx_fifo(core_if);
1814
1815 /* Flush the Learning Queue. */
1816 resetctl.b.intknqflsh = 1;
1817 DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
1818
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
1823 }
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);
1829
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);
1832 dcfg.b.epmscnt = 2;
1833 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1834
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]);
1839 }
1840 DWC_DEBUGPL(DBG_CILV,"\n");
1841 }
1842
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?
1846 */
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);
1851 }
1852 }
1853
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);
1857 }
1858
1859 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1860 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
1861 } else {
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);
1866 }
1867
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) {
1872 depctl.d32 = 0;
1873 depctl.b.epdis = 1;
1874 depctl.b.snak = 1;
1875 } else {
1876 depctl.d32 = 0;
1877 }
1878
1879 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1880
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);
1884 }
1885
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);
1895 do {
1896 dwc_udelay(10);
1897 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
1898 } while (!gintsts.b.goutnakeff);
1899 gintsts.d32 = 0;
1900 gintsts.b.goutnakeff = 1;
1901 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1902
1903 depctl.d32 = 0;
1904 depctl.b.epdis = 1;
1905 depctl.b.snak = 1;
1906 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1907 do {
1908 dwc_udelay(10);
1909 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
1910 out_ep_regs[i]->doepint);
1911 } while (!doepint.b.epdisabled);
1912
1913 doepint.b.epdisabled = 1;
1914 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32);
1915
1916 dctl.d32 = 0;
1917 dctl.b.cgoutnak = 1;
1918 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1919 } else {
1920 depctl.d32 = 0;
1921 }
1922
1923 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1924
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);
1928 }
1929
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;
1934
1935 dev_if->rx_thr_length = params->rx_thr_length;
1936 dev_if->tx_thr_length = params->tx_thr_length;
1937
1938 dev_if->setup_desc_index = 0;
1939
1940 dthrctl.d32 = 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;
1947
1948 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1949 dthrctl.d32);
1950
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);
1956
1957 }
1958
1959 dwc_otg_enable_device_interrupts(core_if);
1960
1961 {
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);
1967 } else {
1968 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
1969 msk.d32, msk.d32);
1970 }
1971 }
1972
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);
1978 }
1979
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);
1985 }
1986 }
1987
1988 /**
1989 * This function enables the Host mode interrupts.
1990 *
1991 * @param core_if Programming view of DWC_otg controller
1992 */
1993 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
1994 {
1995 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1996 gintmsk_data_t intr_mask = {.d32 = 0 };
1997
1998 DWC_DEBUGPL(DBG_CIL, "%s(%p)\n", __func__, core_if);
1999
2000 /* Disable all interrupts. */
2001 DWC_WRITE_REG32(&global_regs->gintmsk, 0);
2002
2003 /* Clear any pending interrupts. */
2004 DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
2005
2006 /* Enable the common interrupts */
2007 dwc_otg_enable_common_interrupts(core_if);
2008
2009 /*
2010 * Enable host mode interrupts without disturbing common
2011 * interrupts.
2012 */
2013
2014 intr_mask.b.disconnect = 1;
2015 intr_mask.b.portintr = 1;
2016 intr_mask.b.hcintr = 1;
2017
2018 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2019 }
2020
2021 /**
2022 * This function disables the Host Mode interrupts.
2023 *
2024 * @param core_if Programming view of DWC_otg controller
2025 */
2026 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
2027 {
2028 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2029 gintmsk_data_t intr_mask = {.d32 = 0 };
2030
2031 DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2032
2033 /*
2034 * Disable host mode interrupts without disturbing common
2035 * interrupts.
2036 */
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;
2042
2043 DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
2044 }
2045
2046 /**
2047 * This function initializes the DWC_otg controller registers for
2048 * host mode.
2049 *
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.
2053 *
2054 * @param core_if Programming view of DWC_otg controller
2055 *
2056 */
2057 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
2058 {
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 };
2067 int i;
2068 hcchar_data_t hcchar;
2069 hcfg_data_t hcfg;
2070 hfir_data_t hfir;
2071 dwc_otg_hc_regs_t *hc_regs;
2072 int num_channels;
2073 gotgctl_data_t gotgctl = {.d32 = 0 };
2074
2075 DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
2076
2077 /* Restart the Phy Clock */
2078 DWC_WRITE_REG32(core_if->pcgcctl, 0);
2079
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);
2086
2087 }
2088
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
2092 * during runtime.*/
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);
2097 }
2098
2099 if (core_if->core_params->dma_desc_enable) {
2100 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
2101 if (!
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)
2106 || (op_mode ==
2107 DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
2108 || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
2109 || (op_mode ==
2110 DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
2111
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");
2117 return;
2118 }
2119 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2120 hcfg.b.descdma = 1;
2121 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2122 }
2123
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);
2134
2135 /* Rx FIFO */
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));
2142
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));
2151
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));
2161
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);
2171 }
2172 }
2173
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);
2181
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);
2185
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;
2189
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);
2193 hcchar.b.chen = 0;
2194 hcchar.b.chdis = 1;
2195 hcchar.b.epdir = 0;
2196 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2197 }
2198
2199 /* Halt all channels to put them into a known state. */
2200 for (i = 0; i < num_channels; i++) {
2201 int count = 0;
2202 hc_regs = core_if->host_if->hc_regs[i];
2203 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2204 hcchar.b.chen = 1;
2205 hcchar.b.chdis = 1;
2206 hcchar.b.epdir = 0;
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);
2209 do {
2210 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2211 if (++count > 1000) {
2212 DWC_ERROR
2213 ("%s: Unable to clear halt on channel %d (timeout HCCHAR 0x%X @%p)\n",
2214 __func__, i, hcchar.d32, &hc_regs->hcchar);
2215 break;
2216 }
2217 dwc_udelay(1);
2218 } while (hcchar.b.chen);
2219 }
2220 }
2221
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) {
2228 hprt0.b.prtpwr = 1;
2229 DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2230 }
2231 }
2232
2233 dwc_otg_enable_host_interrupts(core_if);
2234 }
2235
2236 /**
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.
2241 *
2242 * @param core_if Programming view of DWC_otg controller
2243 * @param hc Information needed to initialize the host channel
2244 */
2245 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2246 {
2247 hcintmsk_data_t hc_intr_mask;
2248 hcchar_data_t hcchar;
2249 hcsplt_data_t hcsplt;
2250
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];
2254
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);
2259
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;
2267 else {
2268 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2269 hc_intr_mask.b.xfercompl = 1;
2270 }
2271
2272 if (hc->error_state && !hc->do_split &&
2273 hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2274 hc_intr_mask.b.ack = 1;
2275 if (hc->ep_is_in) {
2276 hc_intr_mask.b.datatglerr = 1;
2277 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2278 hc_intr_mask.b.nak = 1;
2279 }
2280 }
2281 }
2282 } else {
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;
2290 if (hc->ep_is_in) {
2291 hc_intr_mask.b.bblerr = 1;
2292 } else {
2293 hc_intr_mask.b.nak = 1;
2294 hc_intr_mask.b.nyet = 1;
2295 if (hc->do_ping) {
2296 hc_intr_mask.b.ack = 1;
2297 }
2298 }
2299
2300 if (hc->do_split) {
2301 hc_intr_mask.b.nak = 1;
2302 if (hc->complete_split) {
2303 hc_intr_mask.b.nyet = 1;
2304 } else {
2305 hc_intr_mask.b.ack = 1;
2306 }
2307 }
2308
2309 if (hc->error_state) {
2310 hc_intr_mask.b.ack = 1;
2311 }
2312 break;
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;
2320
2321 if (hc->ep_is_in) {
2322 hc_intr_mask.b.bblerr = 1;
2323 }
2324 if (hc->error_state) {
2325 hc_intr_mask.b.ack = 1;
2326 }
2327 if (hc->do_split) {
2328 if (hc->complete_split) {
2329 hc_intr_mask.b.nyet = 1;
2330 } else {
2331 hc_intr_mask.b.ack = 1;
2332 }
2333 }
2334 break;
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;
2339
2340 if (hc->ep_is_in) {
2341 hc_intr_mask.b.xacterr = 1;
2342 hc_intr_mask.b.bblerr = 1;
2343 }
2344 break;
2345 }
2346 }
2347 DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2348
2349 /*
2350 * Program the HCCHARn register with the endpoint characteristics for
2351 * the current transfer.
2352 */
2353 hcchar.d32 = 0;
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;
2360
2361 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2362
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);
2369
2370 /*
2371 * Program the HCSPLIT register for SPLITs
2372 */
2373 hcsplt.d32 = 0;
2374 if (hc->do_split) {
2375 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
2376 hc->hc_num,
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);
2389 }
2390 DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2391
2392 }
2393
2394 /**
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
2399 * intervention.
2400 *
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.
2408 *
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.
2412 *
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.
2416 *
2417 * @param core_if Controller register interface.
2418 * @param hc Host channel to halt.
2419 * @param halt_status Reason for halting the channel.
2420 */
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)
2423 {
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;
2430
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;
2434
2435 DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
2436 "halt_status = %d\n", halt_status);
2437
2438 if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2439 halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2440 /*
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.
2445 */
2446 hcintmsk_data_t hcintmsk;
2447 hcintmsk.d32 = 0;
2448 hcintmsk.b.chhltd = 1;
2449 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
2450
2451 /*
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.
2455 */
2456 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
2457
2458 /*
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
2461 * reason.
2462 */
2463 hc->halt_status = halt_status;
2464
2465 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2466 if (hcchar.b.chen == 0) {
2467 /*
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
2476 * started yet.
2477 */
2478 return;
2479 }
2480 }
2481 if (hc->halt_pending) {
2482 /*
2483 * A halt has already been issued for this channel. This might
2484 * happen when a transfer is aborted by a higher level in
2485 * the stack.
2486 */
2487 #ifdef DEBUG
2488 DWC_PRINTF
2489 ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2490 __func__, hc->hc_num);
2491
2492 #endif
2493 return;
2494 }
2495
2496 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2497
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)
2501 hcchar.b.chen = 1;
2502 hcchar.b.chdis = 1;
2503
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) {
2510 hcchar.b.chen = 0;
2511 }
2512 } else {
2513 hptxsts.d32 =
2514 DWC_READ_REG32(&host_global_regs->hptxsts);
2515 if ((hptxsts.b.ptxqspcavail == 0)
2516 || (core_if->queuing_high_bandwidth)) {
2517 hcchar.b.chen = 0;
2518 }
2519 }
2520 }
2521 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2522
2523 hc->halt_status = halt_status;
2524
2525 if (hcchar.b.chen) {
2526 hc->halt_pending = 1;
2527 hc->halt_on_queue = 0;
2528 } else {
2529 hc->halt_on_queue = 1;
2530 }
2531
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);
2537
2538 return;
2539 }
2540
2541 /**
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.
2544 *
2545 * @param core_if Programming view of DWC_otg controller.
2546 * @param hc Identifies the host channel to clean up.
2547 */
2548 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2549 {
2550 dwc_otg_hc_regs_t *hc_regs;
2551
2552 hc->xfer_started = 0;
2553
2554 /*
2555 * Clear channel interrupt enables and any unhandled channel interrupt
2556 * conditions.
2557 */
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);
2561 #ifdef DEBUG
2562 DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
2563 #endif
2564 }
2565
2566 /**
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.
2570 *
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
2574 * channel.
2575 */
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)
2578 {
2579 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2580 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2581 hfnum_data_t hfnum;
2582 hfnum.d32 =
2583 DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
2584
2585 /* 1 if _next_ frame is odd, 0 if it's even */
2586 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2587 #ifdef DEBUG
2588 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
2589 && !hc->complete_split) {
2590 switch (hfnum.b.frnum & 0x7) {
2591 case 7:
2592 core_if->hfnum_7_samples++;
2593 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2594 break;
2595 case 0:
2596 core_if->hfnum_0_samples++;
2597 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2598 break;
2599 default:
2600 core_if->hfnum_other_samples++;
2601 core_if->hfnum_other_frrem_accum +=
2602 hfnum.b.frrem;
2603 break;
2604 }
2605 }
2606 #endif
2607 }
2608 }
2609
2610 #ifdef DEBUG
2611 void hc_xfer_timeout(void *ptr)
2612 {
2613 hc_xfer_info_t *xfer_info = NULL;
2614 int hc_num = 0;
2615
2616 if (ptr)
2617 xfer_info = (hc_xfer_info_t *) ptr;
2618
2619 if (!xfer_info->hc) {
2620 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
2621 return;
2622 }
2623
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]);
2628 }
2629 #endif
2630
2631 void ep_xfer_timeout(void *ptr)
2632 {
2633 ep_xfer_info_t *xfer_info = NULL;
2634 int ep_num = 0;
2635 dctl_data_t dctl = {.d32 = 0 };
2636 gintsts_data_t gintsts = {.d32 = 0 };
2637 gintmsk_data_t gintmsk = {.d32 = 0 };
2638
2639 if (ptr)
2640 xfer_info = (ep_xfer_info_t *) ptr;
2641
2642 if (!xfer_info->ep) {
2643 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
2644 return;
2645 }
2646
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;
2651
2652 dctl.d32 =
2653 DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl);
2654 gintsts.d32 =
2655 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts);
2656 gintmsk.d32 =
2657 DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk);
2658
2659 if (!gintmsk.b.goutnakeff) {
2660 /* Unmask it */
2661 gintmsk.b.goutnakeff = 1;
2662 DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk,
2663 gintmsk.d32);
2664
2665 }
2666
2667 if (!gintsts.b.goutnakeff) {
2668 dctl.b.sgoutnak = 1;
2669 }
2670 DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl,
2671 dctl.d32);
2672
2673 }
2674
2675 void set_pid_isoc(dwc_hc_t * hc)
2676 {
2677 /* Set up the initial PID for the transfer. */
2678 if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2679 if (hc->ep_is_in) {
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;
2684 } else {
2685 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2686 }
2687 } else {
2688 if (hc->multi_count == 1) {
2689 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2690 } else {
2691 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2692 }
2693 }
2694 } else {
2695 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2696 }
2697 }
2698
2699 /**
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.
2704 *
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
2707 * the Host ISR.
2708 *
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.
2712 *
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.
2717 *
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
2722 * transfer.
2723 *
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.
2729 */
2730 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2731 {
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];
2738
2739 hctsiz.d32 = 0;
2740
2741 if (hc->do_ping) {
2742 if (!core_if->dma_enable) {
2743 dwc_otg_hc_do_ping(core_if, hc);
2744 hc->xfer_started = 1;
2745 return;
2746 } else {
2747 hctsiz.b.dopng = 1;
2748 }
2749 }
2750
2751 if (hc->do_split) {
2752 num_packets = 1;
2753
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 */
2757 hc->xfer_len = 0;
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)) {
2761 hc->xfer_len = 188;
2762 }
2763
2764 hctsiz.b.xfersize = hc->xfer_len;
2765 } else {
2766 /*
2767 * Ensure that the transfer length and packet count will fit
2768 * in the widths allocated for them in the HCTSIZn register.
2769 */
2770 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2771 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2772 /*
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.)
2778 */
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;
2783 } else {
2784 }
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;
2788 }
2789
2790 if (hc->xfer_len > 0) {
2791 num_packets =
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;
2797 }
2798 } else {
2799 /* Need 1 packet for transfer length of 0. */
2800 num_packets = 1;
2801 }
2802
2803 if (hc->ep_is_in) {
2804 /* Always program an integral # of max packets for IN transfers. */
2805 hc->xfer_len = num_packets * hc->max_packet;
2806 }
2807
2808 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2809 hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2810 /*
2811 * Make sure that the multi_count field matches the
2812 * actual transfer length.
2813 */
2814 hc->multi_count = num_packets;
2815 }
2816
2817 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2818 set_pid_isoc(hc);
2819
2820 hctsiz.b.xfersize = hc->xfer_len;
2821 }
2822
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);
2827
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);
2832
2833 if (core_if->dma_enable) {
2834 dwc_dma_t dma_addr;
2835 if (hc->align_buff) {
2836 dma_addr = hc->align_buff;
2837 } else {
2838 dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
2839 }
2840 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
2841 }
2842
2843 /* Start the split */
2844 if (hc->do_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);
2849 }
2850
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);
2854 #ifdef DEBUG
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);
2859 }
2860 #endif
2861
2862 /* Set host channel enable after all other setup is complete. */
2863 hcchar.b.chen = 1;
2864 hcchar.b.chdis = 0;
2865 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2866
2867 hc->xfer_started = 1;
2868 hc->requests++;
2869
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);
2873 }
2874 #ifdef DEBUG
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;
2880
2881 /* Start a timer for this transfer. */
2882 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2883 }
2884 #endif
2885 }
2886
2887 /**
2888 * This function does the setup for a data transfer for a host channel
2889 * and starts the transfer in Descriptor DMA mode.
2890 *
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.
2894 *
2895 * Initializes HCDMA register with descriptor list address and CTD value
2896 * then starts the transfer via enabling the channel.
2897 *
2898 * @param core_if Programming view of DWC_otg controller.
2899 * @param hc Information needed to initialize the host channel.
2900 */
2901 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2902 {
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;
2906 hcdma_data_t hcdma;
2907
2908 hctsiz.d32 = 0;
2909
2910 if (hc->do_ping)
2911 hctsiz.b_ddma.dopng = 1;
2912
2913 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2914 set_pid_isoc(hc);
2915
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 */
2920
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);
2924
2925 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2926
2927 hcdma.d32 = 0;
2928 hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
2929
2930 /* Always start from first descriptor. */
2931 hcdma.b.ctd = 0;
2932 DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
2933
2934 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2935 hcchar.b.multicnt = hc->multi_count;
2936
2937 #ifdef DEBUG
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);
2942 }
2943 #endif
2944
2945 /* Set host channel enable after all other setup is complete. */
2946 hcchar.b.chen = 1;
2947 hcchar.b.chdis = 0;
2948
2949 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2950
2951 hc->xfer_started = 1;
2952 hc->requests++;
2953
2954 #ifdef DEBUG
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);
2963 }
2964 #endif
2965
2966 }
2967
2968 /**
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.
2974 *
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.
2979 *
2980 * @return 1 if a new request is queued, 0 if no more requests are required
2981 * for this transfer.
2982 */
2983 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2984 {
2985 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2986
2987 if (hc->do_split) {
2988 /* SPLITs always queue just once per channel */
2989 return 0;
2990 } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
2991 /* SETUPs are queued only once since they can't be NAKed. */
2992 return 0;
2993 } else if (hc->ep_is_in) {
2994 /*
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
3004 * be flushed.
3005 */
3006 hcchar_data_t hcchar;
3007 dwc_otg_hc_regs_t *hc_regs =
3008 core_if->host_if->hc_regs[hc->hc_num];
3009
3010 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3011 hc_set_even_odd_frame(core_if, hc, &hcchar);
3012 hcchar.b.chen = 1;
3013 hcchar.b.chdis = 0;
3014 DWC_DEBUGPL(DBG_HCDV, " IN xfer: hcchar = 0x%08x\n",
3015 hcchar.d32);
3016 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3017 hc->requests++;
3018 return 1;
3019 } else {
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);
3029 }
3030
3031 /* Load OUT packet into the appropriate Tx FIFO. */
3032 dwc_otg_hc_write_packet(core_if, hc);
3033 hc->requests++;
3034 return 1;
3035 } else {
3036 return 0;
3037 }
3038 }
3039 }
3040
3041 /**
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.
3044 */
3045 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3046 {
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];
3050
3051 DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3052
3053 hctsiz.d32 = 0;
3054 hctsiz.b.dopng = 1;
3055 hctsiz.b.pktcnt = 1;
3056 DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3057
3058 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3059 hcchar.b.chen = 1;
3060 hcchar.b.chdis = 0;
3061 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3062 }
3063
3064 /*
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
3069 * mode.
3070 *
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.
3073 */
3074 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3075 {
3076 uint32_t i;
3077 uint32_t remaining_count;
3078 uint32_t byte_count;
3079 uint32_t dword_count;
3080
3081 uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
3082 uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
3083
3084 remaining_count = hc->xfer_len - hc->xfer_count;
3085 if (remaining_count > hc->max_packet) {
3086 byte_count = hc->max_packet;
3087 } else {
3088 byte_count = remaining_count;
3089 }
3090
3091 dword_count = (byte_count + 3) / 4;
3092
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);
3097 }
3098 } else {
3099 /* xfer_buff is not DWORD aligned. */
3100 for (i = 0; i < dword_count; i++, data_buff++) {
3101 uint32_t data;
3102 data =
3103 (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
3104 16 | data_buff[3] << 24);
3105 DWC_WRITE_REG32(data_fifo, data);
3106 }
3107 }
3108
3109 hc->xfer_count += byte_count;
3110 hc->xfer_buff += byte_count;
3111 }
3112
3113 /**
3114 * Gets the current USB frame number. This is the frame number from the last
3115 * SOF packet.
3116 */
3117 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
3118 {
3119 dsts_data_t dsts;
3120 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
3121
3122 /* read current frame/microframe number from DSTS register */
3123 return dsts.b.soffn;
3124 }
3125
3126 /**
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.
3131 */
3132
3133 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
3134 {
3135 gusbcfg_data_t usbcfg;
3136 hwcfg2_data_t hwcfg2;
3137 hprt0_data_t hprt0;
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)
3143 clock = 60;
3144 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
3145 clock = 48;
3146 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3147 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3148 clock = 30;
3149 if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3150 !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3151 clock = 60;
3152 if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3153 !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3154 clock = 48;
3155 if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
3156 clock = 48;
3157 if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
3158 clock = 48;
3159 if (hprt0.b.prtspd == 0)
3160 /* High speed case */
3161 return 125 * clock - 1;
3162 else
3163 /* FS/LS case */
3164 return 1000 * clock - 1;
3165 }
3166
3167 /**
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.
3171 *
3172 * @param core_if Programming view of DWC_otg controller.
3173 * @param dest Destination buffer for packet data.
3174 */
3175 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
3176 {
3177 device_grxsts_data_t status;
3178 /* Get the 8 bytes of a setup transaction data */
3179
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) {
3184 status.d32 =
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);
3190 }
3191 }
3192
3193 /**
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.
3197 *
3198 * @param core_if Programming view of DWC_otg controller.
3199 * @param ep The EP0 data.
3200 */
3201 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3202 {
3203 dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3204 dsts_data_t dsts;
3205 depctl_data_t diepctl;
3206 depctl_data_t doepctl;
3207 dctl_data_t dctl = {.d32 = 0 };
3208
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);
3214
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;
3221 break;
3222 case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3223 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3224 break;
3225 }
3226
3227 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3228
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);
3233 }
3234 #ifdef VERBOSE
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));
3239 #endif
3240 dctl.b.cgnpinnak = 1;
3241
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));
3245
3246 }
3247
3248 /**
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.
3252 *
3253 * @param core_if Programming view of DWC_otg controller.
3254 * @param ep The EP to activate.
3255 */
3256 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3257 {
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 };
3262 dcfg_data_t dcfg;
3263 uint8_t i;
3264
3265 DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3266 (ep->is_in ? "IN" : "OUT"));
3267
3268 #ifdef DWC_UTE_PER_IO
3269 ep->xiso_frame_num = 0xFFFFFFFF;
3270 ep->xiso_active_xfers = 0;
3271 ep->xiso_queued_xfers = 0;
3272 #endif
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;
3277 } else {
3278 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3279 daintmsk.ep.out = 1 << ep->num;
3280 }
3281
3282 /* If the EP is already active don't change the EP Control
3283 * register. */
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;
3289
3290 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3291 depctl.b.setd0pid = 1; // ???
3292 } else {
3293 depctl.b.setd0pid = 1;
3294 }
3295 depctl.b.usbactep = 1;
3296
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)
3301 break;
3302 }
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);
3307 dcfg.b.epmscnt++;
3308 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3309
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]);
3316 }
3317
3318 }
3319
3320
3321 DWC_WRITE_REG32(addr, depctl.d32);
3322 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
3323 }
3324
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) {
3338 diepmsk.b.nak = 1;
3339 }
3340
3341
3342
3343 /*
3344 if (core_if->dma_desc_enable) {
3345 diepmsk.b.bna = 1;
3346 }
3347 */
3348 /*
3349 if (core_if->dma_enable) {
3350 doepmsk.b.nak = 1;
3351 }
3352 */
3353 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3354 diepeachintmsk[ep->num], diepmsk.d32);
3355
3356 } else {
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;
3363
3364 /*
3365
3366 if (core_if->dma_desc_enable) {
3367 doepmsk.b.bna = 1;
3368 }
3369 */
3370 /*
3371 doepmsk.b.babble = 1;
3372 doepmsk.b.nyet = 1;
3373 doepmsk.b.nak = 1;
3374 */
3375 DWC_WRITE_REG32(&dev_if->dev_global_regs->
3376 doepeachintmsk[ep->num], doepmsk.d32);
3377 }
3378 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
3379 0, daintmsk.d32);
3380 } else {
3381 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3382 if (ep->is_in) {
3383 diepmsk_data_t diepmsk = {.d32 = 0 };
3384 diepmsk.b.nak = 1;
3385 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
3386 } else {
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);
3390 }
3391 }
3392 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
3393 0, daintmsk.d32);
3394 }
3395
3396 DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
3397 DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
3398
3399 ep->stall_clear_flag = 0;
3400
3401 return;
3402 }
3403
3404 /**
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.
3408 *
3409 * @param core_if Programming view of DWC_otg controller.
3410 * @param ep The EP to deactivate.
3411 */
3412 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3413 {
3414 depctl_data_t depctl = {.d32 = 0 };
3415 volatile uint32_t *addr;
3416 daint_data_t daintmsk = {.d32 = 0 };
3417 dcfg_data_t dcfg;
3418 uint8_t i = 0;
3419
3420 #ifdef DWC_UTE_PER_IO
3421 ep->xiso_frame_num = 0xFFFFFFFF;
3422 ep->xiso_active_xfers = 0;
3423 ep->xiso_queued_xfers = 0;
3424 #endif
3425
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;
3430 } else {
3431 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3432 daintmsk.ep.out = 1 << ep->num;
3433 }
3434
3435 depctl.d32 = DWC_READ_REG32(addr);
3436
3437 depctl.b.usbactep = 0;
3438
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)
3443 break;
3444 }
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;
3450 dcfg.d32 =
3451 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
3452 dcfg.b.epmscnt--;
3453 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
3454 dcfg.d32);
3455
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]);
3461 }
3462 }
3463
3464 if (ep->is_in == 1)
3465 depctl.b.txfnum = 0;
3466
3467 if (core_if->dma_desc_enable)
3468 depctl.b.epdis = 1;
3469
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};
3475 if (ep->is_in) {
3476 diepint_data_t diepint = {.d32 = 0};
3477
3478 depctl.b.snak = 1;
3479 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3480 diepctl, depctl.d32);
3481 do {
3482 dwc_udelay(10);
3483 diepint.d32 =
3484 DWC_READ_REG32(&core_if->
3485 dev_if->in_ep_regs[ep->num]->
3486 diepint);
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);
3491 depctl.d32 = 0;
3492 depctl.b.epdis = 1;
3493 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3494 diepctl, depctl.d32);
3495 do {
3496 dwc_udelay(10);
3497 diepint.d32 =
3498 DWC_READ_REG32(&core_if->
3499 dev_if->in_ep_regs[ep->num]->
3500 diepint);
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);
3505 } else {
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->
3511 dctl, 0, dctl.d32);
3512 do {
3513 dwc_udelay(10);
3514 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
3515 } while (!gintsts.b.goutnakeff);
3516 gintsts.d32 = 0;
3517 gintsts.b.goutnakeff = 1;
3518 DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
3519
3520 depctl.d32 = 0;
3521 depctl.b.epdis = 1;
3522 depctl.b.snak = 1;
3523 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
3524 do
3525 {
3526 dwc_udelay(10);
3527 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
3528 out_ep_regs[ep->num]->doepint);
3529 } while (!doepint.b.epdisabled);
3530
3531 doepint.b.epdisabled = 1;
3532 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
3533
3534 dctl.d32 = 0;
3535 dctl.b.cgoutnak = 1;
3536 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
3537 }
3538 }
3539
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,
3543 daintmsk.d32, 0);
3544
3545 if (ep->is_in == 1) {
3546 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3547 diepeachintmsk[ep->num], 0);
3548 } else {
3549 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3550 doepeachintmsk[ep->num], 0);
3551 }
3552 } else {
3553 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
3554 daintmsk.d32, 0);
3555 }
3556
3557 }
3558
3559 /**
3560 * This function initializes dma descriptor chain.
3561 *
3562 * @param core_if Programming view of DWC_otg controller.
3563 * @param ep The EP to start the transfer on.
3564 */
3565 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3566 {
3567 dwc_otg_dev_dma_desc_t *dma_desc;
3568 uint32_t offset;
3569 uint32_t xfer_est;
3570 int i;
3571 unsigned maxxfer_local, total_len;
3572
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;
3577 } else {
3578 maxxfer_local = ep->maxxfer;
3579 total_len = ep->total_len;
3580 }
3581
3582 ep->desc_cnt = (total_len / maxxfer_local) +
3583 ((total_len % maxxfer_local) ? 1 : 0);
3584
3585 if (!ep->desc_cnt)
3586 ep->desc_cnt = 1;
3587
3588 if (ep->desc_cnt > MAX_DMA_DESC_CNT)
3589 ep->desc_cnt = MAX_DMA_DESC_CNT;
3590
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);
3597 } else
3598 xfer_est = ep->desc_cnt * maxxfer_local;
3599 } else
3600 xfer_est = total_len;
3601 offset = 0;
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;
3613
3614 xfer_est -= maxxfer_local;
3615 offset += maxxfer_local;
3616 } else {
3617 dma_desc->status.b.bs = BS_HOST_BUSY;
3618 dma_desc->status.b.l = 1;
3619 dma_desc->status.b.ioc = 1;
3620 if (ep->is_in) {
3621 dma_desc->status.b.sp =
3622 (xfer_est %
3623 ep->maxpacket) ? 1 : ((ep->
3624 sent_zlp) ? 1 : 0);
3625 dma_desc->status.b.bytes = xfer_est;
3626 } else {
3627 if (maxxfer_local == ep->maxpacket)
3628 dma_desc->status.b.bytes = xfer_est;
3629 else
3630 dma_desc->status.b.bytes =
3631 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
3632 }
3633
3634 dma_desc->buf = ep->dma_addr + offset;
3635 dma_desc->status.b.sts = 0;
3636 dma_desc->status.b.bs = BS_HOST_READY;
3637 }
3638 dma_desc++;
3639 }
3640 }
3641 /**
3642 * This function is called when to write ISOC data into appropriate dedicated
3643 * periodic FIFO.
3644 */
3645 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
3646 {
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 };
3650 uint32_t len = 0;
3651 int epnum = dwc_ep->num;
3652 int dwords;
3653
3654 DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
3655
3656 ep_regs = core_if->dev_if->in_ep_regs[epnum];
3657
3658 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3659
3660 if (len > dwc_ep->maxpacket) {
3661 len = dwc_ep->maxpacket;
3662 }
3663
3664 dwords = (len + 3) / 4;
3665
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);
3670
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);
3675
3676 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3677 if (len > dwc_ep->maxpacket) {
3678 len = dwc_ep->maxpacket;
3679 }
3680
3681 dwords = (len + 3) / 4;
3682 txstatus.d32 =
3683 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3684 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
3685 txstatus.d32);
3686 }
3687
3688 DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
3689 DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
3690
3691 return 1;
3692 }
3693 /**
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.
3698 *
3699 * @param core_if Programming view of DWC_otg controller.
3700 * @param ep The EP to start the transfer on.
3701 */
3702
3703 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3704 {
3705 depctl_data_t depctl;
3706 deptsiz_data_t deptsiz;
3707 gintmsk_data_t intr_mask = {.d32 = 0 };
3708
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,
3714 ep->total_len);
3715 /* IN endpoint */
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];
3719
3720 gnptxsts_data_t gtxstatus;
3721
3722 gtxstatus.d32 =
3723 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
3724
3725 if (core_if->en_multiple_tx_fifo == 0
3726 && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) {
3727 #ifdef DEBUG
3728 DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3729 #endif
3730 return;
3731 }
3732
3733 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
3734 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
3735
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);
3739 else
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);
3742
3743
3744 /* Zero Length Packet? */
3745 if ((ep->xfer_len - ep->xfer_count) == 0) {
3746 deptsiz.b.xfersize = 0;
3747 deptsiz.b.pktcnt = 1;
3748 } else {
3749 /* Program the transfer size and packet count
3750 * as follows: xfersize = N * maxpacket +
3751 * short_packet pktcnt = N + (short_packet
3752 * exist ? 1 : 0)
3753 */
3754 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3755 deptsiz.b.pktcnt =
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;
3761 }
3762 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3763 deptsiz.b.mc = deptsiz.b.pktcnt;
3764 }
3765
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)
3770 deptsiz.b.mc = 1;
3771 DWC_WRITE_REG32(&in_regs->dieptsiz,
3772 deptsiz.d32);
3773 DWC_WRITE_REG32(&(in_regs->diepdma),
3774 (uint32_t) ep->dma_addr);
3775 } else {
3776 #ifdef DWC_UTE_CFI
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);
3781 } else {
3782 #endif
3783 init_dma_desc_chain(core_if, ep);
3784 /** DIEPDMAn Register write */
3785 DWC_WRITE_REG32(&in_regs->diepdma,
3786 ep->dma_desc_addr);
3787 #ifdef DWC_UTE_CFI
3788 }
3789 #endif
3790 }
3791 } else {
3792 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
3793 if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
3794 /**
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.
3798 */
3799 if (core_if->en_multiple_tx_fifo == 0) {
3800 intr_mask.b.nptxfempty = 1;
3801 DWC_MODIFY_REG32
3802 (&core_if->core_global_regs->gintmsk,
3803 intr_mask.d32, intr_mask.d32);
3804 } else {
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;
3809 DWC_MODIFY_REG32
3810 (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3811 0, fifoemptymsk);
3812
3813 }
3814 }
3815 } else {
3816 write_isoc_tx_fifo(core_if, ep);
3817 }
3818 }
3819 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
3820 depctl.b.nextep = core_if->nextep_seq[ep->num];
3821
3822 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3823 dsts_data_t dsts = {.d32 = 0};
3824 if (ep->bInterval == 1) {
3825 dsts.d32 =
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;
3832 } else
3833 ep->frm_overrun = 0;
3834 if (ep->frame_num & 0x1) {
3835 depctl.b.setd1pid = 1;
3836 } else {
3837 depctl.b.setd0pid = 1;
3838 }
3839 }
3840 }
3841 /* EP enable, IN data in FIFO */
3842 depctl.b.cnak = 1;
3843 depctl.b.epena = 1;
3844 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
3845
3846 } else {
3847 /* OUT endpoint */
3848 dwc_otg_dev_out_ep_regs_t *out_regs =
3849 core_if->dev_if->out_ep_regs[ep->num];
3850
3851 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
3852 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
3853
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);
3858 else
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);
3861 }
3862
3863 /* Program the transfer size and packet count as follows:
3864 *
3865 * pktcnt = N
3866 * xfersize = N * maxpacket
3867 */
3868 if ((ep->xfer_len - ep->xfer_count) == 0) {
3869 /* Zero Length Packet */
3870 deptsiz.b.xfersize = ep->maxpacket;
3871 deptsiz.b.pktcnt = 1;
3872 } else {
3873 deptsiz.b.pktcnt =
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;
3878 }
3879 if (!core_if->dma_desc_enable) {
3880 ep->xfer_len =
3881 deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
3882 }
3883 deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3884 }
3885
3886 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3887 ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
3888
3889 if (core_if->dma_enable) {
3890 if (!core_if->dma_desc_enable) {
3891 DWC_WRITE_REG32(&out_regs->doeptsiz,
3892 deptsiz.d32);
3893
3894 DWC_WRITE_REG32(&(out_regs->doepdma),
3895 (uint32_t) ep->dma_addr);
3896 } else {
3897 #ifdef DWC_UTE_CFI
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);
3902 } else {
3903 #endif
3904 /** This is used for interrupt out transfers*/
3905 if (!ep->xfer_len)
3906 ep->xfer_len = ep->total_len;
3907 init_dma_desc_chain(core_if, ep);
3908
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,
3917 deptsiz.d32);
3918 }
3919 }
3920 /** DOEPDMAn Register write */
3921 DWC_WRITE_REG32(&out_regs->doepdma,
3922 ep->dma_desc_addr);
3923 #ifdef DWC_UTE_CFI
3924 }
3925 #endif
3926 }
3927 } else {
3928 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
3929 }
3930
3931 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3932 dsts_data_t dsts = {.d32 = 0};
3933 if (ep->bInterval == 1) {
3934 dsts.d32 =
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;
3941 } else
3942 ep->frm_overrun = 0;
3943
3944 if (ep->frame_num & 0x1) {
3945 depctl.b.setd1pid = 1;
3946 } else {
3947 depctl.b.setd0pid = 1;
3948 }
3949 }
3950 }
3951
3952 /* EP enable */
3953 depctl.b.cnak = 1;
3954 depctl.b.epena = 1;
3955
3956 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
3957
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->
3963 daintmsk),
3964 DWC_READ_REG32(&core_if->core_global_regs->
3965 gintmsk));
3966
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
3970 */
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;
3976
3977 /* Start a timer for this transfer. */
3978 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
3979 }
3980 }
3981 }
3982 }
3983
3984 /**
3985 * This function setup a zero length transfer in Buffer DMA and
3986 * Slave modes for usb requests with zero field set
3987 *
3988 * @param core_if Programming view of DWC_otg controller.
3989 * @param ep The EP to start the transfer on.
3990 *
3991 */
3992 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3993 {
3994
3995 depctl_data_t depctl;
3996 deptsiz_data_t deptsiz;
3997 gintmsk_data_t intr_mask = {.d32 = 0 };
3998
3999 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4000 DWC_PRINTF("zero length transfer is called\n");
4001
4002 /* IN endpoint */
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];
4006
4007 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4008 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4009
4010 deptsiz.b.xfersize = 0;
4011 deptsiz.b.pktcnt = 1;
4012
4013 /* Write the DMA register */
4014 if (core_if->dma_enable) {
4015 if (core_if->dma_desc_enable == 0) {
4016 deptsiz.b.mc = 1;
4017 DWC_WRITE_REG32(&in_regs->dieptsiz,
4018 deptsiz.d32);
4019 DWC_WRITE_REG32(&(in_regs->diepdma),
4020 (uint32_t) ep->dma_addr);
4021 }
4022 } else {
4023 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4024 /**
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.
4028 */
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);
4034 } else {
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,
4041 0, fifoemptymsk);
4042 }
4043 }
4044 }
4045
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 */
4049 depctl.b.cnak = 1;
4050 depctl.b.epena = 1;
4051 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4052
4053 } else {
4054 /* OUT endpoint */
4055 dwc_otg_dev_out_ep_regs_t *out_regs =
4056 core_if->dev_if->out_ep_regs[ep->num];
4057
4058 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4059 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4060
4061 /* Zero Length Packet */
4062 deptsiz.b.xfersize = ep->maxpacket;
4063 deptsiz.b.pktcnt = 1;
4064
4065 if (core_if->dma_enable) {
4066 if (!core_if->dma_desc_enable) {
4067 DWC_WRITE_REG32(&out_regs->doeptsiz,
4068 deptsiz.d32);
4069
4070 DWC_WRITE_REG32(&(out_regs->doepdma),
4071 (uint32_t) ep->dma_addr);
4072 }
4073 } else {
4074 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4075 }
4076
4077 /* EP enable */
4078 depctl.b.cnak = 1;
4079 depctl.b.epena = 1;
4080
4081 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4082
4083 }
4084 }
4085
4086 /**
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.
4091 *
4092 * @param core_if Programming view of DWC_otg controller.
4093 * @param ep The EP0 data.
4094 */
4095 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4096 {
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;
4101
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);
4106
4107 ep->total_len = ep->xfer_len;
4108
4109 /* IN endpoint */
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];
4113
4114 gnptxsts_data_t gtxstatus;
4115
4116 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4117 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4118 if (depctl.b.epena)
4119 return;
4120 }
4121
4122 gtxstatus.d32 =
4123 DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4124
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);
4128
4129 if (core_if->en_multiple_tx_fifo == 0
4130 && gtxstatus.b.nptxqspcavail == 0
4131 && !core_if->dma_enable) {
4132 #ifdef DEBUG
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",
4137 deptsiz.d32,
4138 deptsiz.b.xfersize, deptsiz.b.pktcnt);
4139 DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4140 gtxstatus.d32);
4141 #endif
4142 return;
4143 }
4144
4145 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4146 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4147
4148 /* Zero Length Packet? */
4149 if (ep->xfer_len == 0) {
4150 deptsiz.b.xfersize = 0;
4151 deptsiz.b.pktcnt = 1;
4152 } else {
4153 /* Program the transfer size and packet count
4154 * as follows: xfersize = N * maxpacket +
4155 * short_packet pktcnt = N + (short_packet
4156 * exist ? 1 : 0)
4157 */
4158 if (ep->xfer_len > ep->maxpacket) {
4159 ep->xfer_len = ep->maxpacket;
4160 deptsiz.b.xfersize = ep->maxpacket;
4161 } else {
4162 deptsiz.b.xfersize = ep->xfer_len;
4163 }
4164 deptsiz.b.pktcnt = 1;
4165
4166 }
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,
4170 deptsiz.d32);
4171
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,
4176 deptsiz.d32);
4177
4178 DWC_WRITE_REG32(&(in_regs->diepdma),
4179 (uint32_t) ep->dma_addr);
4180 } else {
4181 dma_desc = core_if->dev_if->in_desc_addr;
4182
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;
4193
4194 /** DIEPDMA0 Register write */
4195 DWC_WRITE_REG32(&in_regs->diepdma,
4196 core_if->
4197 dev_if->dma_in_desc_addr);
4198 }
4199 } else {
4200 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4201 }
4202
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 */
4206 depctl.b.cnak = 1;
4207 depctl.b.epena = 1;
4208 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4209
4210 /**
4211 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4212 * data will be written into the fifo by the ISR.
4213 */
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);
4220 } else {
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,
4227 0, fifoemptymsk);
4228 }
4229 }
4230 }
4231 } else {
4232 /* OUT endpoint */
4233 dwc_otg_dev_out_ep_regs_t *out_regs =
4234 core_if->dev_if->out_ep_regs[0];
4235
4236 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4237 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4238
4239 /* Program the transfer size and packet count as follows:
4240 * xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4241 * pktcnt = N */
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;
4247
4248 DWC_DEBUGPL(DBG_PCDV, "len=%d xfersize=%d pktcnt=%d\n",
4249 ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4250
4251 if (core_if->dma_enable) {
4252 if (!core_if->dma_desc_enable) {
4253 DWC_WRITE_REG32(&out_regs->doeptsiz,
4254 deptsiz.d32);
4255
4256 DWC_WRITE_REG32(&(out_regs->doepdma),
4257 (uint32_t) ep->dma_addr);
4258 } else {
4259 dma_desc = core_if->dev_if->out_desc_addr;
4260
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;
4266 }
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;
4273
4274 /** DOEPDMA0 Register write */
4275 DWC_WRITE_REG32(&out_regs->doepdma,
4276 core_if->dev_if->
4277 dma_out_desc_addr);
4278 }
4279 } else {
4280 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4281 }
4282
4283 /* EP enable */
4284 depctl.b.cnak = 1;
4285 depctl.b.epena = 1;
4286 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
4287 }
4288 }
4289
4290 /**
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.
4295 *
4296 * @param core_if Programming view of DWC_otg controller.
4297 * @param ep The EP0 data.
4298 */
4299 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4300 {
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;
4305
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 };
4310
4311 tx_status.d32 =
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. */
4315
4316 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4317 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4318
4319 /* Program the transfer size and packet count
4320 * as follows: xfersize = N * maxpacket +
4321 * short_packet pktcnt = N + (short_packet
4322 * exist ? 1 : 0)
4323 */
4324
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 -
4329 ep->xfer_count);
4330 deptsiz.b.pktcnt = 1;
4331 if (core_if->dma_enable == 0) {
4332 ep->xfer_len += deptsiz.b.xfersize;
4333 } else {
4334 ep->xfer_len = deptsiz.b.xfersize;
4335 }
4336 DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4337 } else {
4338 ep->xfer_len =
4339 (ep->total_len - ep->xfer_count) >
4340 ep->maxpacket ? ep->maxpacket : (ep->total_len -
4341 ep->xfer_count);
4342
4343 dma_desc = core_if->dev_if->in_desc_addr;
4344
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;
4355
4356 /** DIEPDMA0 Register write */
4357 DWC_WRITE_REG32(&in_regs->diepdma,
4358 core_if->dev_if->dma_in_desc_addr);
4359 }
4360
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,
4364 deptsiz.d32);
4365
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);
4371 }
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 */
4375 depctl.b.cnak = 1;
4376 depctl.b.epena = 1;
4377 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4378
4379 /**
4380 * Enable the Non-Periodic Tx FIFO empty interrupt, the
4381 * data will be written into the fifo by the ISR.
4382 */
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);
4390
4391 } else {
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,
4398 0, fifoemptymsk);
4399 }
4400 }
4401 }
4402 } else {
4403 dwc_otg_dev_out_ep_regs_t *out_regs =
4404 core_if->dev_if->out_ep_regs[0];
4405
4406 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4407 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4408
4409 /* Program the transfer size and packet count
4410 * as follows: xfersize = N * maxpacket +
4411 * short_packet pktcnt = N + (short_packet
4412 * exist ? 1 : 0)
4413 */
4414 deptsiz.b.xfersize = ep->maxpacket;
4415 deptsiz.b.pktcnt = 1;
4416
4417 if (core_if->dma_desc_enable == 0) {
4418 DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4419 } else {
4420 dma_desc = core_if->dev_if->out_desc_addr;
4421
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;
4430
4431 /** DOEPDMA0 Register write */
4432 DWC_WRITE_REG32(&out_regs->doepdma,
4433 core_if->dev_if->dma_out_desc_addr);
4434 }
4435
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,
4439 deptsiz.d32);
4440
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);
4446
4447 }
4448
4449 /* EP enable, IN data in FIFO */
4450 depctl.b.cnak = 1;
4451 depctl.b.epena = 1;
4452 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4453
4454 }
4455 }
4456
4457 #ifdef DEBUG
4458 void dump_msg(const u8 * buf, unsigned int length)
4459 {
4460 unsigned int start, num, i;
4461 char line[52], *p;
4462
4463 if (length >= 512)
4464 return;
4465 start = 0;
4466 while (length > 0) {
4467 num = length < 16u ? length : 16u;
4468 p = line;
4469 for (i = 0; i < num; ++i) {
4470 if (i == 8)
4471 *p++ = ' ';
4472 DWC_SPRINTF(p, " %02x", buf[i]);
4473 p += 3;
4474 }
4475 *p = 0;
4476 DWC_PRINTF("%6x: %s\n", start, line);
4477 buf += num;
4478 start += num;
4479 length -= num;
4480 }
4481 }
4482 #else
4483 static inline void dump_msg(const u8 * buf, unsigned int length)
4484 {
4485 }
4486 #endif
4487
4488 /**
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.
4493 *
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.
4497 */
4498 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
4499 int dma)
4500 {
4501 /**
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.
4505 *
4506 * ep->xfer_buff always starts DWORD aligned in memory and is a
4507 * multiple of DWORD in length
4508 *
4509 * ep->xfer_len can be any number of bytes
4510 *
4511 * ep->xfer_count is a multiple of ep->maxpacket until the last
4512 * packet
4513 *
4514 * FIFO access is DWORD */
4515
4516 uint32_t i;
4517 uint32_t byte_count;
4518 uint32_t dword_count;
4519 uint32_t *fifo;
4520 uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
4521
4522 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
4523 ep);
4524 if (ep->xfer_count >= ep->xfer_len) {
4525 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4526 return;
4527 }
4528
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;
4532 } else {
4533 byte_count = ep->maxpacket;
4534 }
4535
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;
4539
4540 #ifdef VERBOSE
4541 dump_msg(ep->xfer_buff, byte_count);
4542 #endif
4543
4544 /**@todo NGS Where are the Periodic Tx FIFO addresses
4545 * intialized? What should this be? */
4546
4547 fifo = core_if->data_fifo[ep->num];
4548
4549 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
4550 fifo, data_buff, *data_buff, byte_count);
4551
4552 if (!dma) {
4553 for (i = 0; i < dword_count; i++, data_buff++) {
4554 DWC_WRITE_REG32(fifo, *data_buff);
4555 }
4556 }
4557
4558 ep->xfer_count += byte_count;
4559 ep->xfer_buff += byte_count;
4560 ep->dma_addr += byte_count;
4561 }
4562
4563 /**
4564 * Set the EP STALL.
4565 *
4566 * @param core_if Programming view of DWC_otg controller.
4567 * @param ep The EP to set the stall on.
4568 */
4569 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4570 {
4571 depctl_data_t depctl;
4572 volatile uint32_t *depctl_addr;
4573
4574 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4575 (ep->is_in ? "IN" : "OUT"));
4576
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);
4580
4581 /* set the disable and stall bits */
4582 if (depctl.b.epena) {
4583 depctl.b.epdis = 1;
4584 }
4585 depctl.b.stall = 1;
4586 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4587 } else {
4588 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4589 depctl.d32 = DWC_READ_REG32(depctl_addr);
4590
4591 /* set the stall bit */
4592 depctl.b.stall = 1;
4593 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4594 }
4595
4596 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4597
4598 return;
4599 }
4600
4601 /**
4602 * Clear the EP STALL.
4603 *
4604 * @param core_if Programming view of DWC_otg controller.
4605 * @param ep The EP to clear stall from.
4606 */
4607 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4608 {
4609 depctl_data_t depctl;
4610 volatile uint32_t *depctl_addr;
4611
4612 DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4613 (ep->is_in ? "IN" : "OUT"));
4614
4615 if (ep->is_in == 1) {
4616 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4617 } else {
4618 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4619 }
4620
4621 depctl.d32 = DWC_READ_REG32(depctl_addr);
4622
4623 /* clear the stall bits */
4624 depctl.b.stall = 0;
4625
4626 /*
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.
4631 */
4632 if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4633 ep->type == DWC_OTG_EP_TYPE_BULK) {
4634 depctl.b.setd0pid = 1; /* DATA0 */
4635 }
4636
4637 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4638 DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4639 return;
4640 }
4641
4642 /**
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.
4645 *
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.
4649 */
4650 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
4651 uint8_t * dest, uint16_t bytes)
4652 {
4653 int i;
4654 int word_count = (bytes + 3) / 4;
4655
4656 volatile uint32_t *fifo = core_if->data_fifo[0];
4657 uint32_t *data_buff = (uint32_t *) dest;
4658
4659 /**
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.
4663 */
4664
4665 DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
4666 core_if, dest, bytes);
4667
4668 for (i = 0; i < word_count; i++, data_buff++) {
4669 *data_buff = DWC_READ_REG32(fifo);
4670 }
4671
4672 return;
4673 }
4674
4675 /**
4676 * This functions reads the device registers and prints them
4677 *
4678 * @param core_if Programming view of DWC_otg controller.
4679 */
4680 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
4681 {
4682 int i;
4683 volatile uint32_t *addr;
4684
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));
4714 }
4715
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));
4719
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));
4723
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));
4727
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));
4732 }
4733
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));
4737
4738 if (core_if->hwcfg2.b.multi_proc_int) {
4739
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));
4746
4747 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
4748 addr =
4749 &core_if->dev_if->
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));
4754 }
4755
4756 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
4757 addr =
4758 &core_if->dev_if->
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));
4763 }
4764 }
4765
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) */ );
4786 }
4787
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));
4806 }
4807
4808 }
4809 }
4810
4811 /**
4812 * This functions reads the SPRAM and prints its content
4813 *
4814 * @param core_if Programming view of DWC_otg controller.
4815 */
4816 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
4817 {
4818 volatile uint8_t *addr, *start_addr, *end_addr;
4819
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;
4826
4827 for (addr = start_addr; addr < end_addr; addr += 16) {
4828 DWC_PRINTF
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]
4833 );
4834 }
4835
4836 return;
4837 }
4838
4839 /**
4840 * This function reads the host registers and prints them
4841 *
4842 * @param core_if Programming view of DWC_otg controller.
4843 */
4844 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
4845 {
4846 int i;
4847 volatile uint32_t *addr;
4848
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));
4872 }
4873
4874 addr = core_if->host_if->hprt0;
4875 DWC_PRINTF("HPRT0 @0x%08lX : 0x%08X\n", (unsigned long)addr,
4876 DWC_READ_REG32(addr));
4877
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));
4902 }
4903
4904 }
4905 return;
4906 }
4907
4908 /**
4909 * This function reads the core global registers and prints them
4910 *
4911 * @param core_if Programming view of DWC_otg controller.
4912 */
4913 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
4914 {
4915 int i, ep_num;
4916 volatile uint32_t *addr;
4917 char *txfsiz;
4918
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));
4995
4996 if (core_if->en_multiple_tx_fifo == 0) {
4997 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
4998 txfsiz = "DPTXFSIZ";
4999 } else {
5000 ep_num = core_if->hwcfg4.b.num_in_eps;
5001 txfsiz = "DIENPTXF";
5002 }
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));
5007 }
5008 addr = core_if->pcgcctl;
5009 DWC_PRINTF("PCGCCTL @0x%08lX : 0x%08X\n", (unsigned long)addr,
5010 DWC_READ_REG32(addr));
5011 }
5012
5013 /**
5014 * Flush a Tx FIFO.
5015 *
5016 * @param core_if Programming view of DWC_otg controller.
5017 * @param num Tx FIFO to flush.
5018 */
5019 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
5020 {
5021 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5022 volatile grstctl_t greset = {.d32 = 0 };
5023 int count = 0;
5024
5025 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
5026
5027 greset.b.txfflsh = 1;
5028 greset.b.txfnum = num;
5029 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5030
5031 do {
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));
5037 break;
5038 }
5039 dwc_udelay(1);
5040 } while (greset.b.txfflsh == 1);
5041
5042 /* Wait for 3 PHY Clocks */
5043 dwc_udelay(1);
5044 }
5045
5046 /**
5047 * Flush Rx FIFO.
5048 *
5049 * @param core_if Programming view of DWC_otg controller.
5050 */
5051 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
5052 {
5053 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5054 volatile grstctl_t greset = {.d32 = 0 };
5055 int count = 0;
5056
5057 DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5058 /*
5059 *
5060 */
5061 greset.b.rxfflsh = 1;
5062 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5063
5064 do {
5065 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5066 if (++count > 10000) {
5067 DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5068 greset.d32);
5069 break;
5070 }
5071 dwc_udelay(1);
5072 } while (greset.b.rxfflsh == 1);
5073
5074 /* Wait for 3 PHY Clocks */
5075 dwc_udelay(1);
5076 }
5077
5078 /**
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.
5081 */
5082 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
5083 {
5084 dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5085 volatile grstctl_t greset = {.d32 = 0 };
5086 int count = 0;
5087
5088 DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5089 /* Wait for AHB master IDLE state. */
5090 do {
5091 dwc_udelay(10);
5092 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5093 if (++count > 100000) {
5094 DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5095 greset.d32);
5096 return;
5097 }
5098 }
5099 while (greset.b.ahbidle == 0);
5100
5101 /* Core Soft Reset */
5102 count = 0;
5103 greset.b.csftrst = 1;
5104 DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5105 do {
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);
5110 break;
5111 }
5112 dwc_udelay(1);
5113 }
5114 while (greset.b.csftrst == 1);
5115
5116 /* Wait for 3 PHY Clocks */
5117 dwc_mdelay(100);
5118 }
5119
5120 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
5121 {
5122 return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5123 }
5124
5125 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
5126 {
5127 return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5128 }
5129
5130 /**
5131 * Register HCD callbacks. The callbacks are used to start and stop
5132 * the HCD for interrupt processing.
5133 *
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*).
5137 */
5138 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
5139 dwc_otg_cil_callbacks_t * cb, void *p)
5140 {
5141 core_if->hcd_cb = cb;
5142 cb->p = p;
5143 }
5144
5145 /**
5146 * Register PCD callbacks. The callbacks are used to start and stop
5147 * the PCD for interrupt processing.
5148 *
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*).
5152 */
5153 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
5154 dwc_otg_cil_callbacks_t * cb, void *p)
5155 {
5156 core_if->pcd_cb = cb;
5157 cb->p = p;
5158 }
5159
5160 #ifdef DWC_EN_ISOC
5161
5162 /**
5163 * This function writes isoc data per 1 (micro)frame into tx fifo
5164 *
5165 * @param core_if Programming view of DWC_otg controller.
5166 * @param ep The EP to start the transfer on.
5167 *
5168 */
5169 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
5170 {
5171 dwc_otg_dev_in_ep_regs_t *ep_regs;
5172 dtxfsts_data_t txstatus = {.d32 = 0 };
5173 uint32_t len = 0;
5174 uint32_t dwords;
5175
5176 ep->xfer_len = ep->data_per_frame;
5177 ep->xfer_count = 0;
5178
5179 ep_regs = core_if->dev_if->in_ep_regs[ep->num];
5180
5181 len = ep->xfer_len - ep->xfer_count;
5182
5183 if (len > ep->maxpacket) {
5184 len = ep->maxpacket;
5185 }
5186
5187 dwords = (len + 3) / 4;
5188
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 */
5191 txstatus.d32 =
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);
5194
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);
5199
5200 len = ep->xfer_len - ep->xfer_count;
5201 if (len > ep->maxpacket) {
5202 len = ep->maxpacket;
5203 }
5204
5205 dwords = (len + 3) / 4;
5206 txstatus.d32 =
5207 DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
5208 dtxfsts);
5209 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
5210 txstatus.d32);
5211 }
5212 }
5213
5214 /**
5215 * This function initializes a descriptor chain for Isochronous transfer
5216 *
5217 * @param core_if Programming view of DWC_otg controller.
5218 * @param ep The EP to start the transfer on.
5219 *
5220 */
5221 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
5222 dwc_ep_t * ep)
5223 {
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;
5228
5229 if (ep->is_in) {
5230 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5231 } else {
5232 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5233 }
5234
5235 ep->xfer_len = ep->data_per_frame;
5236 ep->xfer_count = 0;
5237 ep->xfer_buff = ep->cur_pkt_addr;
5238 ep->dma_addr = ep->cur_pkt_dma_addr;
5239
5240 if (ep->is_in) {
5241 /* Program the transfer size and packet count
5242 * as follows: xfersize = N * maxpacket +
5243 * short_packet pktcnt = N + (short_packet
5244 * exist ? 1 : 0)
5245 */
5246 deptsiz.b.xfersize = ep->xfer_len;
5247 deptsiz.b.pktcnt =
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,
5251 deptsiz.d32);
5252
5253 /* Write the DMA register */
5254 if (core_if->dma_enable) {
5255 DWC_WRITE_REG32(&
5256 (core_if->dev_if->in_ep_regs[ep->num]->
5257 diepdma), (uint32_t) ep->dma_addr);
5258 }
5259 } else {
5260 deptsiz.b.pktcnt =
5261 (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
5262 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5263
5264 DWC_WRITE_REG32(&core_if->dev_if->
5265 out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
5266
5267 if (core_if->dma_enable) {
5268 DWC_WRITE_REG32(&
5269 (core_if->dev_if->
5270 out_ep_regs[ep->num]->doepdma),
5271 (uint32_t) ep->dma_addr);
5272 }
5273 }
5274
5275 /** Enable endpoint, clear nak */
5276
5277 depctl.d32 = 0;
5278 if (ep->bInterval == 1) {
5279 dsts.d32 =
5280 DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
5281 ep->next_frame = dsts.b.soffn + ep->bInterval;
5282
5283 if (ep->next_frame & 0x1) {
5284 depctl.b.setd1pid = 1;
5285 } else {
5286 depctl.b.setd0pid = 1;
5287 }
5288 } else {
5289 ep->next_frame += ep->bInterval;
5290
5291 if (ep->next_frame & 0x1) {
5292 depctl.b.setd1pid = 1;
5293 } else {
5294 depctl.b.setd0pid = 1;
5295 }
5296 }
5297 depctl.b.epena = 1;
5298 depctl.b.cnak = 1;
5299
5300 DWC_MODIFY_REG32(addr, 0, depctl.d32);
5301 depctl.d32 = DWC_READ_REG32(addr);
5302
5303 if (ep->is_in && core_if->dma_enable == 0) {
5304 write_isoc_frame_data(core_if, ep);
5305 }
5306
5307 }
5308 #endif /* DWC_EN_ISOC */
5309
5310 static void dwc_otg_set_uninitialized(int32_t * p, int size)
5311 {
5312 int i;
5313 for (i = 0; i < size; i++) {
5314 p[i] = -1;
5315 }
5316 }
5317
5318 static int dwc_otg_param_initialized(int32_t val)
5319 {
5320 return val != -1;
5321 }
5322
5323 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
5324 {
5325 int i;
5326 core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
5327 if (!core_if->core_params) {
5328 return -DWC_E_NO_MEMORY;
5329 }
5330 dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
5331 sizeof(*core_if->core_params) /
5332 sizeof(int32_t));
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,
5382 i);
5383 }
5384
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,
5388 i);
5389 }
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");
5409
5410 return 0;
5411 }
5412
5413 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
5414 {
5415 return core_if->dma_enable;
5416 }
5417
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_)))
5422
5423 /* Parameter access functions */
5424 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
5425 {
5426 int valid;
5427 int retval = 0;
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;
5432 goto out;
5433 }
5434
5435 valid = 1;
5436 switch (val) {
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)
5440 valid = 0;
5441 break;
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)) {
5451 valid = 0;
5452 }
5453 break;
5454 case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
5455 /* always valid */
5456 break;
5457 }
5458 if (!valid) {
5459 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
5460 DWC_ERROR
5461 ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5462 val);
5463 }
5464 val =
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;
5476 }
5477
5478 core_if->core_params->otg_cap = val;
5479 out:
5480 return retval;
5481 }
5482
5483 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
5484 {
5485 return core_if->core_params->otg_cap;
5486 }
5487
5488 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
5489 {
5490 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5491 DWC_WARN("Wrong value for opt parameter\n");
5492 return -DWC_E_INVALID;
5493 }
5494 core_if->core_params->opt = val;
5495 return 0;
5496 }
5497
5498 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
5499 {
5500 return core_if->core_params->opt;
5501 }
5502
5503 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
5504 {
5505 int retval = 0;
5506 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5507 DWC_WARN("Wrong value for dma enable\n");
5508 return -DWC_E_INVALID;
5509 }
5510
5511 if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
5512 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
5513 DWC_ERROR
5514 ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5515 val);
5516 }
5517 val = 0;
5518 retval = -DWC_E_INVALID;
5519 }
5520
5521 core_if->core_params->dma_enable = val;
5522 if (val == 0) {
5523 dwc_otg_set_param_dma_desc_enable(core_if, 0);
5524 }
5525 return retval;
5526 }
5527
5528 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
5529 {
5530 return core_if->core_params->dma_enable;
5531 }
5532
5533 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
5534 {
5535 int retval = 0;
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;
5540 }
5541
5542 if ((val == 1)
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)) {
5547 DWC_ERROR
5548 ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5549 val);
5550 }
5551 val = 0;
5552 retval = -DWC_E_INVALID;
5553 }
5554 core_if->core_params->dma_desc_enable = val;
5555 return retval;
5556 }
5557
5558 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
5559 {
5560 return core_if->core_params->dma_desc_enable;
5561 }
5562
5563 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
5564 int32_t val)
5565 {
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;
5570 }
5571 core_if->core_params->host_support_fs_ls_low_power = val;
5572 return 0;
5573 }
5574
5575 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
5576 core_if)
5577 {
5578 return core_if->core_params->host_support_fs_ls_low_power;
5579 }
5580
5581 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
5582 int32_t val)
5583 {
5584 int retval = 0;
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;
5589 }
5590
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)) {
5594 DWC_ERROR
5595 ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
5596 val);
5597 }
5598 val = 0;
5599 retval = -DWC_E_INVALID;
5600 }
5601 core_if->core_params->enable_dynamic_fifo = val;
5602 return retval;
5603 }
5604
5605 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
5606 {
5607 return core_if->core_params->enable_dynamic_fifo;
5608 }
5609
5610 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5611 {
5612 int retval = 0;
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;
5617 }
5618
5619 if (val > core_if->hwcfg3.b.dfifo_depth) {
5620 if (dwc_otg_param_initialized
5621 (core_if->core_params->data_fifo_size)) {
5622 DWC_ERROR
5623 ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
5624 val);
5625 }
5626 val = core_if->hwcfg3.b.dfifo_depth;
5627 retval = -DWC_E_INVALID;
5628 }
5629
5630 core_if->core_params->data_fifo_size = val;
5631 return retval;
5632 }
5633
5634 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
5635 {
5636 return core_if->core_params->data_fifo_size;
5637 }
5638
5639 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5640 {
5641 int retval = 0;
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;
5646 }
5647
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);
5651 }
5652 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5653 retval = -DWC_E_INVALID;
5654 }
5655
5656 core_if->core_params->dev_rx_fifo_size = val;
5657 return retval;
5658 }
5659
5660 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
5661 {
5662 return core_if->core_params->dev_rx_fifo_size;
5663 }
5664
5665 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5666 int32_t val)
5667 {
5668 int retval = 0;
5669
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;
5674 }
5675
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)) {
5679 DWC_ERROR
5680 ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
5681 val);
5682 }
5683 val =
5684 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5685 16);
5686 retval = -DWC_E_INVALID;
5687 }
5688
5689 core_if->core_params->dev_nperio_tx_fifo_size = val;
5690 return retval;
5691 }
5692
5693 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5694 {
5695 return core_if->core_params->dev_nperio_tx_fifo_size;
5696 }
5697
5698 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
5699 int32_t val)
5700 {
5701 int retval = 0;
5702
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;
5707 }
5708
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)) {
5712 DWC_ERROR
5713 ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
5714 val);
5715 }
5716 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5717 retval = -DWC_E_INVALID;
5718 }
5719
5720 core_if->core_params->host_rx_fifo_size = val;
5721 return retval;
5722
5723 }
5724
5725 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
5726 {
5727 return core_if->core_params->host_rx_fifo_size;
5728 }
5729
5730 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5731 int32_t val)
5732 {
5733 int retval = 0;
5734
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;
5739 }
5740
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)) {
5744 DWC_ERROR
5745 ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
5746 val);
5747 }
5748 val =
5749 (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5750 16);
5751 retval = -DWC_E_INVALID;
5752 }
5753
5754 core_if->core_params->host_nperio_tx_fifo_size = val;
5755 return retval;
5756 }
5757
5758 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5759 {
5760 return core_if->core_params->host_nperio_tx_fifo_size;
5761 }
5762
5763 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5764 int32_t val)
5765 {
5766 int retval = 0;
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;
5771 }
5772
5773 if (val > ((core_if->hptxfsiz.d32) >> 16)) {
5774 if (dwc_otg_param_initialized
5775 (core_if->core_params->host_perio_tx_fifo_size)) {
5776 DWC_ERROR
5777 ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
5778 val);
5779 }
5780 val = (core_if->hptxfsiz.d32) >> 16;
5781 retval = -DWC_E_INVALID;
5782 }
5783
5784 core_if->core_params->host_perio_tx_fifo_size = val;
5785 return retval;
5786 }
5787
5788 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5789 {
5790 return core_if->core_params->host_perio_tx_fifo_size;
5791 }
5792
5793 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
5794 int32_t val)
5795 {
5796 int retval = 0;
5797
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;
5802 }
5803
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)) {
5807 DWC_ERROR
5808 ("%d invalid for max_transfer_size. Check HW configuration.\n",
5809 val);
5810 }
5811 val =
5812 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
5813 1);
5814 retval = -DWC_E_INVALID;
5815 }
5816
5817 core_if->core_params->max_transfer_size = val;
5818 return retval;
5819 }
5820
5821 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
5822 {
5823 return core_if->core_params->max_transfer_size;
5824 }
5825
5826 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
5827 {
5828 int retval = 0;
5829
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;
5834 }
5835
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)) {
5839 DWC_ERROR
5840 ("%d invalid for max_packet_count. Check HW configuration.\n",
5841 val);
5842 }
5843 val =
5844 ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
5845 retval = -DWC_E_INVALID;
5846 }
5847
5848 core_if->core_params->max_packet_count = val;
5849 return retval;
5850 }
5851
5852 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
5853 {
5854 return core_if->core_params->max_packet_count;
5855 }
5856
5857 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
5858 {
5859 int retval = 0;
5860
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;
5865 }
5866
5867 if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
5868 if (dwc_otg_param_initialized
5869 (core_if->core_params->host_channels)) {
5870 DWC_ERROR
5871 ("%d invalid for host_channels. Check HW configurations.\n",
5872 val);
5873 }
5874 val = (core_if->hwcfg2.b.num_host_chan + 1);
5875 retval = -DWC_E_INVALID;
5876 }
5877
5878 core_if->core_params->host_channels = val;
5879 return retval;
5880 }
5881
5882 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
5883 {
5884 return core_if->core_params->host_channels;
5885 }
5886
5887 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
5888 {
5889 int retval = 0;
5890
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;
5895 }
5896
5897 if (val > (core_if->hwcfg2.b.num_dev_ep)) {
5898 if (dwc_otg_param_initialized
5899 (core_if->core_params->dev_endpoints)) {
5900 DWC_ERROR
5901 ("%d invalid for dev_endpoints. Check HW configurations.\n",
5902 val);
5903 }
5904 val = core_if->hwcfg2.b.num_dev_ep;
5905 retval = -DWC_E_INVALID;
5906 }
5907
5908 core_if->core_params->dev_endpoints = val;
5909 return retval;
5910 }
5911
5912 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
5913 {
5914 return core_if->core_params->dev_endpoints;
5915 }
5916
5917 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
5918 {
5919 int retval = 0;
5920 int valid = 0;
5921
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;
5926 }
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))) {
5931 valid = 1;
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))) {
5935 valid = 1;
5936 } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
5937 (core_if->hwcfg2.b.fs_phy_type == 1)) {
5938 valid = 1;
5939 }
5940 if (!valid) {
5941 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
5942 DWC_ERROR
5943 ("%d invalid for phy_type. Check HW configurations.\n",
5944 val);
5945 }
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;
5950 } else {
5951 val = DWC_PHY_TYPE_PARAM_ULPI;
5952 }
5953 }
5954 retval = -DWC_E_INVALID;
5955 }
5956 #endif
5957 core_if->core_params->phy_type = val;
5958 return retval;
5959 }
5960
5961 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
5962 {
5963 return core_if->core_params->phy_type;
5964 }
5965
5966 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
5967 {
5968 int retval = 0;
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;
5973 }
5974 if ((val == 0)
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)) {
5977 DWC_ERROR
5978 ("%d invalid for speed paremter. Check HW configuration.\n",
5979 val);
5980 }
5981 val =
5982 (dwc_otg_get_param_phy_type(core_if) ==
5983 DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
5984 retval = -DWC_E_INVALID;
5985 }
5986 core_if->core_params->speed = val;
5987 return retval;
5988 }
5989
5990 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
5991 {
5992 return core_if->core_params->speed;
5993 }
5994
5995 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
5996 int32_t val)
5997 {
5998 int retval = 0;
5999
6000 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6001 DWC_WARN
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;
6005 }
6006
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)) {
6011 DWC_ERROR
6012 ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6013 val);
6014 }
6015 val =
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;
6021 }
6022
6023 core_if->core_params->host_ls_low_power_phy_clk = val;
6024 return retval;
6025 }
6026
6027 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
6028 {
6029 return core_if->core_params->host_ls_low_power_phy_clk;
6030 }
6031
6032 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
6033 {
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;
6038 }
6039
6040 core_if->core_params->phy_ulpi_ddr = val;
6041 return 0;
6042 }
6043
6044 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
6045 {
6046 return core_if->core_params->phy_ulpi_ddr;
6047 }
6048
6049 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
6050 int32_t val)
6051 {
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;
6056 }
6057
6058 core_if->core_params->phy_ulpi_ext_vbus = val;
6059 return 0;
6060 }
6061
6062 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
6063 {
6064 return core_if->core_params->phy_ulpi_ext_vbus;
6065 }
6066
6067 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
6068 {
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;
6073 }
6074
6075 core_if->core_params->phy_utmi_width = val;
6076 return 0;
6077 }
6078
6079 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
6080 {
6081 return core_if->core_params->phy_utmi_width;
6082 }
6083
6084 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
6085 {
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;
6090 }
6091
6092 core_if->core_params->ulpi_fs_ls = val;
6093 return 0;
6094 }
6095
6096 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
6097 {
6098 return core_if->core_params->ulpi_fs_ls;
6099 }
6100
6101 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
6102 {
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;
6107 }
6108
6109 core_if->core_params->ts_dline = val;
6110 return 0;
6111 }
6112
6113 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
6114 {
6115 return core_if->core_params->ts_dline;
6116 }
6117
6118 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
6119 {
6120 int retval = 0;
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;
6125 }
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)) {
6129 DWC_ERROR
6130 ("%d invalid for i2c_enable. Check HW configuration.\n",
6131 val);
6132 }
6133 val = 0;
6134 retval = -DWC_E_INVALID;
6135 }
6136 #endif
6137
6138 core_if->core_params->i2c_enable = val;
6139 return retval;
6140 }
6141
6142 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
6143 {
6144 return core_if->core_params->i2c_enable;
6145 }
6146
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)
6149 {
6150 int retval = 0;
6151
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;
6156 }
6157
6158 if (val >
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])) {
6162 DWC_ERROR
6163 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6164 val, fifo_num);
6165 }
6166 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
6167 retval = -DWC_E_INVALID;
6168 }
6169
6170 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
6171 return retval;
6172 }
6173
6174 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6175 int fifo_num)
6176 {
6177 return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
6178 }
6179
6180 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
6181 int32_t val)
6182 {
6183 int retval = 0;
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;
6188 }
6189
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)) {
6193 DWC_ERROR
6194 ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6195 val);
6196 }
6197 val = 0;
6198 retval = -DWC_E_INVALID;
6199 }
6200
6201 core_if->core_params->en_multiple_tx_fifo = val;
6202 return retval;
6203 }
6204
6205 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
6206 {
6207 return core_if->core_params->en_multiple_tx_fifo;
6208 }
6209
6210 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
6211 int fifo_num)
6212 {
6213 int retval = 0;
6214
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;
6219 }
6220
6221 if (val >
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])) {
6225 DWC_ERROR
6226 ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
6227 val, fifo_num);
6228 }
6229 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
6230 retval = -DWC_E_INVALID;
6231 }
6232
6233 core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
6234 return retval;
6235 }
6236
6237 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
6238 int fifo_num)
6239 {
6240 return core_if->core_params->dev_tx_fifo_size[fifo_num];
6241 }
6242
6243 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6244 {
6245 int retval = 0;
6246
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;
6251 }
6252
6253 if ((val != 0) &&
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)) {
6257 DWC_ERROR
6258 ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6259 val);
6260 }
6261 val = 0;
6262 retval = -DWC_E_INVALID;
6263 }
6264
6265 core_if->core_params->thr_ctl = val;
6266 return retval;
6267 }
6268
6269 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
6270 {
6271 return core_if->core_params->thr_ctl;
6272 }
6273
6274 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
6275 {
6276 int retval = 0;
6277
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;
6282 }
6283
6284 if (val && !core_if->hwcfg3.b.otg_lpm_en) {
6285 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
6286 DWC_ERROR
6287 ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6288 val);
6289 }
6290 val = 0;
6291 retval = -DWC_E_INVALID;
6292 }
6293
6294 core_if->core_params->lpm_enable = val;
6295 return retval;
6296 }
6297
6298 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
6299 {
6300 return core_if->core_params->lpm_enable;
6301 }
6302
6303 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6304 {
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;
6309 }
6310
6311 core_if->core_params->tx_thr_length = val;
6312 return 0;
6313 }
6314
6315 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
6316 {
6317 return core_if->core_params->tx_thr_length;
6318 }
6319
6320 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6321 {
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;
6326 }
6327
6328 core_if->core_params->rx_thr_length = val;
6329 return 0;
6330 }
6331
6332 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
6333 {
6334 return core_if->core_params->rx_thr_length;
6335 }
6336
6337 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
6338 {
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;
6349 }
6350 core_if->core_params->dma_burst_size = val;
6351 return 0;
6352 }
6353
6354 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
6355 {
6356 return core_if->core_params->dma_burst_size;
6357 }
6358
6359 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
6360 {
6361 int retval = 0;
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;
6365 }
6366 if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
6367 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
6368 DWC_ERROR
6369 ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6370 val);
6371 }
6372 retval = -DWC_E_INVALID;
6373 val = 0;
6374 }
6375 core_if->core_params->pti_enable = val;
6376 return retval;
6377 }
6378
6379 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
6380 {
6381 return core_if->core_params->pti_enable;
6382 }
6383
6384 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
6385 {
6386 int retval = 0;
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;
6390 }
6391 if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
6392 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
6393 DWC_ERROR
6394 ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6395 val);
6396 }
6397 retval = -DWC_E_INVALID;
6398 val = 0;
6399 }
6400 core_if->core_params->mpi_enable = val;
6401 return retval;
6402 }
6403
6404 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
6405 {
6406 return core_if->core_params->mpi_enable;
6407 }
6408
6409 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
6410 {
6411 int retval = 0;
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;
6415 }
6416 if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
6417 if (dwc_otg_param_initialized
6418 (core_if->core_params->adp_supp_enable)) {
6419 DWC_ERROR
6420 ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6421 val);
6422 }
6423 retval = -DWC_E_INVALID;
6424 val = 0;
6425 }
6426 core_if->core_params->adp_supp_enable = val;
6427 /*Set OTG version 2.0 in case of enabling ADP*/
6428 if (val)
6429 dwc_otg_set_param_otg_ver(core_if, 1);
6430
6431 return retval;
6432 }
6433
6434 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
6435 {
6436 return core_if->core_params->adp_supp_enable;
6437 }
6438
6439 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
6440 {
6441 int retval = 0;
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;
6446 }
6447
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)) {
6450 DWC_ERROR
6451 ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6452 val);
6453 }
6454 retval = -DWC_E_INVALID;
6455 val = 0;
6456 }
6457 core_if->core_params->ic_usb_cap = val;
6458 return retval;
6459 }
6460
6461 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
6462 {
6463 return core_if->core_params->ic_usb_cap;
6464 }
6465
6466 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
6467 {
6468 int retval = 0;
6469 int valid = 1;
6470
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;
6475 }
6476
6477 if (val
6478 && (core_if->snpsid < OTG_CORE_REV_2_81a
6479 || !dwc_otg_get_param_thr_ctl(core_if))) {
6480 valid = 0;
6481 } else if (val
6482 && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
6483 4)) {
6484 valid = 0;
6485 }
6486 if (valid == 0) {
6487 if (dwc_otg_param_initialized
6488 (core_if->core_params->ahb_thr_ratio)) {
6489 DWC_ERROR
6490 ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6491 val);
6492 }
6493 retval = -DWC_E_INVALID;
6494 val = 0;
6495 }
6496
6497 core_if->core_params->ahb_thr_ratio = val;
6498 return retval;
6499 }
6500
6501 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
6502 {
6503 return core_if->core_params->ahb_thr_ratio;
6504 }
6505
6506 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
6507 {
6508 int retval = 0;
6509 int valid = 1;
6510 hwcfg4_data_t hwcfg4 = {.d32 = 0 };
6511 hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
6512
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;
6517 }
6518
6519 if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
6520 valid = 0;
6521 }
6522 if ((val == 3)
6523 && ((core_if->snpsid < OTG_CORE_REV_3_00a)
6524 || (hwcfg4.b.xhiber == 0))) {
6525 valid = 0;
6526 }
6527 if (valid == 0) {
6528 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
6529 DWC_ERROR
6530 ("%d invalid for parameter power_down. Check HW configuration.\n",
6531 val);
6532 }
6533 retval = -DWC_E_INVALID;
6534 val = 0;
6535 }
6536 core_if->core_params->power_down = val;
6537 return retval;
6538 }
6539
6540 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
6541 {
6542 return core_if->core_params->power_down;
6543 }
6544
6545 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6546 {
6547 int retval = 0;
6548 int valid = 1;
6549
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;
6554 }
6555
6556 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
6557 valid = 0;
6558 }
6559 if (valid == 0) {
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);
6563 }
6564 retval = -DWC_E_INVALID;
6565 val = 0;
6566 }
6567 core_if->core_params->reload_ctl = val;
6568 return retval;
6569 }
6570
6571 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
6572 {
6573 return core_if->core_params->reload_ctl;
6574 }
6575
6576 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
6577 {
6578 int retval = 0;
6579 int valid = 1;
6580
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;
6585 }
6586
6587 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
6588 !(core_if->core_params->dma_desc_enable))) {
6589 valid = 0;
6590 }
6591 if (valid == 0) {
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);
6595 }
6596 retval = -DWC_E_INVALID;
6597 val = 0;
6598 }
6599 core_if->core_params->dev_out_nak = val;
6600 return retval;
6601 }
6602
6603 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
6604 {
6605 return core_if->core_params->dev_out_nak;
6606 }
6607
6608 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
6609 {
6610 int retval = 0;
6611 int valid = 1;
6612
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;
6617 }
6618
6619 if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
6620 !(core_if->core_params->dma_desc_enable))) {
6621 valid = 0;
6622 }
6623 if (valid == 0) {
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);
6627 }
6628 retval = -DWC_E_INVALID;
6629 val = 0;
6630 }
6631 core_if->core_params->cont_on_bna = val;
6632 return retval;
6633 }
6634
6635 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
6636 {
6637 return core_if->core_params->cont_on_bna;
6638 }
6639
6640 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
6641 {
6642 int retval = 0;
6643 int valid = 1;
6644
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;
6649 }
6650
6651 if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
6652 valid = 0;
6653 }
6654 if (valid == 0) {
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);
6658 }
6659 retval = -DWC_E_INVALID;
6660 val = 0;
6661 }
6662 core_if->core_params->ahb_single = val;
6663 return retval;
6664 }
6665
6666 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
6667 {
6668 return core_if->core_params->ahb_single;
6669 }
6670
6671 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
6672 {
6673 int retval = 0;
6674
6675 if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6676 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
6677 DWC_WARN
6678 ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
6679 return -DWC_E_INVALID;
6680 }
6681
6682 core_if->core_params->otg_ver = val;
6683 return retval;
6684 }
6685
6686 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
6687 {
6688 return core_if->core_params->otg_ver;
6689 }
6690
6691 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
6692 {
6693 gotgctl_data_t otgctl;
6694 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6695 return otgctl.b.hstnegscs;
6696 }
6697
6698 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
6699 {
6700 gotgctl_data_t otgctl;
6701 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6702 return otgctl.b.sesreqscs;
6703 }
6704
6705 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
6706 {
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);
6712 } else {
6713 core_if->otg_sts = val;
6714 }
6715 }
6716
6717 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
6718 {
6719 return core_if->snpsid;
6720 }
6721
6722 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
6723 {
6724 gintsts_data_t gintsts;
6725 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6726 return gintsts.b.curmode;
6727 }
6728
6729 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
6730 {
6731 gusbcfg_data_t usbcfg;
6732 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6733 return usbcfg.b.hnpcap;
6734 }
6735
6736 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6737 {
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);
6742 }
6743
6744 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
6745 {
6746 gusbcfg_data_t usbcfg;
6747 usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6748 return usbcfg.b.srpcap;
6749 }
6750
6751 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6752 {
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);
6757 }
6758
6759 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
6760 {
6761 dcfg_data_t dcfg;
6762 /* originally: dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg); */
6763
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");
6778 else {
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);
6785 }
6786 return dcfg.b.devspd;
6787 }
6788
6789 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
6790 {
6791 dcfg_data_t dcfg;
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);
6795 }
6796
6797 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
6798 {
6799 hprt0_data_t hprt0;
6800 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6801 return hprt0.b.prtconnsts;
6802 }
6803
6804 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
6805 {
6806 dsts_data_t dsts;
6807 dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
6808 return dsts.b.enumspd;
6809 }
6810
6811 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
6812 {
6813 hprt0_data_t hprt0;
6814 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6815 return hprt0.b.prtpwr;
6816
6817 }
6818
6819 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
6820 {
6821 return core_if->hibernation_suspend;
6822 }
6823
6824 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
6825 {
6826 hprt0_data_t hprt0;
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);
6830 }
6831
6832 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
6833 {
6834 hprt0_data_t hprt0;
6835 hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6836 return hprt0.b.prtsusp;
6837
6838 }
6839
6840 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
6841 {
6842 hprt0_data_t hprt0;
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);
6846 }
6847
6848 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
6849 {
6850 hfir_data_t hfir;
6851 hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6852 return hfir.b.frint;
6853
6854 }
6855
6856 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
6857 {
6858 hfir_data_t hfir;
6859 uint32_t fram_int;
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");
6866 return;
6867 }
6868 switch (fram_int) {
6869 case 3750:
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");
6873 return;
6874 }
6875 break;
6876 case 30000:
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");
6880 return;
6881 }
6882 break;
6883 case 6000:
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");
6887 return;
6888 }
6889 break;
6890 case 48000:
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");
6894 return;
6895 }
6896 break;
6897 case 7500:
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");
6901 return;
6902 }
6903 break;
6904 case 60000:
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");
6908 return;
6909 }
6910 break;
6911 default:
6912 DWC_WARN("Unknown frame interval\n");
6913 return;
6914 break;
6915
6916 }
6917 hfir.b.frint = val;
6918 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
6919 }
6920
6921 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
6922 {
6923 hcfg_data_t hcfg;
6924 hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
6925 return hcfg.b.modechtimen;
6926
6927 }
6928
6929 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
6930 {
6931 hcfg_data_t hcfg;
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);
6935 }
6936
6937 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
6938 {
6939 hprt0_data_t hprt0;
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);
6943 }
6944
6945 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
6946 {
6947 dctl_data_t dctl;
6948 dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
6949 return dctl.b.rmtwkupsig;
6950 }
6951
6952 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
6953 {
6954 glpmcfg_data_t lpmcfg;
6955 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6956
6957 DWC_ASSERT(!
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);
6961
6962 return lpmcfg.b.prt_sleep_sts;
6963 }
6964
6965 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
6966 {
6967 glpmcfg_data_t lpmcfg;
6968 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6969 return lpmcfg.b.rem_wkup_en;
6970 }
6971
6972 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
6973 {
6974 glpmcfg_data_t lpmcfg;
6975 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6976 return lpmcfg.b.appl_resp;
6977 }
6978
6979 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
6980 {
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);
6985 }
6986
6987 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
6988 {
6989 glpmcfg_data_t lpmcfg;
6990 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
6991 return lpmcfg.b.hsic_connect;
6992 }
6993
6994 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
6995 {
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);
7000 }
7001
7002 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
7003 {
7004 glpmcfg_data_t lpmcfg;
7005 lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7006 return lpmcfg.b.inv_sel_hsic;
7007
7008 }
7009
7010 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
7011 {
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);
7016 }
7017
7018 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
7019 {
7020 return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7021 }
7022
7023 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
7024 {
7025 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
7026 }
7027
7028 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
7029 {
7030 return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7031 }
7032
7033 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
7034 {
7035 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
7036 }
7037
7038 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
7039 {
7040 return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
7041 }
7042
7043 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7044 {
7045 DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
7046 }
7047
7048 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
7049 {
7050 return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
7051 }
7052
7053 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7054 {
7055 DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
7056 }
7057
7058 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
7059 {
7060 return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
7061 }
7062
7063 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
7064 {
7065 DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
7066 }
7067
7068 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
7069 {
7070 return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
7071 }
7072
7073 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
7074 {
7075 DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
7076 }
7077
7078 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
7079 {
7080 return DWC_READ_REG32(core_if->host_if->hprt0);
7081
7082 }
7083
7084 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
7085 {
7086 DWC_WRITE_REG32(core_if->host_if->hprt0, val);
7087 }
7088
7089 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
7090 {
7091 return DWC_READ_REG32(&core_if->core_global_regs->guid);
7092 }
7093
7094 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
7095 {
7096 DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
7097 }
7098
7099 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
7100 {
7101 return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
7102 }
7103
7104 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
7105 {
7106 return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7107 }
7108
7109 /**
7110 * Start the SRP timer to detect when the SRP does not complete within
7111 * 6 seconds.
7112 *
7113 * @param core_if the pointer to core_if strucure.
7114 */
7115 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
7116 {
7117 core_if->srp_timer_started = 1;
7118 DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
7119 }
7120
7121 void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if)
7122 {
7123 uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
7124 gotgctl_data_t mem;
7125 gotgctl_data_t val;
7126
7127 val.d32 = DWC_READ_REG32(addr);
7128 if (val.b.sesreq) {
7129 DWC_ERROR("Session Request Already active!\n");
7130 return;
7131 }
7132
7133 DWC_INFO("Session Request Initated\n"); //NOTICE
7134 mem.d32 = DWC_READ_REG32(addr);
7135 mem.b.sesreq = 1;
7136 DWC_WRITE_REG32(addr, mem.d32);
7137
7138 /* Start the SRP timer */
7139 dwc_otg_pcd_start_srp_timer(core_if);
7140 return;
7141 }