tizen 2.4 release
[kernel/u-boot-tm1.git] / drivers / usb / gadget / dwc_otg / dwc_otg_cil.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
3  * $Revision: #154 $
4  * $Date: 2009/02/05 $
5  * $Change: 1180783 $
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 #define VERBOSE //sword
60 #include "dwc_os.h"
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
63
64 static int in_calibration = 0;
65 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
66
67 void usb_in_cal(int flag)
68 {
69         if(flag){
70                 in_calibration = 1;
71         }else{
72                 in_calibration = 0;
73         }
74 }
75 /**
76  * This function is called to initialize the DWC_otg CSR data
77  * structures.  The register addresses in the device and host
78  * structures are initialized from the base address supplied by the
79  * caller.      The calling function must make the OS calls to get the
80  * base address of the DWC_otg controller registers.  The core_params
81  * argument holds the parameters that specify how the core should be
82  * configured.
83  *
84  * @param[in] reg_base_addr Base address of DWC_otg core registers
85  *
86  */
87 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
88 {
89         dwc_otg_core_if_t *core_if = 0;
90         dwc_otg_dev_if_t *dev_if = 0;
91         dwc_otg_host_if_t *host_if = 0;
92         uint8_t *reg_base = (uint8_t *) reg_base_addr;
93         int i = 0;
94
95         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
96
97         core_if = dwc_alloc(sizeof(dwc_otg_core_if_t));
98
99         if (core_if == 0) {
100                 DWC_DEBUGPL(DBG_CIL,
101                             "Allocation of dwc_otg_core_if_t failed\n");
102                 return 0;
103         }
104         core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
105
106         /*
107          * Allocate the Device Mode structures.
108          */
109         dev_if = dwc_alloc(sizeof(dwc_otg_dev_if_t));
110
111         if (dev_if == 0) {
112                 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
113                 dwc_free(core_if);
114                 return 0;
115         }
116
117         dev_if->dev_global_regs =
118             (dwc_otg_device_global_regs_t *) (reg_base +
119                                               DWC_DEV_GLOBAL_REG_OFFSET);
120
121         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
122                 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
123                     (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
124                      (i * DWC_EP_REG_OFFSET));
125
126                 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
127                     (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
128                      (i * DWC_EP_REG_OFFSET));
129                 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
130                             i, &dev_if->in_ep_regs[i]->diepctl);
131                 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
132                             i, &dev_if->out_ep_regs[i]->doepctl);
133         }
134
135         dev_if->speed = 0;      // unknown
136
137         core_if->dev_if = dev_if;
138
139         /*
140          * Allocate the Host Mode structures.
141          */
142         host_if = dwc_alloc(sizeof(dwc_otg_host_if_t));
143
144         if (host_if == 0) {
145                 DWC_DEBUGPL(DBG_CIL,
146                             "Allocation of dwc_otg_host_if_t failed\n");
147                 dwc_free(dev_if);
148                 dwc_free(core_if);
149                 return 0;
150         }
151
152         host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
153             (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
154
155         host_if->hprt0 =
156             (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
157
158         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
159                 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
160                     (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
161                      (i * DWC_OTG_CHAN_REGS_OFFSET));
162                 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
163                             i, &host_if->hc_regs[i]->hcchar);
164         }
165
166         host_if->num_host_channels = MAX_EPS_CHANNELS;
167         core_if->host_if = host_if;
168
169         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
170                 core_if->data_fifo[i] =
171                     (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
172                                   (i * DWC_OTG_DATA_FIFO_SIZE));
173                 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08x\n",
174                             i, (unsigned)core_if->data_fifo[i]);
175         }
176
177         core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
178
179         /* Initiate lx_state to L3 disconnected state */
180         core_if->lx_state = DWC_OTG_L3;
181         /*
182          * Store the contents of the hardware configuration registers here for
183          * easy access later.
184          */
185         core_if->hwcfg1.d32 =
186             dwc_read_reg32(&core_if->core_global_regs->ghwcfg1);
187         core_if->hwcfg2.d32 =
188             dwc_read_reg32(&core_if->core_global_regs->ghwcfg2);
189         core_if->hwcfg3.d32 =
190             dwc_read_reg32(&core_if->core_global_regs->ghwcfg3);
191         core_if->hwcfg4.d32 =
192             dwc_read_reg32(&core_if->core_global_regs->ghwcfg4);
193
194         DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
195         DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
196         DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
197         DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
198
199         core_if->hcfg.d32 =
200             dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
201         core_if->dcfg.d32 =
202             dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
203
204         DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
205         DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
206
207         DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
208         DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
209         DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
210         DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
211                     core_if->hwcfg2.b.num_host_chan);
212         DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
213                     core_if->hwcfg2.b.nonperio_tx_q_depth);
214         DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
215                     core_if->hwcfg2.b.host_perio_tx_q_depth);
216         DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
217                     core_if->hwcfg2.b.dev_token_q_depth);
218
219         DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
220                     core_if->hwcfg3.b.dfifo_depth);
221         DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
222                     core_if->hwcfg3.b.xfer_size_cntr_width);
223
224         /*
225          * Set the SRP sucess bit for FS-I2c
226          */
227         core_if->srp_success = 0;
228         core_if->srp_timer_started = 0;
229
230 #if 0
231         /*
232          * Create new workqueue and init works
233          */
234         core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
235         if (core_if->wq_otg == 0) {
236                 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
237                 dwc_free(host_if);
238                 dwc_free(dev_if);
239                 dwc_free(core_if);
240                 return 0;
241         }
242 #endif
243         core_if->snpsid = dwc_read_reg32(&core_if->core_global_regs->gsnpsid);
244
245         DWC_DEBUGPL(DBG_CIL,"Core Release: %x.%x%x%x\n",
246                    (core_if->snpsid >> 12 & 0xF),
247                    (core_if->snpsid >> 8 & 0xF),
248                    (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
249
250 #if 0
251         core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
252                                              w_wakeup_detected, core_if);
253         if (core_if->wkp_timer == 0) {
254                 DWC_WARN("DWC_TIMER_ALLOC failed\n");
255                 dwc_free(host_if);
256                 dwc_free(dev_if);
257                 DWC_WORKQ_FREE(core_if->wq_otg);
258                 dwc_free(core_if);
259                 return 0;
260         }
261 #endif
262         if (dwc_otg_setup_params(core_if)) {
263                 DWC_WARN("Error while setting core params\n");
264         }
265
266         return core_if;
267 }
268
269 /**
270  * This function frees the structures allocated by dwc_otg_cil_init().
271  *
272  * @param[in] core_if The core interface pointer returned from
273  * dwc_otg_cil_init().
274  *
275  */
276 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
277 {
278         /* Disable all interrupts */
279         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
280         dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
281
282 /*
283         if (core_if->wq_otg) {
284                 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
285                 DWC_WORKQ_FREE(core_if->wq_otg);
286         }
287 */
288         if (core_if->dev_if) {
289                 dwc_free(core_if->dev_if);
290         }
291         if (core_if->host_if) {
292                 dwc_free(core_if->host_if);
293         }
294         DWC_TIMER_FREE(core_if->wkp_timer);
295         DWC_FREE(core_if->core_params);
296        dwc_free(core_if);
297 }
298
299 /**
300  * This function enables the controller's Global Interrupt in the AHB Config
301  * register.
302  *
303  * @param[in] core_if Programming view of DWC_otg controller.
304  */
305 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
306 {
307         gahbcfg_data_t ahbcfg = {.d32 = 0 };
308         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
309         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
310 }
311
312 /**
313  * This function disables the controller's Global Interrupt in the AHB Config
314  * register.
315  *
316  * @param[in] core_if Programming view of DWC_otg controller.
317  */
318 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
319 {
320         gahbcfg_data_t ahbcfg = {.d32 = 0 };
321         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
322         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
323 }
324
325 /**
326  * This function initializes the commmon interrupts, used in both
327  * device and host modes.
328  *
329  * @param[in] core_if Programming view of the DWC_otg controller
330  *
331  */
332 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
333 {
334         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
335         gintmsk_data_t intr_mask = {.d32 = 0 };
336
337         /* Clear any pending OTG Interrupts */
338         dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
339
340         /* Clear any pending interrupts */
341         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
342
343         /*
344          * Enable the interrupts in the GINTMSK.
345          */
346         intr_mask.b.modemismatch = 1;
347         intr_mask.b.otgintr = 1;
348
349         if (!core_if->dma_enable) {
350                 intr_mask.b.rxstsqlvl = 1;
351         }
352
353         intr_mask.b.conidstschng = 1;
354         intr_mask.b.wkupintr = 1;
355         intr_mask.b.disconnect = 1;
356         intr_mask.b.usbsuspend = 1;
357         intr_mask.b.sessreqintr = 1;
358 #ifdef CONFIG_USB_DWC_OTG_LPM
359         if (core_if->core_params->lpm_enable) {
360                 intr_mask.b.lpmtranrcvd = 1;
361         }
362 #endif
363         dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
364 }
365
366 /**
367  * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
368  * type.
369  */
370 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
371 {
372         uint32_t val;
373         hcfg_data_t hcfg;
374
375         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
376              (core_if->hwcfg2.b.fs_phy_type == 1) &&
377              (core_if->core_params->ulpi_fs_ls)) ||
378             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
379                 /* Full speed PHY */
380                 val = DWC_HCFG_48_MHZ;
381         } else {
382                 /* High speed PHY running at full speed or high speed */
383                 val = DWC_HCFG_30_60_MHZ;
384         }
385
386         DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
387         hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
388         hcfg.b.fslspclksel = val;
389         dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
390 }
391
392 /**
393  * Initializes the DevSpd field of the DCFG register depending on the PHY type
394  * and the enumeration speed of the device.
395  */
396 static void init_devspd(dwc_otg_core_if_t * core_if)
397 {
398         uint32_t val;
399         dcfg_data_t dcfg;
400
401         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
402              (core_if->hwcfg2.b.fs_phy_type == 1) &&
403              (core_if->core_params->ulpi_fs_ls)) ||
404             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
405                 /* Full speed PHY */
406                 val = 0x3;
407         } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
408                 /* High speed PHY running at full speed */
409                 val = 0x1;
410         } else {
411                 /* High speed PHY running at high speed */
412                 val = 0x0;
413         }
414
415         if(in_calibration) //force full speed in calibration
416                 val = 0x1;
417
418         DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
419
420         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
421         dcfg.b.devspd = val;
422         dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
423 }
424
425 /**
426  * This function calculates the number of IN EPS
427  * using GHWCFG1 and GHWCFG2 registers values
428  *
429  * @param core_if Programming view of the DWC_otg controller
430  */
431 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
432 {
433         uint32_t num_in_eps = 0;
434         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
435         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
436         uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
437         int i;
438
439         for (i = 0; i < num_eps; ++i) {
440                 if (!(hwcfg1 & 0x1))
441                         num_in_eps++;
442
443                 hwcfg1 >>= 2;
444         }
445
446         /*
447          * the dedicate fifo maybe less than number of IN eps, but our
448          * composite usb function normally won't use all dedicated fifo,
449          * so, just let allocate more the IN eps. Sword,
450          */
451         #if 0
452         if (core_if->hwcfg4.b.ded_fifo_en) {
453                 num_in_eps =
454                     (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
455         }
456         #endif
457
458         return num_in_eps;
459 }
460
461 /**
462  * This function calculates the number of OUT EPS
463  * using GHWCFG1 and GHWCFG2 registers values
464  *
465  * @param core_if Programming view of the DWC_otg controller
466  */
467 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
468 {
469         uint32_t num_out_eps = 0;
470         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
471         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
472         int i;
473
474         for (i = 0; i < num_eps; ++i) {
475                 if (!(hwcfg1 & 0x1))
476                         num_out_eps++;
477
478                 hwcfg1 >>= 2;
479         }
480         return num_out_eps;
481 }
482
483 /**
484  * This function initializes the DWC_otg controller registers and
485  * prepares the core for device mode or host mode operation.
486  *
487  * @param core_if Programming view of the DWC_otg controller
488  *
489  */
490 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
491 {
492         int i = 0;
493         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
494         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
495         gahbcfg_data_t ahbcfg = {.d32 = 0 };
496         gusbcfg_data_t usbcfg = {.d32 = 0 };
497         gi2cctl_data_t i2cctl = {.d32 = 0 };
498
499         DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
500
501         /* Common Initialization */
502
503         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
504
505         /* Program the ULPI External VBUS bit if needed */
506         usbcfg.b.ulpi_ext_vbus_drv =
507             (core_if->core_params->phy_ulpi_ext_vbus ==
508              DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
509
510         /* Set external TS Dline pulsing */
511         usbcfg.b.term_sel_dl_pulse =
512             (core_if->core_params->ts_dline == 1) ? 1 : 0;
513         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
514
515         /* Reset the Controller */
516         dwc_otg_core_reset(core_if);
517
518         /* Initialize parameters from Hardware configuration registers. */
519         dev_if->num_in_eps = calc_num_in_eps(core_if);
520         dev_if->num_out_eps = calc_num_out_eps(core_if);
521
522         DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
523                     core_if->hwcfg4.b.num_dev_perio_in_ep);
524
525         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
526                 dev_if->perio_tx_fifo_size[i] =
527                     dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
528                 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
529                             i, dev_if->perio_tx_fifo_size[i]);
530         }
531
532         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
533                 dev_if->tx_fifo_size[i] =
534                     dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
535                 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
536                             i, dev_if->perio_tx_fifo_size[i]);
537         }
538
539         core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
540         core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
541         core_if->nperio_tx_fifo_size =
542             dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
543
544         DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
545         DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
546         DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
547                     core_if->nperio_tx_fifo_size);
548
549         /* This programming sequence needs to happen in FS mode before any other
550          * programming occurs */
551         if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
552             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
553                 /* If FS mode with FS PHY */
554
555                 /* core_init() is now called on every switch so only call the
556                  * following for the first time through. */
557                 //if (!core_if->phy_init_done) {
558                 //      core_if->phy_init_done = 1;
559                         DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
560                         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
561                         usbcfg.b.physel = 1;
562                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
563
564                         /* Reset after a PHY select */
565                         dwc_otg_core_reset(core_if);
566                 //}
567
568                 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
569                  * do this on HNP Dev/Host mode switches (done in dev_init and
570                  * host_init). */
571                 if (dwc_otg_is_host_mode(core_if)) {
572                         init_fslspclksel(core_if);
573                 } else {
574                         init_devspd(core_if);
575                 }
576
577                 if (core_if->core_params->i2c_enable) {
578                         DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
579                         /* Program GUSBCFG.OtgUtmifsSel to I2C */
580                         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
581                         usbcfg.b.otgutmifssel = 1;
582                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
583
584                         /* Program GI2CCTL.I2CEn */
585                         i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
586                         i2cctl.b.i2cdevaddr = 1;
587                         i2cctl.b.i2cen = 0;
588                         dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
589                         i2cctl.b.i2cen = 1;
590                         dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
591                 }
592
593         } /* endif speed == DWC_SPEED_PARAM_FULL */
594         else {
595                 //sword
596                 /* High speed PHY. */
597                 /* re set phy anyway sword*/
598                 //if (!core_if->phy_init_done) {
599                 //core_if->phy_init_done = 1;
600                         /* HS PHY parameters.  These parameters are preserved
601                          * during soft reset so only program the first time.  Do
602                          * a soft reset immediately after setting phyif.  */
603                         usbcfg.b.ulpi_utmi_sel = core_if->core_params->phy_type;
604                         /* UTMI+ interface */
605                         if (core_if->core_params->phy_utmi_width == 16) {
606                                 usbcfg.b.phyif = 1;
607
608                         } else {
609                                 usbcfg.b.phyif = 0;
610                         }
611                         usbcfg.b.ulpi_utmi_sel = 0;
612
613                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
614                         /* Reset after setting the PHY parameters */
615                         dwc_otg_core_reset(core_if);
616                 //}
617         }
618
619         if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
620             (core_if->hwcfg2.b.fs_phy_type == 1) &&
621             (core_if->core_params->ulpi_fs_ls)) {
622                 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
623                 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
624                 usbcfg.b.ulpi_fsls = 1;
625                 usbcfg.b.ulpi_clk_sus_m = 1;
626                 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
627         } else {
628                 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
629                 usbcfg.b.ulpi_fsls = 0;
630                 usbcfg.b.ulpi_clk_sus_m = 0;
631                 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
632         }
633
634         /* Program the GAHBCFG Register. */
635         switch (core_if->hwcfg2.b.architecture) {
636
637         case DWC_SLAVE_ONLY_ARCH:
638                 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
639                 ahbcfg.b.nptxfemplvl_txfemplvl =
640                     DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
641                 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
642                 core_if->dma_enable = 0;
643                 core_if->dma_desc_enable = 0;
644                 break;
645
646         case DWC_EXT_DMA_ARCH:
647                 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
648                 {
649                         uint8_t brst_sz = core_if->core_params->dma_burst_size;
650                         ahbcfg.b.hburstlen = 0;
651                         while (brst_sz > 1) {
652                                 ahbcfg.b.hburstlen++;
653                                 brst_sz >>= 1;
654                         }
655                 }
656                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
657                 core_if->dma_desc_enable =
658                     (core_if->core_params->dma_desc_enable != 0);
659                 break;
660
661         case DWC_INT_DMA_ARCH:
662                 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
663                 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
664                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
665                 core_if->dma_desc_enable =
666                     (core_if->core_params->dma_desc_enable != 0);
667                 break;
668
669         }
670         if (core_if->dma_enable) {
671                 if (core_if->dma_desc_enable) {
672                         DWC_DEBUGPL(DBG_CIL,"Using Descriptor DMA mode\n");
673                 } else {
674                         DWC_DEBUGPL(DBG_CIL,"Using Buffer DMA mode\n");
675
676                 }
677         } else {
678                 DWC_DEBUGPL(DBG_CIL,"Using Slave mode\n");
679         }
680         ahbcfg.b.dmaenable = core_if->dma_enable;
681         dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
682
683         core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
684
685         core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
686         core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
687         DWC_DEBUGPL(DBG_CIL,"Periodic Transfer Interrupt Enhancement - %s\n",
688                    ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
689         DWC_DEBUGPL(DBG_CIL,"Multiprocessor Interrupt Enhancement - %s\n",
690                    ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
691
692         /*
693          * Program the GUSBCFG register.
694          */
695         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
696
697         switch (core_if->hwcfg2.b.op_mode) {
698         case DWC_MODE_HNP_SRP_CAPABLE:
699                 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
700                                    DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
701                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
702                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
703                 break;
704
705         case DWC_MODE_SRP_ONLY_CAPABLE:
706                 usbcfg.b.hnpcap = 0;
707                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
708                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
709                 break;
710
711         case DWC_MODE_NO_HNP_SRP_CAPABLE:
712                 usbcfg.b.hnpcap = 0;
713                 usbcfg.b.srpcap = 0;
714                 break;
715
716         case DWC_MODE_SRP_CAPABLE_DEVICE:
717                 usbcfg.b.hnpcap = 0;
718                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
719                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
720                 break;
721
722         case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
723                 usbcfg.b.hnpcap = 0;
724                 usbcfg.b.srpcap = 0;
725                 break;
726
727         case DWC_MODE_SRP_CAPABLE_HOST:
728                 usbcfg.b.hnpcap = 0;
729                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
730                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
731                 break;
732
733         case DWC_MODE_NO_SRP_CAPABLE_HOST:
734                 usbcfg.b.hnpcap = 0;
735                 usbcfg.b.srpcap = 0;
736                 break;
737         }
738
739         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
740
741 #ifdef CONFIG_USB_DWC_OTG_LPM
742         if (core_if->core_params->lpm_enable) {
743                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
744
745                 /* To enable LPM support set lpm_cap_en bit */
746                 lpmcfg.b.lpm_cap_en = 1;
747
748                 /* Make AppL1Res ACK */
749                 lpmcfg.b.appl_resp = 1;
750
751                 /* Retry 3 times */
752                 lpmcfg.b.retry_count = 3;
753
754                 dwc_modify_reg32(&core_if->core_global_regs->glpmcfg,
755                                  0, lpmcfg.d32);
756
757         }
758 #endif
759         if (core_if->core_params->ic_usb_cap) {
760                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
761                 gusbcfg.b.ic_usb_cap = 1;
762                 dwc_modify_reg32(&core_if->core_global_regs->gusbcfg,
763                                  0, gusbcfg.d32);
764         }
765
766         /* Enable common interrupts */
767         dwc_otg_enable_common_interrupts(core_if);
768
769         /* Do device or host intialization based on mode during PCD
770          * and HCD initialization  */
771         if (dwc_otg_is_host_mode(core_if)) {
772                 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
773                 core_if->op_state = A_HOST;
774         } else {
775                 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
776                 core_if->op_state = B_PERIPHERAL;
777 #ifdef DWC_DEVICE_ONLY
778                 dwc_otg_core_dev_init(core_if);
779 #endif
780         }
781 }
782
783 /**
784  * This function enables the Device mode interrupts.
785  *
786  * @param core_if Programming view of DWC_otg controller
787  */
788 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
789 {
790         gintmsk_data_t intr_mask = {.d32 = 0 };
791         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
792
793         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
794
795         /* Disable all interrupts. */
796         dwc_write_reg32(&global_regs->gintmsk, 0);
797
798         /* Clear any pending interrupts */
799         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
800
801         /* Enable the common interrupts */
802         dwc_otg_enable_common_interrupts(core_if);
803
804         /* Enable interrupts */
805         intr_mask.b.usbreset = 1;
806         intr_mask.b.enumdone = 1;
807
808         if (!core_if->multiproc_int_enable) {
809                 intr_mask.b.inepintr = 1;
810                 intr_mask.b.outepintr = 1;
811         }
812
813         intr_mask.b.erlysuspend = 1;
814
815         if (core_if->en_multiple_tx_fifo == 0) {
816                 intr_mask.b.epmismatch = 1;
817         }
818 #ifdef DWC_EN_ISOC
819         if (core_if->dma_enable) {
820                 if (core_if->dma_desc_enable == 0) {
821                         if (core_if->pti_enh_enable) {
822                                 dctl_data_t dctl = {.d32 = 0 };
823                                 dctl.b.ifrmnum = 1;
824                                 dwc_modify_reg32(&core_if->dev_if->
825                                                  dev_global_regs->dctl, 0,
826                                                  dctl.d32);
827                         } else {
828                                 intr_mask.b.incomplisoin = 1;
829                                 intr_mask.b.incomplisoout = 1;
830                         }
831                 }
832         } else {
833                 intr_mask.b.incomplisoin = 1;
834                 intr_mask.b.incomplisoout = 1;
835         }
836 #endif                          /* DWC_EN_ISOC */
837
838         /** @todo NGS: Should this be a module parameter? */
839 #ifdef USE_PERIODIC_EP
840         intr_mask.b.isooutdrop = 1;
841         intr_mask.b.eopframe = 1;
842         intr_mask.b.incomplisoin = 1;
843         intr_mask.b.incomplisoout = 1;
844 #endif
845
846         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
847
848         DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
849                     dwc_read_reg32(&global_regs->gintmsk));
850 }
851
852 /**
853  * This function initializes the DWC_otg controller registers for
854  * device mode.
855  *
856  * @param core_if Programming view of DWC_otg controller
857  *
858  */
859 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
860 {
861         int i;
862         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
863         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
864         dwc_otg_core_params_t *params = core_if->core_params;
865         dcfg_data_t dcfg = {.d32 = 0 };
866         dctl_data_t dctl = {.d32 = 0 };
867         grstctl_t resetctl = {.d32 = 0 };
868         uint32_t rx_fifo_size;
869         fifosize_data_t nptxfifosize;
870         fifosize_data_t txfifosize;
871         dthrctl_data_t dthrctl;
872         fifosize_data_t ptxfifosize;
873
874         /* Restart the Phy Clock */
875         dwc_write_reg32(core_if->pcgcctl, 0);
876 #ifdef CONFIG_USB_CORE_IP_293A
877         dctl.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dctl);
878         dctl.b.sftdiscon = 0;
879         dwc_write_reg32(&dev_if->dev_global_regs->dctl, dctl.d32);
880 #endif
881         /* Device configuration register */
882         init_devspd(core_if);
883         dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
884         dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
885         dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
886         dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
887
888         /* Configure data FIFO sizes */
889         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
890                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
891                             core_if->total_fifo_size);
892                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
893                             params->dev_rx_fifo_size);
894                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
895                             params->dev_nperio_tx_fifo_size);
896
897                 /* Rx FIFO */
898                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
899                             dwc_read_reg32(&global_regs->grxfsiz));
900
901 #ifdef DWC_UTE_CFI
902                 core_if->pwron_rxfsiz = dwc_read_reg32(&global_regs->grxfsiz);
903                 core_if->init_rxfsiz = params->dev_rx_fifo_size;
904 #endif
905                 rx_fifo_size = params->dev_rx_fifo_size;
906                 dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
907
908                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
909                             dwc_read_reg32(&global_regs->grxfsiz));
910
911                 /** Set Periodic Tx FIFO Mask all bits 0 */
912                 core_if->p_tx_msk = 0;
913
914 #if defined( CONFIG_SC8830) || defined(CONFIG_SC9630)
915                 /**fisrt 3 txfifos are 0x40 in shark, tooo small, don't use them*/
916                 core_if->tx_msk = 7;
917 #else
918                 /** Set Tx FIFO Mask all bits 0 */
919                 core_if->tx_msk = 0;
920 #endif
921
922                 if (core_if->en_multiple_tx_fifo == 0) {
923                         /* Non-periodic Tx FIFO */
924                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
925                                     dwc_read_reg32(&global_regs->gnptxfsiz));
926
927                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
928                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
929
930                         dwc_write_reg32(&global_regs->gnptxfsiz,
931                                         nptxfifosize.d32);
932
933                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
934                                     dwc_read_reg32(&global_regs->gnptxfsiz));
935
936                         /**@todo NGS: Fix Periodic FIFO Sizing! */
937                         /*
938                          * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
939                          * Indexes of the FIFO size module parameters in the
940                          * dev_perio_tx_fifo_size array and the FIFO size registers in
941                          * the dptxfsiz array run from 0 to 14.
942                          */
943                         /** @todo Finish debug of this */
944                         ptxfifosize.b.startaddr =
945                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
946                         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep;
947                              i++) {
948                                 ptxfifosize.b.depth =
949                                     params->dev_perio_tx_fifo_size[i];
950                                 DWC_DEBUGPL(DBG_CIL,
951                                             "initial dptxfsiz_dieptxf[%d]=%08x\n",
952                                             i,
953                                             dwc_read_reg32(&global_regs->
954                                                            dptxfsiz_dieptxf
955                                                            [i]));
956                                 dwc_write_reg32(&global_regs->
957                                                 dptxfsiz_dieptxf[i],
958                                                 ptxfifosize.d32);
959                                 DWC_DEBUGPL(DBG_CIL,
960                                             "new dptxfsiz_dieptxf[%d]=%08x\n",
961                                             i,
962                                             dwc_read_reg32(&global_regs->
963                                                            dptxfsiz_dieptxf
964                                                            [i]));
965                                 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
966                         }
967                 } else {
968                         /*
969                          * Tx FIFOs These FIFOs are numbered from 1 to 15.
970                          * Indexes of the FIFO size module parameters in the
971                          * dev_tx_fifo_size array and the FIFO size registers in
972                          * the dptxfsiz_dieptxf array run from 0 to 14.
973                          */
974
975                         /* Non-periodic Tx FIFO */
976                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
977                                     dwc_read_reg32(&global_regs->gnptxfsiz));
978
979 #ifdef DWC_UTE_CFI
980                         core_if->pwron_gnptxfsiz =
981                             (dwc_read_reg32(&global_regs->gnptxfsiz) >> 16);
982                         core_if->init_gnptxfsiz =
983                             params->dev_nperio_tx_fifo_size;
984 #endif
985                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
986                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
987
988                         dwc_write_reg32(&global_regs->gnptxfsiz,
989                                         nptxfifosize.d32);
990
991                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
992                                     dwc_read_reg32(&global_regs->gnptxfsiz));
993
994                         txfifosize.b.startaddr =
995                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
996
997                         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
998
999                                 txfifosize.b.depth =
1000                                     params->dev_tx_fifo_size[i];
1001
1002                                 DWC_DEBUGPL(DBG_CIL,
1003                                             "initial dptxfsiz_dieptxf[%d]=%08x\n",
1004                                             i,
1005                                             dwc_read_reg32(&global_regs->
1006                                                            dptxfsiz_dieptxf
1007                                                            [i]));
1008
1009 #ifdef DWC_UTE_CFI
1010                                 core_if->pwron_txfsiz[i] =
1011                                     (dwc_read_reg32
1012                                      (&global_regs->dptxfsiz_dieptxf[i]) >> 16);
1013                                 core_if->init_txfsiz[i] =
1014                                     params->dev_tx_fifo_size[i];
1015 #endif
1016                                 dwc_write_reg32(&global_regs->
1017                                                 dptxfsiz_dieptxf[i],
1018                                                 txfifosize.d32);
1019
1020                                 DWC_DEBUGPL(DBG_CIL,
1021                                             "new dptxfsiz_dieptxf[%d]=%08x\n",
1022                                             i,
1023                                             dwc_read_reg32(&global_regs->
1024                                                            dptxfsiz_dieptxf
1025                                                            [i]));
1026
1027                                 txfifosize.b.startaddr += txfifosize.b.depth;
1028                         }
1029                 }
1030         }
1031         /* Flush the FIFOs */
1032         dwc_otg_flush_tx_fifo(core_if, 0x10);   /* all Tx FIFOs */
1033         dwc_otg_flush_rx_fifo(core_if);
1034
1035         /* Flush the Learning Queue. */
1036         resetctl.b.intknqflsh = 1;
1037         dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
1038
1039         /* Clear all pending Device Interrupts */
1040         /** @todo - if the condition needed to be checked
1041          *  or in any case all pending interrutps should be cleared?
1042          */
1043         if (core_if->multiproc_int_enable) {
1044                 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
1045                         dwc_write_reg32(&dev_if->dev_global_regs->
1046                                         diepeachintmsk[i], 0);
1047                 }
1048
1049                 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1050                         dwc_write_reg32(&dev_if->dev_global_regs->
1051                                         doepeachintmsk[i], 0);
1052                 }
1053
1054                 dwc_write_reg32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1055                 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, 0);
1056         } else {
1057                 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
1058                 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
1059                 dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1060                 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
1061         }
1062
1063         for (i = 0; i <= dev_if->num_in_eps; i++) {
1064                 depctl_data_t depctl;
1065                 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
1066                 if (depctl.b.epena) {
1067                         depctl.d32 = 0;
1068                         depctl.b.epdis = 1;
1069                         depctl.b.snak = 1;
1070                 } else {
1071                         depctl.d32 = 0;
1072                 }
1073
1074                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1075
1076                 dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1077                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
1078                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1079         }
1080
1081         for (i = 0; i <= dev_if->num_out_eps; i++) {
1082                 depctl_data_t depctl;
1083                 depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
1084                 if (depctl.b.epena) {
1085                         depctl.d32 = 0;
1086                         depctl.b.epdis = 1;
1087                         depctl.b.snak = 1;
1088                 } else {
1089                         depctl.d32 = 0;
1090                 }
1091
1092                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1093
1094                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
1095                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
1096                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
1097         }
1098
1099         if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1100                 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
1101                 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
1102                 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
1103
1104                 dev_if->rx_thr_length = params->rx_thr_length;
1105                 dev_if->tx_thr_length = params->tx_thr_length;
1106
1107                 dev_if->setup_desc_index = 0;
1108
1109                 dthrctl.d32 = 0;
1110                 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1111                 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1112                 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1113                 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1114                 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1115                 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
1116
1117                 dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1118                                 dthrctl.d32);
1119
1120                 DWC_DEBUGPL(DBG_CIL,
1121                             "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1122                             dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1123                             dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1124                             dthrctl.b.rx_thr_len);
1125
1126         }
1127
1128         dwc_otg_enable_device_interrupts(core_if);
1129
1130         {
1131                 diepmsk_data_t msk = {.d32 = 0 };
1132                 msk.b.txfifoundrn = 1;
1133                 if (core_if->multiproc_int_enable) {
1134                         dwc_modify_reg32(&dev_if->dev_global_regs->
1135                                          diepeachintmsk[0], msk.d32, msk.d32);
1136                 } else {
1137                         dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk,
1138                                          msk.d32, msk.d32);
1139                 }
1140         }
1141
1142         if (core_if->multiproc_int_enable) {
1143                 /* Set NAK on Babble */
1144                 dctl_data_t dctl = {.d32 = 0 };
1145                 dctl.b.nakonbble = 1;
1146                 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1147         }
1148 }
1149
1150 /**
1151  * This function enables the Host mode interrupts.
1152  *
1153  * @param core_if Programming view of DWC_otg controller
1154  */
1155 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
1156 {
1157         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1158         gintmsk_data_t intr_mask = {.d32 = 0 };
1159
1160         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1161
1162         /* Disable all interrupts. */
1163         dwc_write_reg32(&global_regs->gintmsk, 0);
1164
1165         /* Clear any pending interrupts. */
1166         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
1167
1168         /* Enable the common interrupts */
1169         dwc_otg_enable_common_interrupts(core_if);
1170
1171         /*
1172          * Enable host mode interrupts without disturbing common
1173          * interrupts.
1174          */
1175         intr_mask.b.sofintr = 1;
1176         intr_mask.b.portintr = 1;
1177         intr_mask.b.hcintr = 1;
1178
1179         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1180 }
1181
1182 /**
1183  * This function disables the Host Mode interrupts.
1184  *
1185  * @param core_if Programming view of DWC_otg controller
1186  */
1187 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
1188 {
1189         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1190         gintmsk_data_t intr_mask = {.d32 = 0 };
1191
1192         DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
1193
1194         /*
1195          * Disable host mode interrupts without disturbing common
1196          * interrupts.
1197          */
1198         intr_mask.b.sofintr = 1;
1199         intr_mask.b.portintr = 1;
1200         intr_mask.b.hcintr = 1;
1201         intr_mask.b.ptxfempty = 1;
1202         intr_mask.b.nptxfempty = 1;
1203
1204         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
1205 }
1206
1207 /**
1208  * This function initializes the DWC_otg controller registers for
1209  * host mode.
1210  *
1211  * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
1212  * request queues. Host channels are reset to ensure that they are ready for
1213  * performing transfers.
1214  *
1215  * @param core_if Programming view of DWC_otg controller
1216  *
1217  */
1218 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
1219 {
1220         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1221         dwc_otg_host_if_t *host_if = core_if->host_if;
1222         dwc_otg_core_params_t *params = core_if->core_params;
1223         hprt0_data_t hprt0 = {.d32 = 0 };
1224         fifosize_data_t nptxfifosize;
1225         fifosize_data_t ptxfifosize;
1226         int i;
1227         hcchar_data_t hcchar;
1228         hcfg_data_t hcfg;
1229         dwc_otg_hc_regs_t *hc_regs;
1230         int num_channels;
1231         gotgctl_data_t gotgctl = {.d32 = 0 };
1232
1233         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
1234
1235         /* Restart the Phy Clock */
1236         dwc_write_reg32(core_if->pcgcctl, 0);
1237
1238         /* Initialize Host Configuration Register */
1239         init_fslspclksel(core_if);
1240         if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1241                 hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
1242                 hcfg.b.fslssupp = 1;
1243                 dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
1244         }
1245
1246         /* Configure data FIFO sizes */
1247         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1248                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
1249                             core_if->total_fifo_size);
1250                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
1251                             params->host_rx_fifo_size);
1252                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
1253                             params->host_nperio_tx_fifo_size);
1254                 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
1255                             params->host_perio_tx_fifo_size);
1256
1257                 /* Rx FIFO */
1258                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1259                             dwc_read_reg32(&global_regs->grxfsiz));
1260                 dwc_write_reg32(&global_regs->grxfsiz,
1261                                 params->host_rx_fifo_size);
1262                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1263                             dwc_read_reg32(&global_regs->grxfsiz));
1264
1265                 /* Non-periodic Tx FIFO */
1266                 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1267                             dwc_read_reg32(&global_regs->gnptxfsiz));
1268                 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
1269                 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
1270                 dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
1271                 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1272                             dwc_read_reg32(&global_regs->gnptxfsiz));
1273
1274                 /* Periodic Tx FIFO */
1275                 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
1276                             dwc_read_reg32(&global_regs->hptxfsiz));
1277                 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
1278                 ptxfifosize.b.startaddr =
1279                     nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1280                 dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
1281                 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
1282                             dwc_read_reg32(&global_regs->hptxfsiz));
1283         }
1284
1285         /* Clear Host Set HNP Enable in the OTG Control Register */
1286         gotgctl.b.hstsethnpen = 1;
1287         dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
1288
1289         /* Make sure the FIFOs are flushed. */
1290         dwc_otg_flush_tx_fifo(core_if, 0x10 /* all Tx FIFOs */ );
1291         dwc_otg_flush_rx_fifo(core_if);
1292
1293         /* Flush out any leftover queued requests. */
1294         num_channels = core_if->core_params->host_channels;
1295         for (i = 0; i < num_channels; i++) {
1296                 hc_regs = core_if->host_if->hc_regs[i];
1297                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1298                 hcchar.b.chen = 0;
1299                 hcchar.b.chdis = 1;
1300                 hcchar.b.epdir = 0;
1301                 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1302         }
1303
1304         /* Halt all channels to put them into a known state. */
1305         for (i = 0; i < num_channels; i++) {
1306                 int count = 0;
1307                 hc_regs = core_if->host_if->hc_regs[i];
1308                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1309                 hcchar.b.chen = 1;
1310                 hcchar.b.chdis = 1;
1311                 hcchar.b.epdir = 0;
1312                 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1313                 DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
1314                 do {
1315                         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1316                         if (++count > 1000) {
1317                                 DWC_ERROR
1318                                     ("%s: Unable to clear halt on channel %d\n",
1319                                      __func__, i);
1320                                 break;
1321                         }
1322                         dwc_udelay(1);
1323                 } while (hcchar.b.chen);
1324         }
1325
1326         /* Turn on the vbus power. */
1327         DWC_DEBUGPL(DBG_CIL,"Init: Port Power? op_state=%d\n", core_if->op_state);
1328         if (core_if->op_state == A_HOST) {
1329                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
1330                 DWC_DEBUGPL(DBG_CIL,"Init: Power Port (%d)\n", hprt0.b.prtpwr);
1331                 if (hprt0.b.prtpwr == 0) {
1332                         hprt0.b.prtpwr = 1;
1333                         dwc_write_reg32(host_if->hprt0, hprt0.d32);
1334                 }
1335         }
1336
1337         dwc_otg_enable_host_interrupts(core_if);
1338 }
1339
1340 /**
1341  * Prepares a host channel for transferring packets to/from a specific
1342  * endpoint. The HCCHARn register is set up with the characteristics specified
1343  * in _hc. Host channel interrupts that may need to be serviced while this
1344  * transfer is in progress are enabled.
1345  *
1346  * @param core_if Programming view of DWC_otg controller
1347  * @param hc Information needed to initialize the host channel
1348  */
1349 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1350 {
1351         uint32_t intr_enable;
1352         hcintmsk_data_t hc_intr_mask;
1353         gintmsk_data_t gintmsk = {.d32 = 0 };
1354         hcchar_data_t hcchar;
1355         hcsplt_data_t hcsplt;
1356
1357         uint8_t hc_num = hc->hc_num;
1358         dwc_otg_host_if_t *host_if = core_if->host_if;
1359         dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
1360
1361         /* Clear old interrupt conditions for this host channel. */
1362         hc_intr_mask.d32 = 0xFFFFFFFF;
1363         hc_intr_mask.b.reserved = 0;
1364         dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
1365
1366         /* Enable channel interrupts required for this transfer. */
1367         hc_intr_mask.d32 = 0;
1368         hc_intr_mask.b.chhltd = 1;
1369         if (core_if->dma_enable) {
1370                 hc_intr_mask.b.ahberr = 1;
1371                 if (hc->error_state && !hc->do_split &&
1372                     hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
1373                         hc_intr_mask.b.ack = 1;
1374                         if (hc->ep_is_in) {
1375                                 hc_intr_mask.b.datatglerr = 1;
1376                                 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
1377                                         hc_intr_mask.b.nak = 1;
1378                                 }
1379                         }
1380                 }
1381         } else {
1382                 switch (hc->ep_type) {
1383                 case DWC_OTG_EP_TYPE_CONTROL:
1384                 case DWC_OTG_EP_TYPE_BULK:
1385                         hc_intr_mask.b.xfercompl = 1;
1386                         hc_intr_mask.b.stall = 1;
1387                         hc_intr_mask.b.xacterr = 1;
1388                         hc_intr_mask.b.datatglerr = 1;
1389                         if (hc->ep_is_in) {
1390                                 hc_intr_mask.b.bblerr = 1;
1391                         } else {
1392                                 hc_intr_mask.b.nak = 1;
1393                                 hc_intr_mask.b.nyet = 1;
1394                                 if (hc->do_ping) {
1395                                         hc_intr_mask.b.ack = 1;
1396                                 }
1397                         }
1398
1399                         if (hc->do_split) {
1400                                 hc_intr_mask.b.nak = 1;
1401                                 if (hc->complete_split) {
1402                                         hc_intr_mask.b.nyet = 1;
1403                                 } else {
1404                                         hc_intr_mask.b.ack = 1;
1405                                 }
1406                         }
1407
1408                         if (hc->error_state) {
1409                                 hc_intr_mask.b.ack = 1;
1410                         }
1411                         break;
1412                 case DWC_OTG_EP_TYPE_INTR:
1413                         hc_intr_mask.b.xfercompl = 1;
1414                         hc_intr_mask.b.nak = 1;
1415                         hc_intr_mask.b.stall = 1;
1416                         hc_intr_mask.b.xacterr = 1;
1417                         hc_intr_mask.b.datatglerr = 1;
1418                         hc_intr_mask.b.frmovrun = 1;
1419
1420                         if (hc->ep_is_in) {
1421                                 hc_intr_mask.b.bblerr = 1;
1422                         }
1423                         if (hc->error_state) {
1424                                 hc_intr_mask.b.ack = 1;
1425                         }
1426                         if (hc->do_split) {
1427                                 if (hc->complete_split) {
1428                                         hc_intr_mask.b.nyet = 1;
1429                                 } else {
1430                                         hc_intr_mask.b.ack = 1;
1431                                 }
1432                         }
1433                         break;
1434                 case DWC_OTG_EP_TYPE_ISOC:
1435                         hc_intr_mask.b.xfercompl = 1;
1436                         hc_intr_mask.b.frmovrun = 1;
1437                         hc_intr_mask.b.ack = 1;
1438
1439                         if (hc->ep_is_in) {
1440                                 hc_intr_mask.b.xacterr = 1;
1441                                 hc_intr_mask.b.bblerr = 1;
1442                         }
1443                         break;
1444                 }
1445         }
1446         dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
1447
1448         /* Enable the top level host channel interrupt. */
1449         intr_enable = (1 << hc_num);
1450         dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
1451
1452         /* Make sure host channel interrupts are enabled. */
1453         gintmsk.b.hcintr = 1;
1454         dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
1455
1456         /*
1457          * Program the HCCHARn register with the endpoint characteristics for
1458          * the current transfer.
1459          */
1460         hcchar.d32 = 0;
1461         hcchar.b.devaddr = hc->dev_addr;
1462         hcchar.b.epnum = hc->ep_num;
1463         hcchar.b.epdir = hc->ep_is_in;
1464         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
1465         hcchar.b.eptype = hc->ep_type;
1466         hcchar.b.mps = hc->max_packet;
1467
1468         dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
1469
1470         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1471         DWC_DEBUGPL(DBG_HCDV, "  Dev Addr: %d\n", hcchar.b.devaddr);
1472         DWC_DEBUGPL(DBG_HCDV, "  Ep Num: %d\n", hcchar.b.epnum);
1473         DWC_DEBUGPL(DBG_HCDV, "  Is In: %d\n", hcchar.b.epdir);
1474         DWC_DEBUGPL(DBG_HCDV, "  Is Low Speed: %d\n", hcchar.b.lspddev);
1475         DWC_DEBUGPL(DBG_HCDV, "  Ep Type: %d\n", hcchar.b.eptype);
1476         DWC_DEBUGPL(DBG_HCDV, "  Max Pkt: %d\n", hcchar.b.mps);
1477         DWC_DEBUGPL(DBG_HCDV, "  Multi Cnt: %d\n", hcchar.b.multicnt);
1478
1479         /*
1480          * Program the HCSPLIT register for SPLITs
1481          */
1482         hcsplt.d32 = 0;
1483         if (hc->do_split) {
1484                 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
1485                             hc->hc_num,
1486                             hc->complete_split ? "CSPLIT" : "SSPLIT");
1487                 hcsplt.b.compsplt = hc->complete_split;
1488                 hcsplt.b.xactpos = hc->xact_pos;
1489                 hcsplt.b.hubaddr = hc->hub_addr;
1490                 hcsplt.b.prtaddr = hc->port_addr;
1491                 DWC_DEBUGPL(DBG_HCDV, "   comp split %d\n", hc->complete_split);
1492                 DWC_DEBUGPL(DBG_HCDV, "   xact pos %d\n", hc->xact_pos);
1493                 DWC_DEBUGPL(DBG_HCDV, "   hub addr %d\n", hc->hub_addr);
1494                 DWC_DEBUGPL(DBG_HCDV, "   port addr %d\n", hc->port_addr);
1495                 DWC_DEBUGPL(DBG_HCDV, "   is_in %d\n", hc->ep_is_in);
1496                 DWC_DEBUGPL(DBG_HCDV, "   Max Pkt: %d\n", hcchar.b.mps);
1497                 DWC_DEBUGPL(DBG_HCDV, "   xferlen: %d\n", hc->xfer_len);
1498         }
1499         dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
1500
1501 }
1502
1503 /**
1504  * Attempts to halt a host channel. This function should only be called in
1505  * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
1506  * normal circumstances in DMA mode, the controller halts the channel when the
1507  * transfer is complete or a condition occurs that requires application
1508  * intervention.
1509  *
1510  * In slave mode, checks for a free request queue entry, then sets the Channel
1511  * Enable and Channel Disable bits of the Host Channel Characteristics
1512  * register of the specified channel to intiate the halt. If there is no free
1513  * request queue entry, sets only the Channel Disable bit of the HCCHARn
1514  * register to flush requests for this channel. In the latter case, sets a
1515  * flag to indicate that the host channel needs to be halted when a request
1516  * queue slot is open.
1517  *
1518  * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
1519  * HCCHARn register. The controller ensures there is space in the request
1520  * queue before submitting the halt request.
1521  *
1522  * Some time may elapse before the core flushes any posted requests for this
1523  * host channel and halts. The Channel Halted interrupt handler completes the
1524  * deactivation of the host channel.
1525  *
1526  * @param core_if Controller register interface.
1527  * @param hc Host channel to halt.
1528  * @param halt_status Reason for halting the channel.
1529  */
1530 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
1531                      dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
1532 {
1533         gnptxsts_data_t nptxsts;
1534         hptxsts_data_t hptxsts;
1535         hcchar_data_t hcchar;
1536         dwc_otg_hc_regs_t *hc_regs;
1537         dwc_otg_core_global_regs_t *global_regs;
1538         dwc_otg_host_global_regs_t *host_global_regs;
1539
1540         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1541         global_regs = core_if->core_global_regs;
1542         host_global_regs = core_if->host_if->host_global_regs;
1543
1544         DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
1545                    "halt_status = %d\n", halt_status);
1546
1547         if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
1548             halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
1549                 /*
1550                  * Disable all channel interrupts except Ch Halted. The QTD
1551                  * and QH state associated with this transfer has been cleared
1552                  * (in the case of URB_DEQUEUE), so the channel needs to be
1553                  * shut down carefully to prevent crashes.
1554                  */
1555                 hcintmsk_data_t hcintmsk;
1556                 hcintmsk.d32 = 0;
1557                 hcintmsk.b.chhltd = 1;
1558                 dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
1559
1560                 /*
1561                  * Make sure no other interrupts besides halt are currently
1562                  * pending. Handling another interrupt could cause a crash due
1563                  * to the QTD and QH state.
1564                  */
1565                 dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
1566
1567                 /*
1568                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
1569                  * even if the channel was already halted for some other
1570                  * reason.
1571                  */
1572                 hc->halt_status = halt_status;
1573
1574                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1575                 if (hcchar.b.chen == 0) {
1576                         /*
1577                          * The channel is either already halted or it hasn't
1578                          * started yet. In DMA mode, the transfer may halt if
1579                          * it finishes normally or a condition occurs that
1580                          * requires driver intervention. Don't want to halt
1581                          * the channel again. In either Slave or DMA mode,
1582                          * it's possible that the transfer has been assigned
1583                          * to a channel, but not started yet when an URB is
1584                          * dequeued. Don't want to halt a channel that hasn't
1585                          * started yet.
1586                          */
1587                         return;
1588                 }
1589         }
1590
1591         if (hc->halt_pending) {
1592                 /*
1593                  * A halt has already been issued for this channel. This might
1594                  * happen when a transfer is aborted by a higher level in
1595                  * the stack.
1596                  */
1597 #ifdef DEBUG
1598 DWC_DEBUGPL(DBG_CIL,"*** %s: Channel %d, _hc->halt_pending already set ***\n",
1599                      __func__, hc->hc_num);
1600
1601 /*              dwc_otg_dump_global_registers(core_if); */
1602 /*              dwc_otg_dump_host_registers(core_if); */
1603 #endif
1604                 return;
1605         }
1606
1607         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1608         hcchar.b.chen = 1;
1609         hcchar.b.chdis = 1;
1610
1611         if (!core_if->dma_enable) {
1612                 /* Check for space in the request queue to issue the halt. */
1613                 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
1614                     hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
1615                         nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
1616                         if (nptxsts.b.nptxqspcavail == 0) {
1617                                 hcchar.b.chen = 0;
1618                         }
1619                 } else {
1620                         hptxsts.d32 =
1621                             dwc_read_reg32(&host_global_regs->hptxsts);
1622                         if ((hptxsts.b.ptxqspcavail == 0)
1623                             || (core_if->queuing_high_bandwidth)) {
1624                                 hcchar.b.chen = 0;
1625                         }
1626                 }
1627         }
1628
1629         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1630
1631         hc->halt_status = halt_status;
1632
1633         if (hcchar.b.chen) {
1634                 hc->halt_pending = 1;
1635                 hc->halt_on_queue = 0;
1636         } else {
1637                 hc->halt_on_queue = 1;
1638         }
1639
1640         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1641         DWC_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n", hcchar.d32);
1642         DWC_DEBUGPL(DBG_HCDV, "  halt_pending: %d\n", hc->halt_pending);
1643         DWC_DEBUGPL(DBG_HCDV, "  halt_on_queue: %d\n", hc->halt_on_queue);
1644         DWC_DEBUGPL(DBG_HCDV, "  halt_status: %d\n", hc->halt_status);
1645
1646         return;
1647 }
1648
1649 /**
1650  * Clears the transfer state for a host channel. This function is normally
1651  * called after a transfer is done and the host channel is being released.
1652  *
1653  * @param core_if Programming view of DWC_otg controller.
1654  * @param hc Identifies the host channel to clean up.
1655  */
1656 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1657 {
1658         dwc_otg_hc_regs_t *hc_regs;
1659
1660         hc->xfer_started = 0;
1661
1662         /*
1663          * Clear channel interrupt enables and any unhandled channel interrupt
1664          * conditions.
1665          */
1666         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1667         dwc_write_reg32(&hc_regs->hcintmsk, 0);
1668         dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
1669
1670 #ifdef DEBUG
1671         DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
1672         {
1673                 hcchar_data_t hcchar;
1674                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1675                 if (hcchar.b.chdis) {
1676                         DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1677                                  __func__, hc->hc_num, hcchar.d32);
1678                 }
1679         }
1680 #endif
1681 }
1682
1683 /**
1684  * Sets the channel property that indicates in which frame a periodic transfer
1685  * should occur. This is always set to the _next_ frame. This function has no
1686  * effect on non-periodic transfers.
1687  *
1688  * @param core_if Programming view of DWC_otg controller.
1689  * @param hc Identifies the host channel to set up and its properties.
1690  * @param hcchar Current value of the HCCHAR register for the specified host
1691  * channel.
1692  */
1693 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
1694                                          dwc_hc_t * hc, hcchar_data_t * hcchar)
1695 {
1696         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1697             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1698                 hfnum_data_t hfnum;
1699                 hfnum.d32 =
1700                     dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
1701
1702                 /* 1 if _next_ frame is odd, 0 if it's even */
1703                 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
1704 #ifdef DEBUG
1705                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
1706                     && !hc->complete_split) {
1707                         switch (hfnum.b.frnum & 0x7) {
1708                         case 7:
1709                                 core_if->hfnum_7_samples++;
1710                                 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
1711                                 break;
1712                         case 0:
1713                                 core_if->hfnum_0_samples++;
1714                                 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
1715                                 break;
1716                         default:
1717                                 core_if->hfnum_other_samples++;
1718                                 core_if->hfnum_other_frrem_accum +=
1719                                     hfnum.b.frrem;
1720                                 break;
1721                         }
1722                 }
1723 #endif
1724         }
1725 }
1726
1727 #ifdef DEBUG
1728 void hc_xfer_timeout(void *ptr)
1729 {
1730         hc_xfer_info_t *xfer_info = (hc_xfer_info_t *) ptr;
1731         int hc_num = xfer_info->hc->hc_num;
1732         DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
1733         DWC_WARN("      start_hcchar_val 0x%08x\n",
1734                  xfer_info->core_if->start_hcchar_val[hc_num]);
1735 }
1736 #endif
1737
1738 /*
1739  * This function does the setup for a data transfer for a host channel and
1740  * starts the transfer. May be called in either Slave mode or DMA mode. In
1741  * Slave mode, the caller must ensure that there is sufficient space in the
1742  * request queue and Tx Data FIFO.
1743  *
1744  * For an OUT transfer in Slave mode, it loads a data packet into the
1745  * appropriate FIFO. If necessary, additional data packets will be loaded in
1746  * the Host ISR.
1747  *
1748  * For an IN transfer in Slave mode, a data packet is requested. The data
1749  * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
1750  * additional data packets are requested in the Host ISR.
1751  *
1752  * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
1753  * register along with a packet count of 1 and the channel is enabled. This
1754  * causes a single PING transaction to occur. Other fields in HCTSIZ are
1755  * simply set to 0 since no data transfer occurs in this case.
1756  *
1757  * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
1758  * all the information required to perform the subsequent data transfer. In
1759  * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
1760  * controller performs the entire PING protocol, then starts the data
1761  * transfer.
1762  *
1763  * @param core_if Programming view of DWC_otg controller.
1764  * @param hc Information needed to initialize the host channel. The xfer_len
1765  * value may be reduced to accommodate the max widths of the XferSize and
1766  * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
1767  * to reflect the final xfer_len value.
1768  */
1769 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1770 {
1771         hcchar_data_t hcchar;
1772         hctsiz_data_t hctsiz;
1773         uint16_t num_packets;
1774         uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
1775         uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
1776         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1777
1778         hctsiz.d32 = 0;
1779
1780         if (hc->do_ping) {
1781                 if (!core_if->dma_enable) {
1782                         dwc_otg_hc_do_ping(core_if, hc);
1783                         hc->xfer_started = 1;
1784                         return;
1785                 } else {
1786                         hctsiz.b.dopng = 1;
1787                 }
1788         }
1789
1790         if (hc->do_split) {
1791                 num_packets = 1;
1792
1793                 if (hc->complete_split && !hc->ep_is_in) {
1794                         /* For CSPLIT OUT Transfer, set the size to 0 so the
1795                          * core doesn't expect any data written to the FIFO */
1796                         hc->xfer_len = 0;
1797                 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
1798                         hc->xfer_len = hc->max_packet;
1799                 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
1800                         hc->xfer_len = 188;
1801                 }
1802
1803                 hctsiz.b.xfersize = hc->xfer_len;
1804         } else {
1805                 /*
1806                  * Ensure that the transfer length and packet count will fit
1807                  * in the widths allocated for them in the HCTSIZn register.
1808                  */
1809                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1810                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1811                         /*
1812                          * Make sure the transfer size is no larger than one
1813                          * (micro)frame's worth of data. (A check was done
1814                          * when the periodic transfer was accepted to ensure
1815                          * that a (micro)frame's worth of data can be
1816                          * programmed into a channel.)
1817                          */
1818                         uint32_t max_periodic_len =
1819                             hc->multi_count * hc->max_packet;
1820                         if (hc->xfer_len > max_periodic_len) {
1821                                 hc->xfer_len = max_periodic_len;
1822                         } else {
1823                         }
1824                 } else if (hc->xfer_len > max_hc_xfer_size) {
1825                         /* Make sure that xfer_len is a multiple of max packet size. */
1826                         hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
1827                 }
1828
1829                 if (hc->xfer_len > 0) {
1830                         num_packets =
1831                             (hc->xfer_len + hc->max_packet -
1832                              1) / hc->max_packet;
1833                         if (num_packets > max_hc_pkt_count) {
1834                                 num_packets = max_hc_pkt_count;
1835                                 hc->xfer_len = num_packets * hc->max_packet;
1836                         }
1837                 } else {
1838                         /* Need 1 packet for transfer length of 0. */
1839                         num_packets = 1;
1840                 }
1841
1842                 if (hc->ep_is_in) {
1843                         /* Always program an integral # of max packets for IN transfers. */
1844                         hc->xfer_len = num_packets * hc->max_packet;
1845                 }
1846
1847                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1848                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1849                         /*
1850                          * Make sure that the multi_count field matches the
1851                          * actual transfer length.
1852                          */
1853                         hc->multi_count = num_packets;
1854                 }
1855
1856                 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1857                         /* Set up the initial PID for the transfer. */
1858                         if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
1859                                 if (hc->ep_is_in) {
1860                                         if (hc->multi_count == 1) {
1861                                                 hc->data_pid_start =
1862                                                     DWC_OTG_HC_PID_DATA0;
1863                                         } else if (hc->multi_count == 2) {
1864                                                 hc->data_pid_start =
1865                                                     DWC_OTG_HC_PID_DATA1;
1866                                         } else {
1867                                                 hc->data_pid_start =
1868                                                     DWC_OTG_HC_PID_DATA2;
1869                                         }
1870                                 } else {
1871                                         if (hc->multi_count == 1) {
1872                                                 hc->data_pid_start =
1873                                                     DWC_OTG_HC_PID_DATA0;
1874                                         } else {
1875                                                 hc->data_pid_start =
1876                                                     DWC_OTG_HC_PID_MDATA;
1877                                         }
1878                                 }
1879                         } else {
1880                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
1881                         }
1882                 }
1883
1884                 hctsiz.b.xfersize = hc->xfer_len;
1885         }
1886
1887         hc->start_pkt_count = num_packets;
1888         hctsiz.b.pktcnt = num_packets;
1889         hctsiz.b.pid = hc->data_pid_start;
1890         dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
1891
1892         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1893         DWC_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
1894         DWC_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n", hctsiz.b.pktcnt);
1895         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
1896
1897         if (core_if->dma_enable) {
1898                 dwc_write_reg32(&hc_regs->hcdma, (uint32_t) hc->xfer_buff);
1899         }
1900
1901         /* Start the split */
1902         if (hc->do_split) {
1903                 hcsplt_data_t hcsplt;
1904                 hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
1905                 hcsplt.b.spltena = 1;
1906                 dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
1907         }
1908
1909         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1910         hcchar.b.multicnt = hc->multi_count;
1911         hc_set_even_odd_frame(core_if, hc, &hcchar);
1912 #ifdef DEBUG
1913         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
1914         if (hcchar.b.chdis) {
1915                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1916                          __func__, hc->hc_num, hcchar.d32);
1917         }
1918 #endif
1919
1920         /* Set host channel enable after all other setup is complete. */
1921         hcchar.b.chen = 1;
1922         hcchar.b.chdis = 0;
1923         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1924
1925         hc->xfer_started = 1;
1926         hc->requests++;
1927
1928         if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
1929                 /* Load OUT packet into the appropriate Tx FIFO. */
1930                 dwc_otg_hc_write_packet(core_if, hc);
1931         }
1932 #ifdef DEBUG
1933         core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
1934         core_if->hc_xfer_info[hc->hc_num].hc = hc;
1935         /* Start a timer for this transfer. */
1936         DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
1937 #endif
1938 }
1939
1940 /**
1941  * This function continues a data transfer that was started by previous call
1942  * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
1943  * sufficient space in the request queue and Tx Data FIFO. This function
1944  * should only be called in Slave mode. In DMA mode, the controller acts
1945  * autonomously to complete transfers programmed to a host channel.
1946  *
1947  * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
1948  * if there is any data remaining to be queued. For an IN transfer, another
1949  * data packet is always requested. For the SETUP phase of a control transfer,
1950  * this function does nothing.
1951  *
1952  * @return 1 if a new request is queued, 0 if no more requests are required
1953  * for this transfer.
1954  */
1955 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
1956 {
1957         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
1958
1959         if (hc->do_split) {
1960                 /* SPLITs always queue just once per channel */
1961                 return 0;
1962         } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
1963                 /* SETUPs are queued only once since they can't be NAKed. */
1964                 return 0;
1965         } else if (hc->ep_is_in) {
1966                 /*
1967                  * Always queue another request for other IN transfers. If
1968                  * back-to-back INs are issued and NAKs are received for both,
1969                  * the driver may still be processing the first NAK when the
1970                  * second NAK is received. When the interrupt handler clears
1971                  * the NAK interrupt for the first NAK, the second NAK will
1972                  * not be seen. So we can't depend on the NAK interrupt
1973                  * handler to requeue a NAKed request. Instead, IN requests
1974                  * are issued each time this function is called. When the
1975                  * transfer completes, the extra requests for the channel will
1976                  * be flushed.
1977                  */
1978                 hcchar_data_t hcchar;
1979                 dwc_otg_hc_regs_t *hc_regs =
1980                     core_if->host_if->hc_regs[hc->hc_num];
1981
1982                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
1983                 hc_set_even_odd_frame(core_if, hc, &hcchar);
1984                 hcchar.b.chen = 1;
1985                 hcchar.b.chdis = 0;
1986                 DWC_DEBUGPL(DBG_HCDV, "  IN xfer: hcchar = 0x%08x\n",
1987                             hcchar.d32);
1988                 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
1989                 hc->requests++;
1990                 return 1;
1991         } else {
1992                 /* OUT transfers. */
1993                 if (hc->xfer_count < hc->xfer_len) {
1994                         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
1995                             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
1996                                 hcchar_data_t hcchar;
1997                                 dwc_otg_hc_regs_t *hc_regs;
1998                                 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
1999                                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2000                                 hc_set_even_odd_frame(core_if, hc, &hcchar);
2001                         }
2002
2003                         /* Load OUT packet into the appropriate Tx FIFO. */
2004                         dwc_otg_hc_write_packet(core_if, hc);
2005                         hc->requests++;
2006                         return 1;
2007                 } else {
2008                         return 0;
2009                 }
2010         }
2011 }
2012
2013 /**
2014  * Starts a PING transfer. This function should only be called in Slave mode.
2015  * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
2016  */
2017 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2018 {
2019         hcchar_data_t hcchar;
2020         hctsiz_data_t hctsiz;
2021         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2022
2023         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2024
2025         hctsiz.d32 = 0;
2026         hctsiz.b.dopng = 1;
2027         hctsiz.b.pktcnt = 1;
2028         dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
2029
2030         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
2031         hcchar.b.chen = 1;
2032         hcchar.b.chdis = 0;
2033         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
2034 }
2035
2036 /*
2037  * This function writes a packet into the Tx FIFO associated with the Host
2038  * Channel. For a channel associated with a non-periodic EP, the non-periodic
2039  * Tx FIFO is written. For a channel associated with a periodic EP, the
2040  * periodic Tx FIFO is written. This function should only be called in Slave
2041  * mode.
2042  *
2043  * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2044  * then number of bytes written to the Tx FIFO.
2045  */
2046 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2047 {
2048         uint32_t i;
2049         uint32_t remaining_count;
2050         uint32_t byte_count;
2051         uint32_t dword_count;
2052
2053         uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
2054         uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
2055
2056         remaining_count = hc->xfer_len - hc->xfer_count;
2057         if (remaining_count > hc->max_packet) {
2058                 byte_count = hc->max_packet;
2059         } else {
2060                 byte_count = remaining_count;
2061         }
2062
2063         dword_count = (byte_count + 3) / 4;
2064
2065         if ((((unsigned long)data_buff) & 0x3) == 0) {
2066                 /* xfer_buff is DWORD aligned. */
2067                 for (i = 0; i < dword_count; i++, data_buff++) {
2068                         dwc_write_reg32(data_fifo, *data_buff);
2069                 }
2070         } else {
2071                 /* xfer_buff is not DWORD aligned. */
2072                 for (i = 0; i < dword_count; i++, data_buff++) {
2073                         uint32_t data;
2074                         data =
2075                             (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
2076                              16 | data_buff[3] << 24);
2077                         dwc_write_reg32(data_fifo, data);
2078                 }
2079         }
2080
2081         hc->xfer_count += byte_count;
2082         hc->xfer_buff += byte_count;
2083 }
2084
2085 /**
2086  * Gets the current USB frame number. This is the frame number from the last
2087  * SOF packet.
2088  */
2089 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
2090 {
2091         dsts_data_t dsts;
2092         dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
2093
2094         /* read current frame/microframe number from DSTS register */
2095         return dsts.b.soffn;
2096 }
2097
2098 /**
2099  * This function reads a setup packet from the Rx FIFO into the destination
2100  * buffer.      This function is called from the Rx Status Queue Level (RxStsQLvl)
2101  * Interrupt routine when a SETUP packet has been received in Slave mode.
2102  *
2103  * @param core_if Programming view of DWC_otg controller.
2104  * @param dest Destination buffer for packet data.
2105  */
2106 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
2107 {
2108         /* Get the 8 bytes of a setup transaction data */
2109
2110         /* Pop 2 DWORDS off the receive data FIFO into memory */
2111         dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
2112         dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
2113 }
2114
2115 /**
2116  * This function enables EP0 OUT to receive SETUP packets and configures EP0
2117  * IN for transmitting packets.  It is normally called when the
2118  * "Enumeration Done" interrupt occurs.
2119  *
2120  * @param core_if Programming view of DWC_otg controller.
2121  * @param ep The EP0 data.
2122  */
2123 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2124 {
2125         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2126         dsts_data_t dsts;
2127         depctl_data_t diepctl;
2128         depctl_data_t doepctl;
2129         dctl_data_t dctl = {.d32 = 0 };
2130
2131         /* Read the Device Status and Endpoint 0 Control registers */
2132         dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
2133         diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
2134         doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
2135
2136         /* Set the MPS of the IN EP based on the enumeration speed */
2137         switch (dsts.b.enumspd) {
2138         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
2139         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
2140         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
2141                 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
2142                 break;
2143         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
2144                 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
2145                 break;
2146         }
2147
2148         dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
2149
2150         /* Enable OUT EP for receive */
2151         doepctl.b.epena = 1;
2152         dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
2153
2154 #ifdef VERBOSE
2155         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
2156                     dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
2157         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
2158                     dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
2159 #endif
2160         dctl.b.cgnpinnak = 1;
2161
2162         dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
2163         DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
2164                     dwc_read_reg32(&dev_if->dev_global_regs->dctl));
2165 }
2166
2167 /**
2168  * This function activates an EP.  The Device EP control register for
2169  * the EP is configured as defined in the ep structure.  Note: This
2170  * function is not used for EP0.
2171  *
2172  * @param core_if Programming view of DWC_otg controller.
2173  * @param ep The EP to activate.
2174  */
2175 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2176 {
2177         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
2178         depctl_data_t depctl;
2179         volatile uint32_t *addr;
2180         daint_data_t daintmsk = {.d32 = 0 };
2181
2182         DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
2183                     (ep->is_in ? "IN" : "OUT"));
2184
2185         /* Read DEPCTLn register */
2186         if (ep->is_in == 1) {
2187                 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
2188                 daintmsk.ep.in = 1 << ep->num;
2189         } else {
2190                 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
2191                 daintmsk.ep.out = 1 << ep->num;
2192         }
2193
2194         /* If the EP is already active don't change the EP Control
2195          * register. */
2196         depctl.d32 = dwc_read_reg32(addr);
2197         if (!depctl.b.usbactep) {
2198                 depctl.b.mps = ep->maxpacket;
2199                 depctl.b.eptype = ep->type;
2200                 depctl.b.txfnum = ep->tx_fifo_num;
2201
2202                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
2203                         depctl.b.setd0pid = 1;  // ???
2204                 } else {
2205                         depctl.b.setd0pid = 1;
2206                 }
2207                 depctl.b.usbactep = 1;
2208
2209                 dwc_write_reg32(addr, depctl.d32);
2210                 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr));
2211         }
2212
2213         /* Enable the Interrupt for this EP */
2214         if (core_if->multiproc_int_enable) {
2215                 if (ep->is_in == 1) {
2216                         diepmsk_data_t diepmsk = {.d32 = 0 };
2217                         diepmsk.b.xfercompl = 1;
2218                         diepmsk.b.timeout = 1;
2219                         diepmsk.b.epdisabled = 1;
2220                         diepmsk.b.ahberr = 1;
2221                         diepmsk.b.intknepmis = 1;
2222                         diepmsk.b.txfifoundrn = 1;      //?????
2223
2224                         if (core_if->dma_desc_enable) {
2225                                 diepmsk.b.bna = 1;
2226                         }
2227 /*
2228                         if(core_if->dma_enable) {
2229                                 doepmsk.b.nak = 1;
2230                         }
2231 */
2232                         dwc_write_reg32(&dev_if->dev_global_regs->
2233                                         diepeachintmsk[ep->num], diepmsk.d32);
2234
2235                 } else {
2236                         doepmsk_data_t doepmsk = {.d32 = 0 };
2237                         doepmsk.b.xfercompl = 1;
2238                         doepmsk.b.ahberr = 1;
2239                         doepmsk.b.epdisabled = 1;
2240
2241                         if (core_if->dma_desc_enable) {
2242                                 doepmsk.b.bna = 1;
2243                         }
2244 /*
2245                         doepmsk.b.babble = 1;
2246                         doepmsk.b.nyet = 1;
2247                         doepmsk.b.nak = 1;
2248 */
2249                         dwc_write_reg32(&dev_if->dev_global_regs->
2250                                         doepeachintmsk[ep->num], doepmsk.d32);
2251                 }
2252                 dwc_modify_reg32(&dev_if->dev_global_regs->deachintmsk,
2253                                  0, daintmsk.d32);
2254         } else {
2255                 dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
2256                                  0, daintmsk.d32);
2257         }
2258
2259         DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
2260                     dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
2261
2262         ep->stall_clear_flag = 0;
2263         return;
2264 }
2265
2266 /**
2267  * This function deactivates an EP. This is done by clearing the USB Active
2268  * EP bit in the Device EP control register. Note: This function is not used
2269  * for EP0. EP0 cannot be deactivated.
2270  *
2271  * @param core_if Programming view of DWC_otg controller.
2272  * @param ep The EP to deactivate.
2273  */
2274 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2275 {
2276         depctl_data_t depctl = {.d32 = 0 };
2277         volatile uint32_t *addr;
2278         daint_data_t daintmsk = {.d32 = 0 };
2279
2280         /* Read DEPCTLn register */
2281         if (ep->is_in == 1) {
2282                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
2283                 daintmsk.ep.in = 1 << ep->num;
2284         } else {
2285                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
2286                 daintmsk.ep.out = 1 << ep->num;
2287         }
2288
2289         depctl.d32 = dwc_read_reg32(addr);
2290
2291         depctl.b.usbactep = 0;
2292
2293         if (core_if->dma_desc_enable)
2294                 depctl.b.epdis = 1;
2295
2296         dwc_write_reg32(addr, depctl.d32);
2297
2298         /* Disable the Interrupt for this EP */
2299         if (core_if->multiproc_int_enable) {
2300                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->deachintmsk,
2301                                  daintmsk.d32, 0);
2302
2303                 if (ep->is_in == 1) {
2304                         dwc_write_reg32(&core_if->dev_if->dev_global_regs->
2305                                         diepeachintmsk[ep->num], 0);
2306                 } else {
2307                         dwc_write_reg32(&core_if->dev_if->dev_global_regs->
2308                                         doepeachintmsk[ep->num], 0);
2309                 }
2310         } else {
2311                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
2312                                  daintmsk.d32, 0);
2313         }
2314 }
2315
2316 /**
2317  * This function initializes dma descriptor chain.
2318  *
2319  * @param core_if Programming view of DWC_otg controller.
2320  * @param ep The EP to start the transfer on.
2321  */
2322 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2323 {
2324         dwc_otg_dma_desc_t *dma_desc;
2325         uint32_t offset;
2326         uint32_t xfer_est;
2327         int i;
2328
2329         ep->desc_cnt = (ep->total_len / ep->maxxfer) +
2330             ((ep->total_len % ep->maxxfer) ? 1 : 0);
2331         if (!ep->desc_cnt)
2332                 ep->desc_cnt = 1;
2333
2334         dma_desc = ep->desc_addr;
2335         xfer_est = ep->total_len;
2336         offset = 0;
2337         for (i = 0; i < ep->desc_cnt; ++i) {
2338                 /** DMA Descriptor Setup */
2339                 if (xfer_est > ep->maxxfer) {
2340                         dma_desc->status.b.bs = BS_HOST_BUSY;
2341                         dma_desc->status.b.l = 0;
2342                         dma_desc->status.b.ioc = 0;
2343                         dma_desc->status.b.sp = 0;
2344                         dma_desc->status.b.bytes = ep->maxxfer;
2345                         dma_desc->buf = ep->dma_addr + offset;
2346                         dma_desc->status.b.bs = BS_HOST_READY;
2347
2348                         xfer_est -= ep->maxxfer;
2349                         offset += ep->maxxfer;
2350                 } else {
2351                         dma_desc->status.b.bs = BS_HOST_BUSY;
2352                         dma_desc->status.b.l = 1;
2353                         dma_desc->status.b.ioc = 1;
2354                         if (ep->is_in) {
2355                                 dma_desc->status.b.sp =
2356                                     (xfer_est %
2357                                      ep->maxpacket) ? 1 : ((ep->
2358                                                             sent_zlp) ? 1 : 0);
2359                                 dma_desc->status.b.bytes = xfer_est;
2360                         } else {
2361                                 dma_desc->status.b.bytes =
2362                                     xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
2363                         }
2364
2365                         dma_desc->buf = ep->dma_addr + offset;
2366                         dma_desc->status.b.bs = BS_HOST_READY;
2367                 }
2368                 dma_desc++;
2369         }
2370 }
2371
2372 /**
2373  * This function does the setup for a data transfer for an EP and
2374  * starts the transfer.  For an IN transfer, the packets will be
2375  * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
2376  * the packets are unloaded from the Rx FIFO in the ISR.  the ISR.
2377  *
2378  * @param core_if Programming view of DWC_otg controller.
2379  * @param ep The EP to start the transfer on.
2380  */
2381
2382 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2383 {
2384         depctl_data_t depctl;
2385         deptsiz_data_t deptsiz;
2386         gintmsk_data_t intr_mask = {.d32 = 0 };
2387
2388         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
2389         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
2390                     "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
2391                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
2392                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
2393                     ep->total_len);
2394         /* IN endpoint */
2395         if (ep->is_in == 1) {
2396                 dwc_otg_dev_in_ep_regs_t *in_regs =
2397                     core_if->dev_if->in_ep_regs[ep->num];
2398
2399                 gnptxsts_data_t gtxstatus;
2400
2401                 gtxstatus.d32 =
2402                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2403
2404                 if (core_if->en_multiple_tx_fifo == 0
2405                     && gtxstatus.b.nptxqspcavail == 0) {
2406 #ifdef DEBUG
2407                         DWC_DEBUGPL(DBG_CIL,"TX Queue Full (0x%0x)\n", gtxstatus.d32);
2408 #endif
2409                         return;
2410                 }
2411
2412                 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
2413                 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
2414
2415                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
2416                     ep->maxxfer : (ep->total_len - ep->xfer_len);
2417
2418                 /* Zero Length Packet? */
2419                 if ((ep->xfer_len - ep->xfer_count) == 0) {
2420                         deptsiz.b.xfersize = 0;
2421                         deptsiz.b.pktcnt = 1;
2422                 } else {
2423                         /* Program the transfer size and packet count
2424                          *      as follows: xfersize = N * maxpacket +
2425                          *      short_packet pktcnt = N + (short_packet
2426                          *      exist ? 1 : 0)
2427                          */
2428                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
2429                         deptsiz.b.pktcnt =
2430                             (ep->xfer_len - ep->xfer_count - 1 +
2431                              ep->maxpacket) / ep->maxpacket;
2432                 }
2433
2434                 /* Write the DMA register */
2435                 if (core_if->dma_enable) {
2436                         if (core_if->dma_desc_enable == 0) {
2437                                 dwc_write_reg32(&in_regs->dieptsiz,
2438                                                 deptsiz.d32);
2439                                 dwc_write_reg32(&(in_regs->diepdma),
2440                                                 (uint32_t) ep->dma_addr);
2441                         } else {
2442 #ifdef DWC_UTE_CFI
2443                                 /* The descriptor chain should be already initialized by now */
2444                                 if (ep->buff_mode != BM_STANDARD) {
2445                                         dwc_write_reg32(&in_regs->diepdma,
2446                                                         ep->descs_dma_addr);
2447                                 } else {
2448 #endif
2449                                         init_dma_desc_chain(core_if, ep);
2450                                         /** DIEPDMAn Register write */
2451                                         dwc_write_reg32(&in_regs->diepdma,
2452                                                         ep->dma_desc_addr);
2453 #ifdef DWC_UTE_CFI
2454                                 }
2455 #endif
2456                         }
2457                 } else {
2458                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2459                         if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
2460                                 /**
2461                                  * Enable the Non-Periodic Tx FIFO empty interrupt,
2462                                  * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
2463                                  * the data will be written into the fifo by the ISR.
2464                                  */
2465                                 if (core_if->en_multiple_tx_fifo == 0) {
2466                                         intr_mask.b.nptxfempty = 1;
2467                                         dwc_modify_reg32(&core_if->
2468                                                          core_global_regs->
2469                                                          gintmsk, intr_mask.d32,
2470                                                          intr_mask.d32);
2471                                 } else {
2472                                         /* Enable the Tx FIFO Empty Interrupt for this EP */
2473                                         if (ep->xfer_len > 0) {
2474                                                 uint32_t fifoemptymsk = 0;
2475                                                 fifoemptymsk = 1 << ep->num;
2476                                                 dwc_modify_reg32(&core_if->
2477                                                                  dev_if->
2478                                                                  dev_global_regs->
2479                                                                  dtknqr4_fifoemptymsk,
2480                                                                  0,
2481                                                                  fifoemptymsk);
2482
2483                                         }
2484                                 }
2485                         }
2486                 }
2487
2488                 /* EP enable, IN data in FIFO */
2489                 depctl.b.cnak = 1;
2490                 depctl.b.epena = 1;
2491                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2492
2493                 depctl.d32 =
2494                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
2495                 depctl.b.nextep = ep->num;
2496                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
2497                                 depctl.d32);
2498
2499         } else {
2500                 /* OUT endpoint */
2501                 dwc_otg_dev_out_ep_regs_t *out_regs =
2502                     core_if->dev_if->out_ep_regs[ep->num];
2503
2504                 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
2505                 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
2506
2507                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
2508                     ep->maxxfer : (ep->total_len - ep->xfer_len);
2509
2510                 /* Program the transfer size and packet count as follows:
2511                  *
2512                  *      pktcnt = N
2513                  *      xfersize = N * maxpacket
2514                  */
2515                 if ((ep->xfer_len - ep->xfer_count) == 0) {
2516                         /* Zero Length Packet */
2517                         deptsiz.b.xfersize = ep->maxpacket;
2518                         deptsiz.b.pktcnt = 1;
2519                 } else {
2520                         deptsiz.b.pktcnt =
2521                             (ep->xfer_len - ep->xfer_count +
2522                              (ep->maxpacket - 1)) / ep->maxpacket;
2523                         ep->xfer_len =
2524                             deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
2525                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
2526                 }
2527
2528                 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
2529                             ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
2530
2531                 if (core_if->dma_enable) {
2532                         if (!core_if->dma_desc_enable) {
2533                                 dwc_write_reg32(&out_regs->doeptsiz,
2534                                                 deptsiz.d32);
2535
2536                                 dwc_write_reg32(&(out_regs->doepdma),
2537                                                 (uint32_t) ep->dma_addr);
2538                         } else {
2539 #ifdef DWC_UTE_CFI
2540                                 /* The descriptor chain should be already initialized by now */
2541                                 if (ep->buff_mode != BM_STANDARD) {
2542                                         dwc_write_reg32(&out_regs->doepdma,
2543                                                         ep->descs_dma_addr);
2544                                 } else {
2545 #endif
2546
2547                                         init_dma_desc_chain(core_if, ep);
2548
2549                                 /** DOEPDMAn Register write */
2550                                         dwc_write_reg32(&out_regs->doepdma,
2551                                                         ep->dma_desc_addr);
2552 #ifdef DWC_UTE_CFI
2553                                 }
2554 #endif
2555                         }
2556                 } else {
2557                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2558                 }
2559
2560                 /* EP enable */
2561                 depctl.b.cnak = 1;
2562                 depctl.b.epena = 1;
2563
2564                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
2565
2566                 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
2567                             dwc_read_reg32(&out_regs->doepctl),
2568                             dwc_read_reg32(&out_regs->doeptsiz));
2569                 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
2570                             dwc_read_reg32(&core_if->dev_if->dev_global_regs->
2571                                            daintmsk),
2572                             dwc_read_reg32(&core_if->core_global_regs->
2573                                            gintmsk));
2574         }
2575 }
2576
2577 /**
2578  * This function setup a zero length transfer in Buffer DMA and
2579  * Slave modes for usb requests with zero field set
2580  *
2581  * @param core_if Programming view of DWC_otg controller.
2582  * @param ep The EP to start the transfer on.
2583  *
2584  */
2585 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2586 {
2587
2588         depctl_data_t depctl;
2589         deptsiz_data_t deptsiz;
2590         gintmsk_data_t intr_mask = {.d32 = 0 };
2591
2592         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
2593         DWC_DEBUGPL(DBG_CIL,"zero length transfer is called\n");
2594
2595         /* IN endpoint */
2596         if (ep->is_in == 1) {
2597                 dwc_otg_dev_in_ep_regs_t *in_regs =
2598                     core_if->dev_if->in_ep_regs[ep->num];
2599
2600                 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
2601                 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
2602
2603                 deptsiz.b.xfersize = 0;
2604                 deptsiz.b.pktcnt = 1;
2605
2606                 /* Write the DMA register */
2607                 if (core_if->dma_enable) {
2608                         if (core_if->dma_desc_enable == 0) {
2609                                 dwc_write_reg32(&in_regs->dieptsiz,
2610                                                 deptsiz.d32);
2611                                 dwc_write_reg32(&(in_regs->diepdma),
2612                                                 (uint32_t) ep->dma_addr);
2613                         }
2614                 } else {
2615                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2616                         /**
2617                          * Enable the Non-Periodic Tx FIFO empty interrupt,
2618                          * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
2619                          * the data will be written into the fifo by the ISR.
2620                          */
2621                         if (core_if->en_multiple_tx_fifo == 0) {
2622                                 intr_mask.b.nptxfempty = 1;
2623                                 dwc_modify_reg32(&core_if->core_global_regs->
2624                                                  gintmsk, intr_mask.d32,
2625                                                  intr_mask.d32);
2626                         } else {
2627                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
2628                                 if (ep->xfer_len > 0) {
2629                                         uint32_t fifoemptymsk = 0;
2630                                         fifoemptymsk = 1 << ep->num;
2631                                         dwc_modify_reg32(&core_if->dev_if->
2632                                                          dev_global_regs->
2633                                                          dtknqr4_fifoemptymsk,
2634                                                          0, fifoemptymsk);
2635                                 }
2636                         }
2637                 }
2638
2639                 /* EP enable, IN data in FIFO */
2640                 depctl.b.cnak = 1;
2641                 depctl.b.epena = 1;
2642                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2643
2644                 depctl.d32 =
2645                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
2646                 depctl.b.nextep = ep->num;
2647                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
2648                                 depctl.d32);
2649
2650         } else {
2651                 /* OUT endpoint */
2652                 dwc_otg_dev_out_ep_regs_t *out_regs =
2653                     core_if->dev_if->out_ep_regs[ep->num];
2654
2655                 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
2656                 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
2657
2658                 /* Zero Length Packet */
2659                 deptsiz.b.xfersize = ep->maxpacket;
2660                 deptsiz.b.pktcnt = 1;
2661
2662                 if (core_if->dma_enable) {
2663                         if (!core_if->dma_desc_enable) {
2664                                 dwc_write_reg32(&out_regs->doeptsiz,
2665                                                 deptsiz.d32);
2666
2667                                 dwc_write_reg32(&(out_regs->doepdma),
2668                                                 (uint32_t) ep->dma_addr);
2669                         }
2670                 } else {
2671                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2672                 }
2673
2674                 /* EP enable */
2675                 depctl.b.cnak = 1;
2676                 depctl.b.epena = 1;
2677
2678                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
2679
2680         }
2681 }
2682
2683 /**
2684  * This function does the setup for a data transfer for EP0 and starts
2685  * the transfer.  For an IN transfer, the packets will be loaded into
2686  * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
2687  * unloaded from the Rx FIFO in the ISR.
2688  *
2689  * @param core_if Programming view of DWC_otg controller.
2690  * @param ep The EP0 data.
2691  */
2692 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2693 {
2694         depctl_data_t depctl;
2695         deptsiz0_data_t deptsiz;
2696         gintmsk_data_t intr_mask = {.d32 = 0 };
2697         dwc_otg_dma_desc_t *dma_desc;
2698
2699         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
2700                     "xfer_buff=%p start_xfer_buff=%p \n",
2701                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
2702                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
2703
2704         ep->total_len = ep->xfer_len;
2705
2706         /* IN endpoint */
2707         if (ep->is_in == 1) {
2708                 dwc_otg_dev_in_ep_regs_t *in_regs =
2709                     core_if->dev_if->in_ep_regs[0];
2710
2711                 gnptxsts_data_t gtxstatus;
2712
2713                 gtxstatus.d32 =
2714                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2715
2716                 if (core_if->en_multiple_tx_fifo == 0
2717                     && gtxstatus.b.nptxqspcavail == 0) {
2718 #ifdef DEBUG
2719                         deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2720                         DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
2721                                     dwc_read_reg32(&in_regs->diepctl));
2722                         DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
2723                                     deptsiz.d32,
2724                                     deptsiz.b.xfersize, deptsiz.b.pktcnt);
2725                         DWC_DEBUGPL(DBG_CIL,"TX Queue or FIFO Full (0x%0x)\n",
2726                                    gtxstatus.d32);
2727 #endif
2728                         return;
2729                 }
2730
2731                 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
2732                 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2733
2734                 /* Zero Length Packet? */
2735                 if (ep->xfer_len == 0) {
2736                         deptsiz.b.xfersize = 0;
2737                         deptsiz.b.pktcnt = 1;
2738                 } else {
2739                         /* Program the transfer size and packet count
2740                          *      as follows: xfersize = N * maxpacket +
2741                          *      short_packet pktcnt = N + (short_packet
2742                          *      exist ? 1 : 0)
2743                          */
2744                         if (ep->xfer_len > ep->maxpacket) {
2745                                 ep->xfer_len = ep->maxpacket;
2746                                 deptsiz.b.xfersize = ep->maxpacket;
2747                         } else {
2748                                 deptsiz.b.xfersize = ep->xfer_len;
2749                         }
2750                         deptsiz.b.pktcnt = 1;
2751
2752                 }
2753                 DWC_DEBUGPL(DBG_PCDV,
2754                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
2755                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
2756                             deptsiz.d32);
2757
2758                 /* Write the DMA register */
2759                 if (core_if->dma_enable) {
2760                         if (core_if->dma_desc_enable == 0) {
2761                                 dwc_write_reg32(&in_regs->dieptsiz,
2762                                                 deptsiz.d32);
2763
2764                                 dwc_write_reg32(&(in_regs->diepdma),
2765                                                 (uint32_t) ep->dma_addr);
2766                         } else {
2767                                 dma_desc = core_if->dev_if->in_desc_addr;
2768
2769                                 /** DMA Descriptor Setup */
2770                                 dma_desc->status.b.bs = BS_HOST_BUSY;
2771                                 dma_desc->status.b.l = 1;
2772                                 dma_desc->status.b.ioc = 1;
2773                                 dma_desc->status.b.sp =
2774                                     (ep->xfer_len == ep->maxpacket) ? 0 : 1;
2775                                 dma_desc->status.b.bytes = ep->xfer_len;
2776                                 dma_desc->buf = ep->dma_addr;
2777                                 dma_desc->status.b.bs = BS_HOST_READY;
2778
2779                                 /** DIEPDMA0 Register write */
2780                                 dwc_write_reg32(&in_regs->diepdma,
2781                                                 core_if->dev_if->
2782                                                 dma_in_desc_addr);
2783                         }
2784                 } else {
2785                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2786                 }
2787
2788                 /* EP enable, IN data in FIFO */
2789                 depctl.b.cnak = 1;
2790                 depctl.b.epena = 1;
2791                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2792
2793                 /**
2794                  * Enable the Non-Periodic Tx FIFO empty interrupt, the
2795                  * data will be written into the fifo by the ISR.
2796                  */
2797                 if (!core_if->dma_enable) {
2798                         if (core_if->en_multiple_tx_fifo == 0) {
2799                                 intr_mask.b.nptxfempty = 1;
2800                                 dwc_modify_reg32(&core_if->core_global_regs->
2801                                                  gintmsk, intr_mask.d32,
2802                                                  intr_mask.d32);
2803                         } else {
2804                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
2805                                 if (ep->xfer_len > 0) {
2806                                         uint32_t fifoemptymsk = 0;
2807                                         fifoemptymsk |= 1 << ep->num;
2808                                         dwc_modify_reg32(&core_if->dev_if->
2809                                                          dev_global_regs->
2810                                                          dtknqr4_fifoemptymsk,
2811                                                          0, fifoemptymsk);
2812                                 }
2813                         }
2814                 }
2815         } else {
2816                 /* OUT endpoint */
2817                 dwc_otg_dev_out_ep_regs_t *out_regs =
2818                     core_if->dev_if->out_ep_regs[0];
2819
2820                 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
2821                 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
2822
2823                 /* Program the transfer size and packet count as follows:
2824                  *      xfersize = N * (maxpacket + 4 - (maxpacket % 4))
2825                  *      pktcnt = N                                                                                      */
2826                 /* Zero Length Packet */
2827                 deptsiz.b.xfersize = ep->maxpacket;
2828                 deptsiz.b.pktcnt = 1;
2829
2830                 DWC_DEBUGPL(DBG_PCDV, "len=%d  xfersize=%d pktcnt=%d\n",
2831                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
2832
2833                 if (core_if->dma_enable) {
2834                         if (!core_if->dma_desc_enable) {
2835                                 dwc_write_reg32(&out_regs->doeptsiz,
2836                                                 deptsiz.d32);
2837
2838                                 dwc_write_reg32(&(out_regs->doepdma),
2839                                                 (uint32_t) ep->dma_addr);
2840                         } else {
2841                                 dma_desc = core_if->dev_if->out_desc_addr;
2842
2843                                 /** DMA Descriptor Setup */
2844                                 dma_desc->status.b.bs = BS_HOST_BUSY;
2845                                 dma_desc->status.b.l = 1;
2846                                 dma_desc->status.b.ioc = 1;
2847                                 dma_desc->status.b.bytes = ep->maxpacket;
2848                                 dma_desc->buf = ep->dma_addr;
2849                                 dma_desc->status.b.bs = BS_HOST_READY;
2850
2851                                 /** DOEPDMA0 Register write */
2852                                 dwc_write_reg32(&out_regs->doepdma,
2853                                                 core_if->dev_if->
2854                                                 dma_out_desc_addr);
2855                         }
2856                 } else {
2857                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2858                 }
2859
2860                 /* EP enable */
2861                 depctl.b.cnak = 1;
2862                 depctl.b.epena = 1;
2863                 dwc_write_reg32(&(out_regs->doepctl), depctl.d32);
2864         }
2865 }
2866
2867 /**
2868  * This function continues control IN transfers started by
2869  * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
2870  * single packet.  NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
2871  * bit for the packet count.
2872  *
2873  * @param core_if Programming view of DWC_otg controller.
2874  * @param ep The EP0 data.
2875  */
2876 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
2877 {
2878         depctl_data_t depctl;
2879         deptsiz0_data_t deptsiz;
2880         gintmsk_data_t intr_mask = {.d32 = 0 };
2881         dwc_otg_dma_desc_t *dma_desc;
2882
2883         if (ep->is_in == 1) {
2884                 dwc_otg_dev_in_ep_regs_t *in_regs =
2885                     core_if->dev_if->in_ep_regs[0];
2886                 gnptxsts_data_t tx_status = {.d32 = 0 };
2887
2888                 tx_status.d32 =
2889                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
2890                 /** @todo Should there be check for room in the Tx
2891                  * Status Queue.  If not remove the code above this comment. */
2892
2893                 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
2894                 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
2895
2896                 /* Program the transfer size and packet count
2897                  *      as follows: xfersize = N * maxpacket +
2898                  *      short_packet pktcnt = N + (short_packet
2899                  *      exist ? 1 : 0)
2900                  */
2901
2902                 if (core_if->dma_desc_enable == 0) {
2903                         deptsiz.b.xfersize =
2904                             (ep->total_len - ep->xfer_count) >
2905                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
2906                                                              ep->xfer_count);
2907                         deptsiz.b.pktcnt = 1;
2908                         if (core_if->dma_enable == 0) {
2909                                 ep->xfer_len += deptsiz.b.xfersize;
2910                         } else {
2911                                 ep->xfer_len = deptsiz.b.xfersize;
2912                         }
2913                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
2914                 } else {
2915                         ep->xfer_len =
2916                             (ep->total_len - ep->xfer_count) >
2917                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
2918                                                              ep->xfer_count);
2919
2920                         dma_desc = core_if->dev_if->in_desc_addr;
2921
2922                         /** DMA Descriptor Setup */
2923                         dma_desc->status.b.bs = BS_HOST_BUSY;
2924                         dma_desc->status.b.l = 1;
2925                         dma_desc->status.b.ioc = 1;
2926                         dma_desc->status.b.sp =
2927                             (ep->xfer_len == ep->maxpacket) ? 0 : 1;
2928                         dma_desc->status.b.bytes = ep->xfer_len;
2929                         dma_desc->buf = ep->dma_addr;
2930                         dma_desc->status.b.bs = BS_HOST_READY;
2931
2932                         /** DIEPDMA0 Register write */
2933                         dwc_write_reg32(&in_regs->diepdma,
2934                                         core_if->dev_if->dma_in_desc_addr);
2935                 }
2936
2937                 DWC_DEBUGPL(DBG_PCDV,
2938                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
2939                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
2940                             deptsiz.d32);
2941
2942                 /* Write the DMA register */
2943                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
2944                         if (core_if->dma_desc_enable == 0)
2945                                 dwc_write_reg32(&(in_regs->diepdma),
2946                                                 (uint32_t) ep->dma_addr);
2947                 }
2948
2949                 /* EP enable, IN data in FIFO */
2950                 depctl.b.cnak = 1;
2951                 depctl.b.epena = 1;
2952                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
2953
2954                 /**
2955                  * Enable the Non-Periodic Tx FIFO empty interrupt, the
2956                  * data will be written into the fifo by the ISR.
2957                  */
2958                 if (!core_if->dma_enable) {
2959                         if (core_if->en_multiple_tx_fifo == 0) {
2960                                 /* First clear it from GINTSTS */
2961                                 intr_mask.b.nptxfempty = 1;
2962                                 dwc_modify_reg32(&core_if->core_global_regs->
2963                                                  gintmsk, intr_mask.d32,
2964                                                  intr_mask.d32);
2965
2966                         } else {
2967                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
2968                                 if (ep->xfer_len > 0) {
2969                                         uint32_t fifoemptymsk = 0;
2970                                         fifoemptymsk |= 1 << ep->num;
2971                                         dwc_modify_reg32(&core_if->dev_if->
2972                                                          dev_global_regs->
2973                                                          dtknqr4_fifoemptymsk,
2974                                                          0, fifoemptymsk);
2975                                 }
2976                         }
2977                 }
2978         } else {
2979                 dwc_otg_dev_out_ep_regs_t *out_regs =
2980                     core_if->dev_if->out_ep_regs[0];
2981
2982                 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
2983                 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
2984
2985                 /* Program the transfer size and packet count
2986                  *      as follows: xfersize = N * maxpacket +
2987                  *      short_packet pktcnt = N + (short_packet
2988                  *      exist ? 1 : 0)
2989                  */
2990                 deptsiz.b.xfersize = ep->maxpacket;
2991                 deptsiz.b.pktcnt = 1;
2992
2993                 if (core_if->dma_desc_enable == 0) {
2994                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
2995                 } else {
2996                         dma_desc = core_if->dev_if->out_desc_addr;
2997
2998                         /** DMA Descriptor Setup */
2999                         dma_desc->status.b.bs = BS_HOST_BUSY;
3000                         dma_desc->status.b.l = 1;
3001                         dma_desc->status.b.ioc = 1;
3002                         dma_desc->status.b.bytes = ep->maxpacket;
3003                         dma_desc->buf = ep->dma_addr;
3004                         dma_desc->status.b.bs = BS_HOST_READY;
3005
3006                         /** DOEPDMA0 Register write */
3007                         dwc_write_reg32(&out_regs->doepdma,
3008                                         core_if->dev_if->dma_out_desc_addr);
3009                 }
3010
3011                 DWC_DEBUGPL(DBG_PCDV,
3012                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
3013                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
3014                             deptsiz.d32);
3015
3016                 /* Write the DMA register */
3017                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
3018                         if (core_if->dma_desc_enable == 0)
3019                                 dwc_write_reg32(&(out_regs->doepdma),
3020                                                 (uint32_t) ep->dma_addr);
3021                 }
3022
3023                 /* EP enable, IN data in FIFO */
3024                 depctl.b.cnak = 1;
3025                 depctl.b.epena = 1;
3026                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
3027
3028         }
3029 }
3030
3031 #ifdef DEBUG
3032 void dump_msg(const u8 * buf, unsigned int length)
3033 {
3034         unsigned int start, num, i;
3035         char line[52], *p;
3036
3037         if (length >= 512)
3038                 return;
3039         start = 0;
3040         while (length > 0) {
3041                 num = length < 16u ? length : 16u;
3042                 p = line;
3043                 for (i = 0; i < num; ++i) {
3044                         if (i == 8)
3045                                 *p++ = ' ';
3046                         DWC_SPRINTF(p, " %02x", buf[i]);
3047                         p += 3;
3048                 }
3049                 *p = 0;
3050                 DWC_DEBUGPL(DBG_CIL,"%6x: %s\n", start, line);
3051                 buf += num;
3052                 start += num;
3053                 length -= num;
3054         }
3055 }
3056 #else
3057 static inline void dump_msg(const u8 * buf, unsigned int length)
3058 {
3059 }
3060 #endif
3061
3062 /**
3063  * This function writes a packet into the Tx FIFO associated with the
3064  * EP.  For non-periodic EPs the non-periodic Tx FIFO is written.  For
3065  * periodic EPs the periodic Tx FIFO associated with the EP is written
3066  * with all packets for the next micro-frame.
3067  *
3068  * @param core_if Programming view of DWC_otg controller.
3069  * @param ep The EP to write packet for.
3070  * @param dma Indicates if DMA is being used.
3071  */
3072 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
3073                              int dma)
3074 {
3075         /**
3076          * The buffer is padded to DWORD on a per packet basis in
3077          * slave/dma mode if the MPS is not DWORD aligned.      The last
3078          * packet, if short, is also padded to a multiple of DWORD.
3079          *
3080          * ep->xfer_buff always starts DWORD aligned in memory and is a
3081          * multiple of DWORD in length
3082          *
3083          * ep->xfer_len can be any number of bytes
3084          *
3085          * ep->xfer_count is a multiple of ep->maxpacket until the last
3086          *      packet
3087          *
3088          * FIFO access is DWORD */
3089
3090         uint32_t i;
3091         uint32_t byte_count;
3092         uint32_t dword_count;
3093         uint32_t *fifo;
3094         uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
3095
3096         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
3097                     ep);
3098         if (ep->xfer_count >= ep->xfer_len) {
3099                 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
3100                 return;
3101         }
3102
3103         /* Find the byte length of the packet either short packet or MPS */
3104         if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
3105                 byte_count = ep->xfer_len - ep->xfer_count;
3106         } else {
3107                 byte_count = ep->maxpacket;
3108         }
3109
3110         /* Find the DWORD length, padded by extra bytes as neccessary if MPS
3111          * is not a multiple of DWORD */
3112         dword_count = (byte_count + 3) / 4;
3113
3114 #ifdef VERBOSE
3115         dump_msg(ep->xfer_buff, byte_count);
3116 #endif
3117
3118         /**@todo NGS Where are the Periodic Tx FIFO addresses
3119          * intialized?  What should this be? */
3120
3121         fifo = core_if->data_fifo[ep->num];
3122
3123         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
3124                     fifo, data_buff, *data_buff, byte_count);
3125
3126         if (!dma) {
3127                 for (i = 0; i < dword_count; i++, data_buff++) {
3128                         dwc_write_reg32(fifo, *data_buff);
3129                 }
3130         }
3131
3132         ep->xfer_count += byte_count;
3133         ep->xfer_buff += byte_count;
3134         ep->dma_addr += byte_count;
3135 }
3136
3137 /**
3138  * Set the EP STALL.
3139  *
3140  * @param core_if Programming view of DWC_otg controller.
3141  * @param ep The EP to set the stall on.
3142  */
3143 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3144 {
3145         depctl_data_t depctl;
3146         volatile uint32_t *depctl_addr;
3147
3148         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
3149                     (ep->is_in ? "IN" : "OUT"));
3150
3151         if (ep->is_in == 1) {
3152                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
3153                 depctl.d32 = dwc_read_reg32(depctl_addr);
3154
3155                 /* set the disable and stall bits */
3156                 if (depctl.b.epena) {
3157                         depctl.b.epdis = 1;
3158                 }
3159                 depctl.b.stall = 1;
3160                 dwc_write_reg32(depctl_addr, depctl.d32);
3161         } else {
3162                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
3163                 depctl.d32 = dwc_read_reg32(depctl_addr);
3164
3165                 /* set the stall bit */
3166                 depctl.b.stall = 1;
3167                 dwc_write_reg32(depctl_addr, depctl.d32);
3168         }
3169
3170         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
3171
3172         return;
3173 }
3174
3175 /**
3176  * Clear the EP STALL.
3177  *
3178  * @param core_if Programming view of DWC_otg controller.
3179  * @param ep The EP to clear stall from.
3180  */
3181 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3182 {
3183         depctl_data_t depctl;
3184         volatile uint32_t *depctl_addr;
3185
3186         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
3187                     (ep->is_in ? "IN" : "OUT"));
3188
3189         if (ep->is_in == 1) {
3190                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
3191         } else {
3192                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
3193         }
3194
3195         depctl.d32 = dwc_read_reg32(depctl_addr);
3196
3197         /* clear the stall bits */
3198         depctl.b.stall = 0;
3199
3200         /*
3201          * USB Spec 9.4.5: For endpoints using data toggle, regardless
3202          * of whether an endpoint has the Halt feature set, a
3203          * ClearFeature(ENDPOINT_HALT) request always results in the
3204          * data toggle being reinitialized to DATA0.
3205          */
3206         if (ep->type == DWC_OTG_EP_TYPE_INTR ||
3207             ep->type == DWC_OTG_EP_TYPE_BULK) {
3208                 depctl.b.setd0pid = 1;  /* DATA0 */
3209         }
3210
3211         dwc_write_reg32(depctl_addr, depctl.d32);
3212         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
3213         return;
3214 }
3215
3216 /**
3217  * This function reads a packet from the Rx FIFO into the destination
3218  * buffer.      To read SETUP data use dwc_otg_read_setup_packet.
3219  *
3220  * @param core_if Programming view of DWC_otg controller.
3221  * @param dest    Destination buffer for the packet.
3222  * @param bytes  Number of bytes to copy to the destination.
3223  */
3224 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
3225                          uint8_t * dest, uint16_t bytes)
3226 {
3227         int i;
3228         int word_count = (bytes + 3) / 4;
3229
3230         volatile uint32_t *fifo = core_if->data_fifo[0];
3231         uint32_t *data_buff = (uint32_t *) dest;
3232
3233         /**
3234          * @todo Account for the case where _dest is not dword aligned. This
3235          * requires reading data from the FIFO into a uint32_t temp buffer,
3236          * then moving it into the data buffer.
3237          */
3238
3239         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
3240                     core_if, dest, bytes);
3241
3242         for (i = 0; i < word_count; i++, data_buff++) {
3243                 *data_buff = dwc_read_reg32(fifo);
3244         }
3245
3246         return;
3247 }
3248
3249 /**
3250  * This functions reads the device registers and prints them
3251  *
3252  * @param core_if Programming view of DWC_otg controller.
3253  */
3254 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
3255 {
3256         int i;
3257         volatile uint32_t *addr;
3258
3259         DWC_DEBUGPL(DBG_CIL,"Device Global Registers\n");
3260         addr = &core_if->dev_if->dev_global_regs->dcfg;
3261         DWC_DEBUGPL(DBG_CIL,"DCFG                @0x%08X : 0x%08X\n", (uint32_t) addr,
3262                    dwc_read_reg32(addr));
3263         addr = &core_if->dev_if->dev_global_regs->dctl;
3264         DWC_DEBUGPL(DBG_CIL,"DCTL                @0x%08X : 0x%08X\n", (uint32_t) addr,
3265                    dwc_read_reg32(addr));
3266         addr = &core_if->dev_if->dev_global_regs->dsts;
3267         DWC_DEBUGPL(DBG_CIL,"DSTS                @0x%08X : 0x%08X\n", (uint32_t) addr,
3268                    dwc_read_reg32(addr));
3269         addr = &core_if->dev_if->dev_global_regs->diepmsk;
3270         DWC_DEBUGPL(DBG_CIL,"DIEPMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
3271                    dwc_read_reg32(addr));
3272         addr = &core_if->dev_if->dev_global_regs->doepmsk;
3273         DWC_DEBUGPL(DBG_CIL,"DOEPMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
3274                    dwc_read_reg32(addr));
3275         addr = &core_if->dev_if->dev_global_regs->daint;
3276         DWC_DEBUGPL(DBG_CIL,"DAINT       @0x%08X : 0x%08X\n", (uint32_t) addr,
3277                    dwc_read_reg32(addr));
3278         addr = &core_if->dev_if->dev_global_regs->daintmsk;
3279         DWC_DEBUGPL(DBG_CIL,"DAINTMSK    @0x%08X : 0x%08X\n", (uint32_t) addr,
3280                    dwc_read_reg32(addr));
3281         addr = &core_if->dev_if->dev_global_regs->dtknqr1;
3282         DWC_DEBUGPL(DBG_CIL,"DTKNQR1     @0x%08X : 0x%08X\n", (uint32_t) addr,
3283                    dwc_read_reg32(addr));
3284         if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
3285                 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
3286                 DWC_DEBUGPL(DBG_CIL,"DTKNQR2     @0x%08X : 0x%08X\n",
3287                            (uint32_t) addr, dwc_read_reg32(addr));
3288         }
3289
3290         addr = &core_if->dev_if->dev_global_regs->dvbusdis;
3291         DWC_DEBUGPL(DBG_CIL,"DVBUSID     @0x%08X : 0x%08X\n", (uint32_t) addr,
3292                    dwc_read_reg32(addr));
3293
3294         addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
3295         DWC_DEBUGPL(DBG_CIL,"DVBUSPULSE @0x%08X : 0x%08X\n",
3296                    (uint32_t) addr, dwc_read_reg32(addr));
3297
3298         addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
3299         DWC_DEBUGPL(DBG_CIL,"DTKNQR3_DTHRCTL     @0x%08X : 0x%08X\n",
3300                    (uint32_t) addr, dwc_read_reg32(addr));
3301
3302         if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
3303                 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
3304                 DWC_DEBUGPL(DBG_CIL,"DTKNQR4     @0x%08X : 0x%08X\n",
3305                            (uint32_t) addr, dwc_read_reg32(addr));
3306         }
3307
3308         addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
3309         DWC_DEBUGPL(DBG_CIL,"FIFOEMPMSK  @0x%08X : 0x%08X\n", (uint32_t) addr,
3310                    dwc_read_reg32(addr));
3311
3312         addr = &core_if->dev_if->dev_global_regs->deachint;
3313         DWC_DEBUGPL(DBG_CIL,"DEACHINT    @0x%08X : 0x%08X\n", (uint32_t) addr,
3314                    dwc_read_reg32(addr));
3315         addr = &core_if->dev_if->dev_global_regs->deachintmsk;
3316         DWC_DEBUGPL(DBG_CIL,"DEACHINTMSK         @0x%08X : 0x%08X\n", (uint32_t) addr,
3317                    dwc_read_reg32(addr));
3318
3319         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3320                 addr = &core_if->dev_if->dev_global_regs->diepeachintmsk[i];
3321                 DWC_DEBUGPL(DBG_CIL,"DIEPEACHINTMSK[%d]  @0x%08X : 0x%08X\n", i,
3322                            (uint32_t) addr, dwc_read_reg32(addr));
3323         }
3324
3325         for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
3326                 addr = &core_if->dev_if->dev_global_regs->doepeachintmsk[i];
3327                 DWC_DEBUGPL(DBG_CIL,"DOEPEACHINTMSK[%d]  @0x%08X : 0x%08X\n", i,
3328                            (uint32_t) addr, dwc_read_reg32(addr));
3329         }
3330
3331         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3332                 DWC_DEBUGPL(DBG_CIL,"Device IN EP %d Registers\n", i);
3333                 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
3334                 DWC_DEBUGPL(DBG_CIL,"DIEPCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3335                            dwc_read_reg32(addr));
3336                 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
3337                 DWC_DEBUGPL(DBG_CIL,"DIEPINT     @0x%08X : 0x%08X\n", (uint32_t) addr,
3338                            dwc_read_reg32(addr));
3339                 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
3340                 DWC_DEBUGPL(DBG_CIL,"DIETSIZ     @0x%08X : 0x%08X\n", (uint32_t) addr,
3341                            dwc_read_reg32(addr));
3342                 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
3343                 DWC_DEBUGPL(DBG_CIL,"DIEPDMA     @0x%08X : 0x%08X\n", (uint32_t) addr,
3344                            dwc_read_reg32(addr));
3345                 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
3346                 DWC_DEBUGPL(DBG_CIL,"DTXFSTS     @0x%08X : 0x%08X\n", (uint32_t) addr,
3347                            dwc_read_reg32(addr));
3348                 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
3349                 DWC_DEBUGPL(DBG_CIL,"DIEPDMAB    @0x%08X : 0x%08X\n", (uint32_t) addr,
3350                            0 /*dwc_read_reg32(addr) */ );
3351         }
3352
3353         for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
3354                 DWC_DEBUGPL(DBG_CIL,"Device OUT EP %d Registers\n", i);
3355                 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
3356                 DWC_DEBUGPL(DBG_CIL,"DOEPCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3357                            dwc_read_reg32(addr));
3358                 addr = &core_if->dev_if->out_ep_regs[i]->doepfn;
3359                 DWC_DEBUGPL(DBG_CIL,"DOEPFN      @0x%08X : 0x%08X\n", (uint32_t) addr,
3360                            dwc_read_reg32(addr));
3361                 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
3362                 DWC_DEBUGPL(DBG_CIL,"DOEPINT     @0x%08X : 0x%08X\n", (uint32_t) addr,
3363                            dwc_read_reg32(addr));
3364                 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
3365                 DWC_DEBUGPL(DBG_CIL,"DOETSIZ     @0x%08X : 0x%08X\n", (uint32_t) addr,
3366                            dwc_read_reg32(addr));
3367                 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
3368                 DWC_DEBUGPL(DBG_CIL,"DOEPDMA     @0x%08X : 0x%08X\n", (uint32_t) addr,
3369                            dwc_read_reg32(addr));
3370                 if (core_if->dma_enable) {      /* Don't access this register in SLAVE mode */
3371                         addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
3372                         DWC_DEBUGPL(DBG_CIL,"DOEPDMAB    @0x%08X : 0x%08X\n",
3373                                    (uint32_t) addr, dwc_read_reg32(addr));
3374                 }
3375
3376         }
3377 }
3378
3379 /**
3380  * This functions reads the SPRAM and prints its content
3381  *
3382  * @param core_if Programming view of DWC_otg controller.
3383  */
3384 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
3385 {
3386         volatile uint8_t *addr, *start_addr, *end_addr;
3387
3388         DWC_DEBUGPL(DBG_CIL,"SPRAM Data:\n");
3389         start_addr = (void *)core_if->core_global_regs;
3390         DWC_DEBUGPL(DBG_CIL,"Base Address: 0x%8X\n", (uint32_t) start_addr);
3391         start_addr += 0x00028000;
3392         end_addr = (void *)core_if->core_global_regs;
3393         end_addr += 0x000280e0;
3394
3395         for (addr = start_addr; addr < end_addr; addr += 16) {
3396 DWC_DEBUGPL(DBG_CIL,"0x%8X:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
3397                      (uint32_t) addr, addr[0], addr[1], addr[2], addr[3],
3398                      addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
3399                      addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
3400                     );
3401         }
3402
3403         return;
3404 }
3405
3406 /**
3407  * This function reads the host registers and prints them
3408  *
3409  * @param core_if Programming view of DWC_otg controller.
3410  */
3411 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
3412 {
3413         int i;
3414         volatile uint32_t *addr;
3415
3416         DWC_DEBUGPL(DBG_CIL,"Host Global Registers\n");
3417         addr = &core_if->host_if->host_global_regs->hcfg;
3418         DWC_DEBUGPL(DBG_CIL,"HCFG                @0x%08X : 0x%08X\n", (uint32_t) addr,
3419                    dwc_read_reg32(addr));
3420         addr = &core_if->host_if->host_global_regs->hfir;
3421         DWC_DEBUGPL(DBG_CIL,"HFIR                @0x%08X : 0x%08X\n", (uint32_t) addr,
3422                    dwc_read_reg32(addr));
3423         addr = &core_if->host_if->host_global_regs->hfnum;
3424         DWC_DEBUGPL(DBG_CIL,"HFNUM       @0x%08X : 0x%08X\n", (uint32_t) addr,
3425                    dwc_read_reg32(addr));
3426         addr = &core_if->host_if->host_global_regs->hptxsts;
3427         DWC_DEBUGPL(DBG_CIL,"HPTXSTS     @0x%08X : 0x%08X\n", (uint32_t) addr,
3428                    dwc_read_reg32(addr));
3429         addr = &core_if->host_if->host_global_regs->haint;
3430         DWC_DEBUGPL(DBG_CIL,"HAINT       @0x%08X : 0x%08X\n", (uint32_t) addr,
3431                    dwc_read_reg32(addr));
3432         addr = &core_if->host_if->host_global_regs->haintmsk;
3433         DWC_DEBUGPL(DBG_CIL,"HAINTMSK    @0x%08X : 0x%08X\n", (uint32_t) addr,
3434                    dwc_read_reg32(addr));
3435         addr = core_if->host_if->hprt0;
3436         DWC_DEBUGPL(DBG_CIL,"HPRT0       @0x%08X : 0x%08X\n", (uint32_t) addr,
3437                    dwc_read_reg32(addr));
3438
3439         for (i = 0; i < core_if->core_params->host_channels; i++) {
3440                 DWC_DEBUGPL(DBG_CIL,"Host Channel %d Specific Registers\n", i);
3441                 addr = &core_if->host_if->hc_regs[i]->hcchar;
3442                 DWC_DEBUGPL(DBG_CIL,"HCCHAR      @0x%08X : 0x%08X\n", (uint32_t) addr,
3443                            dwc_read_reg32(addr));
3444                 addr = &core_if->host_if->hc_regs[i]->hcsplt;
3445                 DWC_DEBUGPL(DBG_CIL,"HCSPLT      @0x%08X : 0x%08X\n", (uint32_t) addr,
3446                            dwc_read_reg32(addr));
3447                 addr = &core_if->host_if->hc_regs[i]->hcint;
3448                 DWC_DEBUGPL(DBG_CIL,"HCINT       @0x%08X : 0x%08X\n", (uint32_t) addr,
3449                            dwc_read_reg32(addr));
3450                 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
3451                 DWC_DEBUGPL(DBG_CIL,"HCINTMSK    @0x%08X : 0x%08X\n", (uint32_t) addr,
3452                            dwc_read_reg32(addr));
3453                 addr = &core_if->host_if->hc_regs[i]->hctsiz;
3454                 DWC_DEBUGPL(DBG_CIL,"HCTSIZ      @0x%08X : 0x%08X\n", (uint32_t) addr,
3455                            dwc_read_reg32(addr));
3456                 addr = &core_if->host_if->hc_regs[i]->hcdma;
3457                 DWC_DEBUGPL(DBG_CIL,"HCDMA       @0x%08X : 0x%08X\n", (uint32_t) addr,
3458                            dwc_read_reg32(addr));
3459         }
3460         return;
3461 }
3462
3463 /**
3464  * This function reads the core global registers and prints them
3465  *
3466  * @param core_if Programming view of DWC_otg controller.
3467  */
3468 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
3469 {
3470         int i;
3471         volatile uint32_t *addr;
3472
3473         DWC_DEBUGPL(DBG_CIL,"Core Global Registers\n");
3474         addr = &core_if->core_global_regs->gotgctl;
3475         DWC_DEBUGPL(DBG_CIL,"GOTGCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3476                    dwc_read_reg32(addr));
3477         addr = &core_if->core_global_regs->gotgint;
3478         DWC_DEBUGPL(DBG_CIL,"GOTGINT     @0x%08X : 0x%08X\n", (uint32_t) addr,
3479                    dwc_read_reg32(addr));
3480         addr = &core_if->core_global_regs->gahbcfg;
3481         DWC_DEBUGPL(DBG_CIL,"GAHBCFG     @0x%08X : 0x%08X\n", (uint32_t) addr,
3482                    dwc_read_reg32(addr));
3483         addr = &core_if->core_global_regs->gusbcfg;
3484         DWC_DEBUGPL(DBG_CIL,"GUSBCFG     @0x%08X : 0x%08X\n", (uint32_t) addr,
3485                    dwc_read_reg32(addr));
3486         addr = &core_if->core_global_regs->grstctl;
3487         DWC_DEBUGPL(DBG_CIL,"GRSTCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3488                    dwc_read_reg32(addr));
3489         addr = &core_if->core_global_regs->gintsts;
3490         DWC_DEBUGPL(DBG_CIL,"GINTSTS     @0x%08X : 0x%08X\n", (uint32_t) addr,
3491                    dwc_read_reg32(addr));
3492         addr = &core_if->core_global_regs->gintmsk;
3493         DWC_DEBUGPL(DBG_CIL,"GINTMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
3494                    dwc_read_reg32(addr));
3495         addr = &core_if->core_global_regs->grxstsr;
3496         DWC_DEBUGPL(DBG_CIL,"GRXSTSR     @0x%08X : 0x%08X\n", (uint32_t) addr,
3497                    dwc_read_reg32(addr));
3498         //addr=&core_if->core_global_regs->grxstsp;
3499         //DWC_DEBUGPL(DBG_CIL,"GRXSTSP   @0x%08X : 0x%08X\n",(uint32_t)addr,dwc_read_reg32(addr));
3500         addr = &core_if->core_global_regs->grxfsiz;
3501         DWC_DEBUGPL(DBG_CIL,"GRXFSIZ     @0x%08X : 0x%08X\n", (uint32_t) addr,
3502                    dwc_read_reg32(addr));
3503         addr = &core_if->core_global_regs->gnptxfsiz;
3504         DWC_DEBUGPL(DBG_CIL,"GNPTXFSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
3505                    dwc_read_reg32(addr));
3506         addr = &core_if->core_global_regs->gnptxsts;
3507         DWC_DEBUGPL(DBG_CIL,"GNPTXSTS    @0x%08X : 0x%08X\n", (uint32_t) addr,
3508                    dwc_read_reg32(addr));
3509         addr = &core_if->core_global_regs->gi2cctl;
3510         DWC_DEBUGPL(DBG_CIL,"GI2CCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3511                    dwc_read_reg32(addr));
3512         addr = &core_if->core_global_regs->gpvndctl;
3513         DWC_DEBUGPL(DBG_CIL,"GPVNDCTL    @0x%08X : 0x%08X\n", (uint32_t) addr,
3514                    dwc_read_reg32(addr));
3515         addr = &core_if->core_global_regs->ggpio;
3516         DWC_DEBUGPL(DBG_CIL,"GGPIO       @0x%08X : 0x%08X\n", (uint32_t) addr,
3517                    dwc_read_reg32(addr));
3518         addr = &core_if->core_global_regs->guid;
3519         DWC_DEBUGPL(DBG_CIL,"GUID                @0x%08X : 0x%08X\n", (uint32_t) addr,
3520                    dwc_read_reg32(addr));
3521         addr = &core_if->core_global_regs->gsnpsid;
3522         DWC_DEBUGPL(DBG_CIL,"GSNPSID     @0x%08X : 0x%08X\n", (uint32_t) addr,
3523                    dwc_read_reg32(addr));
3524         addr = &core_if->core_global_regs->ghwcfg1;
3525         DWC_DEBUGPL(DBG_CIL,"GHWCFG1     @0x%08X : 0x%08X\n", (uint32_t) addr,
3526                    dwc_read_reg32(addr));
3527         addr = &core_if->core_global_regs->ghwcfg2;
3528         DWC_DEBUGPL(DBG_CIL,"GHWCFG2     @0x%08X : 0x%08X\n", (uint32_t) addr,
3529                    dwc_read_reg32(addr));
3530         addr = &core_if->core_global_regs->ghwcfg3;
3531         DWC_DEBUGPL(DBG_CIL,"GHWCFG3     @0x%08X : 0x%08X\n", (uint32_t) addr,
3532                    dwc_read_reg32(addr));
3533         addr = &core_if->core_global_regs->ghwcfg4;
3534         DWC_DEBUGPL(DBG_CIL,"GHWCFG4     @0x%08X : 0x%08X\n", (uint32_t) addr,
3535                    dwc_read_reg32(addr));
3536         addr = &core_if->core_global_regs->glpmcfg;
3537         DWC_DEBUGPL(DBG_CIL,"GLPMCFG     @0x%08X : 0x%08X\n", (uint32_t) addr,
3538                    dwc_read_reg32(addr));
3539         addr = &core_if->core_global_regs->hptxfsiz;
3540         DWC_DEBUGPL(DBG_CIL,"HPTXFSIZ    @0x%08X : 0x%08X\n", (uint32_t) addr,
3541                    dwc_read_reg32(addr));
3542
3543         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
3544                 addr = &core_if->core_global_regs->dptxfsiz_dieptxf[i];
3545                 DWC_DEBUGPL(DBG_CIL,"DPTXFSIZ[%d] @0x%08X : 0x%08X\n", i,
3546                            (uint32_t) addr, dwc_read_reg32(addr));
3547         }
3548         addr = core_if->pcgcctl;
3549         DWC_DEBUGPL(DBG_CIL,"PCGCCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
3550                    dwc_read_reg32(addr));
3551 }
3552
3553 /**
3554  * Flush a Tx FIFO.
3555  *
3556  * @param core_if Programming view of DWC_otg controller.
3557  * @param num Tx FIFO to flush.
3558  */
3559 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
3560 {
3561         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3562         volatile grstctl_t greset = {.d32 = 0 };
3563         int count = 0;
3564
3565         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
3566
3567         greset.b.txfflsh = 1;
3568         greset.b.txfnum = num;
3569         dwc_write_reg32(&global_regs->grstctl, greset.d32);
3570
3571         do {
3572                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3573                 if (++count > 10000) {
3574                         DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
3575                                  __func__, greset.d32,
3576                                  dwc_read_reg32(&global_regs->gnptxsts));
3577                         break;
3578                 }
3579                 dwc_udelay(1);
3580         } while (greset.b.txfflsh == 1);
3581
3582         /* Wait for 3 PHY Clocks */
3583         dwc_udelay(1);
3584 }
3585
3586 /**
3587  * Flush Rx FIFO.
3588  *
3589  * @param core_if Programming view of DWC_otg controller.
3590  */
3591 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
3592 {
3593         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3594         volatile grstctl_t greset = {.d32 = 0 };
3595         int count = 0;
3596
3597         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
3598         /*
3599          *
3600          */
3601         greset.b.rxfflsh = 1;
3602         dwc_write_reg32(&global_regs->grstctl, greset.d32);
3603
3604         do {
3605                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3606                 if (++count > 10000) {
3607                         DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
3608                                  greset.d32);
3609                         break;
3610                 }
3611                 dwc_udelay(1);
3612         } while (greset.b.rxfflsh == 1);
3613
3614         /* Wait for 3 PHY Clocks */
3615         dwc_udelay(1);
3616 }
3617
3618 /**
3619  * Do core a soft reset of the core.  Be careful with this because it
3620  * resets all the internal state machines of the core.
3621  */
3622 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
3623 {
3624         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
3625         volatile grstctl_t greset = {.d32 = 0 };
3626         int count = 0;
3627
3628         DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
3629         /* Wait for AHB master IDLE state. */
3630         do {
3631                 dwc_udelay(10);
3632                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3633                 if (++count > 100000) {
3634                         DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
3635                                  greset.d32);
3636                         return;
3637                 }
3638         }
3639         while (greset.b.ahbidle == 0);
3640
3641         /* Core Soft Reset */
3642         count = 0;
3643         greset.b.csftrst = 1;
3644         dwc_write_reg32(&global_regs->grstctl, greset.d32);
3645         do {
3646                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
3647                 if (++count > 10000) {
3648                         DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
3649                                  __func__, greset.d32);
3650                         break;
3651                 }
3652                 dwc_udelay(1);
3653         }
3654         while (greset.b.csftrst == 1);
3655
3656         /* Wait for 3 PHY Clocks */
3657         /* orignal 100ms is too long, change to 1ms, sword */
3658         dwc_mdelay(1);
3659 }
3660
3661 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
3662 {
3663         return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
3664 }
3665
3666 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
3667 {
3668         return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
3669 }
3670
3671 /**
3672  * Register HCD callbacks.      The callbacks are used to start and stop
3673  * the HCD for interrupt processing.
3674  *
3675  * @param core_if Programming view of DWC_otg controller.
3676  * @param cb the HCD callback structure.
3677  * @param p pointer to be passed to callback function (usb_hcd*).
3678  */
3679 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
3680                                         dwc_otg_cil_callbacks_t * cb, void *p)
3681 {
3682         core_if->hcd_cb = cb;
3683         cb->p = p;
3684 }
3685
3686 /**
3687  * Register PCD callbacks.      The callbacks are used to start and stop
3688  * the PCD for interrupt processing.
3689  *
3690  * @param core_if Programming view of DWC_otg controller.
3691  * @param cb the PCD callback structure.
3692  * @param p pointer to be passed to callback function (pcd*).
3693  */
3694 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
3695                                         dwc_otg_cil_callbacks_t * cb, void *p)
3696 {
3697         core_if->pcd_cb = cb;
3698         cb->p = p;
3699 }
3700
3701 #ifdef DWC_EN_ISOC
3702
3703 /**
3704  * This function writes isoc data per 1 (micro)frame into tx fifo
3705  *
3706  * @param core_if Programming view of DWC_otg controller.
3707  * @param ep The EP to start the transfer on.
3708  *
3709  */
3710 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3711 {
3712         dwc_otg_dev_in_ep_regs_t *ep_regs;
3713         dtxfsts_data_t txstatus = {.d32 = 0 };
3714         uint32_t len = 0;
3715         uint32_t dwords;
3716
3717         ep->xfer_len = ep->data_per_frame;
3718         ep->xfer_count = 0;
3719
3720         ep_regs = core_if->dev_if->in_ep_regs[ep->num];
3721
3722         len = ep->xfer_len - ep->xfer_count;
3723
3724         if (len > ep->maxpacket) {
3725                 len = ep->maxpacket;
3726         }
3727
3728         dwords = (len + 3) / 4;
3729
3730         /* While there is space in the queue and space in the FIFO and
3731          * More data to tranfer, Write packets to the Tx FIFO */
3732         txstatus.d32 =
3733             dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
3734         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
3735
3736         while (txstatus.b.txfspcavail > dwords &&
3737                ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
3738                 /* Write the FIFO */
3739                 dwc_otg_ep_write_packet(core_if, ep, 0);
3740
3741                 len = ep->xfer_len - ep->xfer_count;
3742                 if (len > ep->maxpacket) {
3743                         len = ep->maxpacket;
3744                 }
3745
3746                 dwords = (len + 3) / 4;
3747                 txstatus.d32 =
3748                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
3749                                    dtxfsts);
3750                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
3751                             txstatus.d32);
3752         }
3753 }
3754
3755 /**
3756  * This function initializes a descriptor chain for Isochronous transfer
3757  *
3758  * @param core_if Programming view of DWC_otg controller.
3759  * @param ep The EP to start the transfer on.
3760  *
3761  */
3762 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
3763                                        dwc_ep_t * ep)
3764 {
3765         deptsiz_data_t deptsiz = {.d32 = 0 };
3766         depctl_data_t depctl = {.d32 = 0 };
3767         dsts_data_t dsts = {.d32 = 0 };
3768         volatile uint32_t *addr;
3769
3770         if (ep->is_in) {
3771                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3772         } else {
3773                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3774         }
3775
3776         ep->xfer_len = ep->data_per_frame;
3777         ep->xfer_count = 0;
3778         ep->xfer_buff = ep->cur_pkt_addr;
3779         ep->dma_addr = ep->cur_pkt_dma_addr;
3780
3781         if (ep->is_in) {
3782                 /* Program the transfer size and packet count
3783                  *      as follows: xfersize = N * maxpacket +
3784                  *      short_packet pktcnt = N + (short_packet
3785                  *      exist ? 1 : 0)
3786                  */
3787                 deptsiz.b.xfersize = ep->xfer_len;
3788                 deptsiz.b.pktcnt =
3789                     (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
3790                 deptsiz.b.mc = deptsiz.b.pktcnt;
3791                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
3792                                 deptsiz.d32);
3793
3794                 /* Write the DMA register */
3795                 if (core_if->dma_enable) {
3796                         dwc_write_reg32(&
3797                                         (core_if->dev_if->in_ep_regs[ep->num]->
3798                                          diepdma), (uint32_t) ep->dma_addr);
3799                 }
3800         } else {
3801                 deptsiz.b.pktcnt =
3802                     (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
3803                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
3804
3805                 dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
3806                                 doeptsiz, deptsiz.d32);
3807
3808                 if (core_if->dma_enable) {
3809                         dwc_write_reg32(&
3810                                         (core_if->dev_if->out_ep_regs[ep->num]->
3811                                          doepdma), (uint32_t) ep->dma_addr);
3812                 }
3813         }
3814
3815         /** Enable endpoint, clear nak  */
3816
3817         depctl.d32 = 0;
3818         if (ep->bInterval == 1) {
3819                 dsts.d32 =
3820                     dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
3821                 ep->next_frame = dsts.b.soffn + ep->bInterval;
3822
3823                 if (ep->next_frame & 0x1) {
3824                         depctl.b.setd1pid = 1;
3825                 } else {
3826                         depctl.b.setd0pid = 1;
3827                 }
3828         } else {
3829                 ep->next_frame += ep->bInterval;
3830
3831                 if (ep->next_frame & 0x1) {
3832                         depctl.b.setd1pid = 1;
3833                 } else {
3834                         depctl.b.setd0pid = 1;
3835                 }
3836         }
3837         depctl.b.epena = 1;
3838         depctl.b.cnak = 1;
3839
3840         dwc_modify_reg32(addr, 0, depctl.d32);
3841         depctl.d32 = dwc_read_reg32(addr);
3842
3843         if (ep->is_in && core_if->dma_enable == 0) {
3844                 write_isoc_frame_data(core_if, ep);
3845         }
3846
3847 }
3848 #endif                          /* DWC_EN_ISOC */
3849
3850 static void dwc_otg_set_uninitialized(int32_t * p, int size)
3851 {
3852         int i;
3853         for (i = 0; i < size; i++) {
3854                 p[i] = -1;
3855         }
3856 }
3857
3858 static int dwc_otg_param_initialized(int32_t val)
3859 {
3860         return val != -1;
3861 }
3862
3863 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
3864 {
3865         int i;
3866         core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
3867         if (!core_if->core_params) {
3868                 return -DWC_E_NO_MEMORY;
3869         }
3870         dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
3871                                   sizeof(*core_if->core_params) /
3872                                   sizeof(int32_t));
3873         DWC_DEBUGPL(DBG_CIL,"Setting default values for core params\n");
3874         dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
3875         dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
3876         dwc_otg_set_param_dma_desc_enable(core_if,
3877                                           dwc_param_dma_desc_enable_default);
3878         dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
3879         dwc_otg_set_param_dma_burst_size(core_if,
3880                                          dwc_param_dma_burst_size_default);
3881         dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
3882                                                        dwc_param_host_support_fs_ls_low_power_default);
3883         dwc_otg_set_param_enable_dynamic_fifo(core_if,
3884                                               dwc_param_enable_dynamic_fifo_default);
3885         dwc_otg_set_param_data_fifo_size(core_if,
3886                                          dwc_param_data_fifo_size_default);
3887         dwc_otg_set_param_dev_rx_fifo_size(core_if,
3888                                            dwc_param_dev_rx_fifo_size_default);
3889         dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
3890                                                   dwc_param_dev_nperio_tx_fifo_size_default);
3891         dwc_otg_set_param_host_rx_fifo_size(core_if,
3892                                             dwc_param_host_rx_fifo_size_default);
3893         dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
3894                                                    dwc_param_host_nperio_tx_fifo_size_default);
3895         dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
3896                                                   dwc_param_host_perio_tx_fifo_size_default);
3897         dwc_otg_set_param_max_transfer_size(core_if,
3898                                             dwc_param_max_transfer_size_default);
3899         dwc_otg_set_param_max_packet_count(core_if,
3900                                            dwc_param_max_packet_count_default);
3901         dwc_otg_set_param_host_channels(core_if,
3902                                         dwc_param_host_channels_default);
3903         dwc_otg_set_param_dev_endpoints(core_if,
3904                                         dwc_param_dev_endpoints_default);
3905         dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
3906         dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
3907         dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
3908                                                     dwc_param_host_ls_low_power_phy_clk_default);
3909         dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
3910         dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
3911                                             dwc_param_phy_ulpi_ext_vbus_default);
3912         dwc_otg_set_param_phy_utmi_width(core_if,
3913                                          dwc_param_phy_utmi_width_default);
3914         dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
3915         dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
3916         dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
3917         dwc_otg_set_param_en_multiple_tx_fifo(core_if,
3918                                               dwc_param_en_multiple_tx_fifo_default);
3919         for (i = 0; i < 15; i++) {
3920                 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
3921                                                          dwc_param_dev_perio_tx_fifo_size_default,
3922                                                          i);
3923         }
3924
3925         for (i = 0; i < 15; i++) {
3926                 dwc_otg_set_param_dev_tx_fifo_size(core_if,
3927                                                    dwc_param_dev_tx_fifo_size_default,
3928                                                    i);
3929         }
3930         dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
3931         dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
3932         dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
3933         dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
3934         dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
3935         dwc_otg_set_param_tx_thr_length(core_if,
3936                                         dwc_param_tx_thr_length_default);
3937         dwc_otg_set_param_rx_thr_length(core_if,
3938                                         dwc_param_rx_thr_length_default);
3939         dwc_otg_set_param_ahb_thr_ratio(core_if, dwc_param_ahb_thr_ratio_default);
3940         return 0;
3941 }
3942
3943 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
3944 {
3945         return core_if->dma_enable;
3946 }
3947
3948 /* Checks if the parameter is outside of its valid range of values */
3949 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
3950                 (((_param_) < (_low_)) || \
3951                 ((_param_) > (_high_)))
3952
3953 /* Parameter access functions */
3954 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
3955 {
3956         int valid;
3957         int retval = 0;
3958         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
3959                 DWC_WARN("Wrong value for otg_cap parameter\n");
3960                 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
3961                 retval = -DWC_E_INVALID;
3962                 goto out;
3963         }
3964
3965         valid = 1;
3966         switch (val) {
3967         case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
3968                 if (core_if->hwcfg2.b.op_mode !=
3969                     DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3970                         valid = 0;
3971                 break;
3972         case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
3973                 if ((core_if->hwcfg2.b.op_mode !=
3974                      DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3975                     && (core_if->hwcfg2.b.op_mode !=
3976                         DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
3977                     && (core_if->hwcfg2.b.op_mode !=
3978                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
3979                     && (core_if->hwcfg2.b.op_mode !=
3980                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
3981                         valid = 0;
3982                 }
3983                 break;
3984         case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
3985                 /* always valid */
3986                 break;
3987         }
3988         if (!valid) {
3989                 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
3990                         DWC_ERROR
3991                             ("%d invalid for otg_cap paremter. Check HW configuration.\n",
3992                              val);
3993                 }
3994                 val =
3995                     (((core_if->hwcfg2.b.op_mode ==
3996                        DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
3997                       || (core_if->hwcfg2.b.op_mode ==
3998                           DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
3999                       || (core_if->hwcfg2.b.op_mode ==
4000                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
4001                       || (core_if->hwcfg2.b.op_mode ==
4002                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
4003                      DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
4004                      DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
4005                 retval = -DWC_E_INVALID;
4006         }
4007
4008         core_if->core_params->otg_cap = val;
4009       out:
4010         return retval;
4011 }
4012
4013 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
4014 {
4015         return core_if->core_params->otg_cap;
4016 }
4017
4018 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
4019 {
4020         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4021                 DWC_WARN("Wrong value for opt parameter\n");
4022                 return -DWC_E_INVALID;
4023         }
4024         core_if->core_params->opt = val;
4025         return 0;
4026 }
4027
4028 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
4029 {
4030         return core_if->core_params->opt;
4031 }
4032
4033 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
4034 {
4035         int retval = 0;
4036         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4037                 DWC_WARN("Wrong value for dma enable\n");
4038                 return -DWC_E_INVALID;
4039         }
4040
4041         if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
4042                 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
4043                         DWC_ERROR
4044                             ("%d invalid for dma_enable paremter. Check HW configuration.\n",
4045                              val);
4046                 }
4047                 val = 0;
4048                 retval = -DWC_E_INVALID;
4049         }
4050
4051         core_if->core_params->dma_enable = val;
4052         if (val == 0) {
4053                 dwc_otg_set_param_dma_desc_enable(core_if, 0);
4054         }
4055         return retval;
4056 }
4057
4058 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
4059 {
4060         return core_if->core_params->dma_enable;
4061 }
4062
4063 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
4064 {
4065         int retval = 0;
4066         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4067                 DWC_WARN("Wrong value for dma_enable\n");
4068                 DWC_WARN("dma_desc_enable must be 0 or 1\n");
4069                 return -DWC_E_INVALID;
4070         }
4071
4072         if ((val == 1)
4073             && ((dwc_otg_get_param_dma_enable(core_if) == 0)
4074                 || (core_if->hwcfg4.b.desc_dma == 0))) {
4075                 if (dwc_otg_param_initialized
4076                     (core_if->core_params->dma_desc_enable)) {
4077                         DWC_ERROR
4078                             ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
4079                              val);
4080                 }
4081                 val = 0;
4082                 retval = -DWC_E_INVALID;
4083         }
4084         core_if->core_params->dma_desc_enable = val;
4085         return retval;
4086 }
4087
4088 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
4089 {
4090         return core_if->core_params->dma_desc_enable;
4091 }
4092
4093 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
4094                                                    int32_t val)
4095 {
4096         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4097                 DWC_WARN("Wrong value for host_support_fs_low_power\n");
4098                 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
4099                 return -DWC_E_INVALID;
4100         }
4101         core_if->core_params->host_support_fs_ls_low_power = val;
4102         return 0;
4103 }
4104
4105 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
4106                                                        core_if)
4107 {
4108         return core_if->core_params->host_support_fs_ls_low_power;
4109 }
4110
4111 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
4112                                           int32_t val)
4113 {
4114         int retval = 0;
4115         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4116                 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
4117                 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
4118                 return -DWC_E_INVALID;
4119         }
4120
4121         if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
4122                 if (dwc_otg_param_initialized
4123                     (core_if->core_params->enable_dynamic_fifo)) {
4124                         DWC_ERROR
4125                             ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
4126                              val);
4127                 }
4128                 val = 0;
4129                 retval = -DWC_E_INVALID;
4130         }
4131         core_if->core_params->enable_dynamic_fifo = val;
4132         return retval;
4133 }
4134
4135 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
4136 {
4137         return core_if->core_params->enable_dynamic_fifo;
4138 }
4139
4140 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
4141 {
4142         int retval = 0;
4143         if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
4144                 DWC_WARN("Wrong value for data_fifo_size\n");
4145                 DWC_WARN("data_fifo_size must be 32-32768\n");
4146                 return -DWC_E_INVALID;
4147         }
4148
4149         if (val > core_if->hwcfg3.b.dfifo_depth) {
4150                 if (dwc_otg_param_initialized
4151                     (core_if->core_params->data_fifo_size)) {
4152                         DWC_ERROR
4153                             ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
4154                              val);
4155                 }
4156                 val = core_if->hwcfg3.b.dfifo_depth;
4157                 retval = -DWC_E_INVALID;
4158         }
4159
4160         core_if->core_params->data_fifo_size = val;
4161         return retval;
4162 }
4163
4164 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
4165 {
4166         return core_if->core_params->data_fifo_size;
4167 }
4168
4169 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
4170 {
4171         int retval = 0;
4172         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4173                 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
4174                 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
4175                 return -DWC_E_INVALID;
4176         }
4177
4178         if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
4179                 if(dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
4180                         DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
4181                 }
4182                 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
4183                 retval = -DWC_E_INVALID;
4184         }
4185
4186         core_if->core_params->dev_rx_fifo_size = val;
4187         return retval;
4188 }
4189
4190 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
4191 {
4192         return core_if->core_params->dev_rx_fifo_size;
4193 }
4194
4195 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4196                                               int32_t val)
4197 {
4198         int retval = 0;
4199
4200         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4201                 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
4202                 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
4203                 return -DWC_E_INVALID;
4204         }
4205
4206         if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
4207                 if (dwc_otg_param_initialized
4208                     (core_if->core_params->dev_nperio_tx_fifo_size)) {
4209                         DWC_ERROR
4210                             ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
4211                              val);
4212                 }
4213                 val =
4214                     (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
4215                      16);
4216                 retval = -DWC_E_INVALID;
4217         }
4218
4219         core_if->core_params->dev_nperio_tx_fifo_size = val;
4220         return retval;
4221 }
4222
4223 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4224 {
4225         return core_if->core_params->dev_nperio_tx_fifo_size;
4226 }
4227
4228 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
4229                                         int32_t val)
4230 {
4231         int retval = 0;
4232
4233         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4234                 DWC_WARN("Wrong value for host_rx_fifo_size\n");
4235                 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
4236                 return -DWC_E_INVALID;
4237         }
4238
4239         if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
4240                 if (dwc_otg_param_initialized
4241                     (core_if->core_params->host_rx_fifo_size)) {
4242                         DWC_ERROR
4243                             ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
4244                              val);
4245                 }
4246                 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
4247                 retval = -DWC_E_INVALID;
4248         }
4249
4250         core_if->core_params->host_rx_fifo_size = val;
4251         return retval;
4252
4253 }
4254
4255 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
4256 {
4257         return core_if->core_params->host_rx_fifo_size;
4258 }
4259
4260 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4261                                                int32_t val)
4262 {
4263         int retval = 0;
4264
4265         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4266                 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
4267                 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
4268                 return -DWC_E_INVALID;
4269         }
4270
4271         if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
4272                 if (dwc_otg_param_initialized
4273                     (core_if->core_params->host_nperio_tx_fifo_size)) {
4274                         DWC_ERROR
4275                             ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
4276                              val);
4277                 }
4278                 val =
4279                     (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
4280                      16);
4281                 retval = -DWC_E_INVALID;
4282         }
4283
4284         core_if->core_params->host_nperio_tx_fifo_size = val;
4285         return retval;
4286 }
4287
4288 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4289 {
4290         return core_if->core_params->host_nperio_tx_fifo_size;
4291 }
4292
4293 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4294                                               int32_t val)
4295 {
4296         int retval = 0;
4297         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
4298                 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
4299                 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
4300                 return -DWC_E_INVALID;
4301         }
4302
4303         if (val >
4304             ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))) {
4305                 if (dwc_otg_param_initialized
4306                     (core_if->core_params->host_perio_tx_fifo_size)) {
4307                         DWC_ERROR
4308                             ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
4309                              val);
4310                 }
4311                 val =
4312                     (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >>
4313                      16);
4314                 retval = -DWC_E_INVALID;
4315         }
4316
4317         core_if->core_params->host_perio_tx_fifo_size = val;
4318         return retval;
4319 }
4320
4321 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
4322 {
4323         return core_if->core_params->host_perio_tx_fifo_size;
4324 }
4325
4326 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
4327                                         int32_t val)
4328 {
4329         int retval = 0;
4330
4331         if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
4332                 DWC_WARN("Wrong value for max_transfer_size\n");
4333                 DWC_WARN("max_transfer_size must be 2047-524288\n");
4334                 return -DWC_E_INVALID;
4335         }
4336
4337         if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
4338                 if (dwc_otg_param_initialized
4339                     (core_if->core_params->max_transfer_size)) {
4340                         DWC_ERROR
4341                             ("%d invalid for max_transfer_size. Check HW configuration.\n",
4342                              val);
4343                 }
4344                 val =
4345                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
4346                      1);
4347                 retval = -DWC_E_INVALID;
4348         }
4349
4350         core_if->core_params->max_transfer_size = val;
4351         return retval;
4352 }
4353
4354 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
4355 {
4356         return core_if->core_params->max_transfer_size;
4357 }
4358
4359 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
4360 {
4361         int retval = 0;
4362
4363         if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
4364                 DWC_WARN("Wrong value for max_packet_count\n");
4365                 DWC_WARN("max_packet_count must be 15-511\n");
4366                 return -DWC_E_INVALID;
4367         }
4368
4369         if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
4370                 if (dwc_otg_param_initialized
4371                     (core_if->core_params->max_packet_count)) {
4372                         DWC_ERROR
4373                             ("%d invalid for max_packet_count. Check HW configuration.\n",
4374                              val);
4375                 }
4376                 val =
4377                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
4378                 retval = -DWC_E_INVALID;
4379         }
4380
4381         core_if->core_params->max_packet_count = val;
4382         return retval;
4383 }
4384
4385 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
4386 {
4387         return core_if->core_params->max_packet_count;
4388 }
4389
4390 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
4391 {
4392         int retval = 0;
4393
4394         if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
4395                 DWC_WARN("Wrong value for host_channels\n");
4396                 DWC_WARN("host_channels must be 1-16\n");
4397                 return -DWC_E_INVALID;
4398         }
4399
4400         if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
4401                 if (dwc_otg_param_initialized
4402                     (core_if->core_params->host_channels)) {
4403                         DWC_ERROR
4404                             ("%d invalid for host_channels. Check HW configurations.\n",
4405                              val);
4406                 }
4407                 val = (core_if->hwcfg2.b.num_host_chan + 1);
4408                 retval = -DWC_E_INVALID;
4409         }
4410
4411         core_if->core_params->host_channels = val;
4412         return retval;
4413 }
4414
4415 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
4416 {
4417         return core_if->core_params->host_channels;
4418 }
4419
4420 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
4421 {
4422         int retval = 0;
4423
4424         if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
4425                 DWC_WARN("Wrong value for dev_endpoints\n");
4426                 DWC_WARN("dev_endpoints must be 1-15\n");
4427                 return -DWC_E_INVALID;
4428         }
4429
4430         if (val > (core_if->hwcfg2.b.num_dev_ep)) {
4431                 if (dwc_otg_param_initialized
4432                     (core_if->core_params->dev_endpoints)) {
4433                         DWC_ERROR
4434                             ("%d invalid for dev_endpoints. Check HW configurations.\n",
4435                              val);
4436                 }
4437                 val = core_if->hwcfg2.b.num_dev_ep;
4438                 retval = -DWC_E_INVALID;
4439         }
4440
4441         core_if->core_params->dev_endpoints = val;
4442         return retval;
4443 }
4444
4445 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
4446 {
4447         return core_if->core_params->dev_endpoints;
4448 }
4449
4450 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
4451 {
4452         int retval = 0;
4453         int valid = 0;
4454
4455         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
4456                 DWC_WARN("Wrong value for phy_type\n");
4457                 DWC_WARN("phy_type must be 0,1 or 2\n");
4458                 return -DWC_E_INVALID;
4459         }
4460 #ifndef NO_FS_PHY_HW_CHECKS
4461         if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
4462             ((core_if->hwcfg2.b.hs_phy_type == 1) ||
4463              (core_if->hwcfg2.b.hs_phy_type == 3))) {
4464                 valid = 1;
4465         } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
4466                    ((core_if->hwcfg2.b.hs_phy_type == 2) ||
4467                     (core_if->hwcfg2.b.hs_phy_type == 3))) {
4468                 valid = 1;
4469         } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
4470                    (core_if->hwcfg2.b.fs_phy_type == 1)) {
4471                 valid = 1;
4472         }
4473         if (!valid) {
4474                 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
4475                         DWC_ERROR
4476                             ("%d invalid for phy_type. Check HW configurations.\n",
4477                              val);
4478                 }
4479                 if (core_if->hwcfg2.b.hs_phy_type) {
4480                         if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
4481                             (core_if->hwcfg2.b.hs_phy_type == 1)) {
4482                                 val = DWC_PHY_TYPE_PARAM_UTMI;
4483                         } else {
4484                                 val = DWC_PHY_TYPE_PARAM_ULPI;
4485                         }
4486                 }
4487                 retval = -DWC_E_INVALID;
4488         }
4489 #endif
4490         core_if->core_params->phy_type = val;
4491         return retval;
4492 }
4493
4494 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
4495 {
4496         return core_if->core_params->phy_type;
4497 }
4498
4499 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
4500 {
4501         int retval = 0;
4502         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4503                 DWC_WARN("Wrong value for speed parameter\n");
4504                 DWC_WARN("max_speed parameter must be 0 or 1\n");
4505                 return -DWC_E_INVALID;
4506         }
4507         if ((val == 0)
4508             && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
4509                 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
4510                         DWC_ERROR
4511                             ("%d invalid for speed paremter. Check HW configuration.\n",
4512                              val);
4513                 }
4514                 val =
4515                     (dwc_otg_get_param_phy_type(core_if) ==
4516                      DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
4517                 retval = -DWC_E_INVALID;
4518         }
4519         core_if->core_params->speed = val;
4520         return retval;
4521 }
4522
4523 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
4524 {
4525         return core_if->core_params->speed;
4526 }
4527
4528 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
4529                                                 int32_t val)
4530 {
4531         int retval = 0;
4532
4533         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4534                 DWC_WARN
4535                     ("Wrong value for host_ls_low_power_phy_clk parameter\n");
4536                 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
4537                 return -DWC_E_INVALID;
4538         }
4539
4540         if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
4541             && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
4542                 if(dwc_otg_param_initialized(core_if->core_params->host_ls_low_power_phy_clk)) {
4543                         DWC_ERROR("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
4544                      val);
4545                 }
4546                 val =
4547                     (dwc_otg_get_param_phy_type(core_if) ==
4548                      DWC_PHY_TYPE_PARAM_FS) ?
4549                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
4550                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
4551                 retval = -DWC_E_INVALID;
4552         }
4553
4554         core_if->core_params->host_ls_low_power_phy_clk = val;
4555         return retval;
4556 }
4557
4558 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
4559 {
4560         return core_if->core_params->host_ls_low_power_phy_clk;
4561 }
4562
4563 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
4564 {
4565         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4566                 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
4567                 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
4568                 return -DWC_E_INVALID;
4569         }
4570
4571         core_if->core_params->phy_ulpi_ddr = val;
4572         return 0;
4573 }
4574
4575 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
4576 {
4577         return core_if->core_params->phy_ulpi_ddr;
4578 }
4579
4580 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
4581                                         int32_t val)
4582 {
4583         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4584                 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
4585                 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
4586                 return -DWC_E_INVALID;
4587         }
4588
4589         core_if->core_params->phy_ulpi_ext_vbus = val;
4590         return 0;
4591 }
4592
4593 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
4594 {
4595         return core_if->core_params->phy_ulpi_ext_vbus;
4596 }
4597
4598 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
4599 {
4600         if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
4601                 DWC_WARN("Wrong valaue for phy_utmi_width\n");
4602                 DWC_WARN("phy_utmi_width must be 8 or 16\n");
4603                 return -DWC_E_INVALID;
4604         }
4605
4606         core_if->core_params->phy_utmi_width = val;
4607         return 0;
4608 }
4609
4610 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
4611 {
4612         return core_if->core_params->phy_utmi_width;
4613 }
4614
4615 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
4616 {
4617         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4618                 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
4619                 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
4620                 return -DWC_E_INVALID;
4621         }
4622
4623         core_if->core_params->ulpi_fs_ls = val;
4624         return 0;
4625 }
4626
4627 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
4628 {
4629         return core_if->core_params->ulpi_fs_ls;
4630 }
4631
4632 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
4633 {
4634         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4635                 DWC_WARN("Wrong valaue for ts_dline\n");
4636                 DWC_WARN("ts_dline must be 0 or 1\n");
4637                 return -DWC_E_INVALID;
4638         }
4639
4640         core_if->core_params->ts_dline = val;
4641         return 0;
4642 }
4643
4644 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
4645 {
4646         return core_if->core_params->ts_dline;
4647 }
4648
4649 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
4650 {
4651         int retval = 0;
4652         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4653                 DWC_WARN("Wrong valaue for i2c_enable\n");
4654                 DWC_WARN("i2c_enable must be 0 or 1\n");
4655                 return -DWC_E_INVALID;
4656         }
4657 #ifndef NO_FS_PHY_HW_CHECK
4658         if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
4659                 if(dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
4660                         DWC_ERROR("%d invalid for i2c_enable. Check HW configuration.\n",
4661                                         val);
4662                 }
4663                 val = 0;
4664                 retval = -DWC_E_INVALID;
4665         }
4666 #endif
4667
4668         core_if->core_params->i2c_enable = val;
4669         return retval;
4670 }
4671
4672 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
4673 {
4674         return core_if->core_params->i2c_enable;
4675 }
4676
4677 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4678                                              int32_t val, int fifo_num)
4679 {
4680         int retval = 0;
4681
4682         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
4683                 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
4684                 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
4685                 return -DWC_E_INVALID;
4686         }
4687
4688         if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
4689                 if(dwc_otg_param_initialized(core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
4690                         DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
4691                                         val, fifo_num);
4692                 }
4693                 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
4694                 retval = -DWC_E_INVALID;
4695         }
4696
4697         core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
4698         return retval;
4699 }
4700
4701 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
4702                                                  int fifo_num)
4703 {
4704         return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
4705 }
4706
4707 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
4708                                           int32_t val)
4709 {
4710         int retval = 0;
4711         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4712                 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
4713                 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
4714                 return -DWC_E_INVALID;
4715         }
4716
4717         if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
4718                 if(dwc_otg_param_initialized(core_if->core_params->en_multiple_tx_fifo)) {
4719                         DWC_ERROR("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
4720                                         val);
4721                 }
4722                 val = 0;
4723                 retval = -DWC_E_INVALID;
4724         }
4725
4726         core_if->core_params->en_multiple_tx_fifo = val;
4727         return retval;
4728 }
4729
4730 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
4731 {
4732         return core_if->core_params->en_multiple_tx_fifo;
4733 }
4734
4735 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
4736                                        int fifo_num)
4737 {
4738         int retval = 0;
4739
4740         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
4741                 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
4742                 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
4743                 return -DWC_E_INVALID;
4744         }
4745
4746         if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
4747                 if(dwc_otg_param_initialized(core_if->core_params->dev_tx_fifo_size[fifo_num])) {
4748                         DWC_ERROR("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
4749                                         val, fifo_num);
4750                 }
4751                 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
4752                 retval = -DWC_E_INVALID;
4753         }
4754
4755         core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
4756         return retval;
4757 }
4758
4759 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
4760                                            int fifo_num)
4761 {
4762         return core_if->core_params->dev_tx_fifo_size[fifo_num];
4763 }
4764
4765 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
4766 {
4767         int retval = 0;
4768
4769         if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
4770                 DWC_WARN("Wrong value for thr_ctl\n");
4771                 DWC_WARN("thr_ctl must be 0-7\n");
4772                 return -DWC_E_INVALID;
4773         }
4774
4775         if ((val != 0) &&
4776             (!dwc_otg_get_param_dma_enable(core_if) ||
4777              !core_if->hwcfg4.b.ded_fifo_en)) {
4778                 if(dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
4779                         DWC_ERROR("%d invalid for parameter thr_ctl. Check HW configuration.\n",
4780                                         val);
4781                 }
4782                 val = 0;
4783                 retval = -DWC_E_INVALID;
4784         }
4785
4786         core_if->core_params->thr_ctl = val;
4787         return retval;
4788 }
4789
4790 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
4791 {
4792         return core_if->core_params->thr_ctl;
4793 }
4794
4795 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
4796 {
4797         int retval = 0;
4798
4799         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4800                 DWC_WARN("Wrong value for lpm_enable\n");
4801                 DWC_WARN("lpm_enable must be 0 or 1\n");
4802                 return -DWC_E_INVALID;
4803         }
4804
4805         if (val && !core_if->hwcfg3.b.otg_lpm_en) {
4806                 if(dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
4807                         DWC_ERROR("%d invalid for parameter lpm_enable. Check HW configuration.\n",
4808                                         val);
4809                 }
4810                 val = 0;
4811                 retval = -DWC_E_INVALID;
4812         }
4813
4814         core_if->core_params->lpm_enable = val;
4815         return retval;
4816 }
4817
4818 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
4819 {
4820         return core_if->core_params->lpm_enable;
4821 }
4822
4823 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
4824 {
4825         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
4826                 DWC_WARN("Wrong valaue for tx_thr_length\n");
4827                 DWC_WARN("tx_thr_length must be 8 - 128\n");
4828                 return -DWC_E_INVALID;
4829         }
4830
4831         core_if->core_params->tx_thr_length = val;
4832         return 0;
4833 }
4834
4835 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
4836 {
4837         return core_if->core_params->tx_thr_length;
4838 }
4839
4840 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
4841 {
4842         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
4843                 DWC_WARN("Wrong valaue for rx_thr_length\n");
4844                 DWC_WARN("rx_thr_length must be 8 - 128\n");
4845                 return -DWC_E_INVALID;
4846         }
4847
4848         core_if->core_params->rx_thr_length = val;
4849         return 0;
4850 }
4851
4852 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
4853 {
4854         return core_if->core_params->rx_thr_length;
4855 }
4856
4857 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
4858 {
4859         if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
4860             DWC_OTG_PARAM_TEST(val, 4, 4) &&
4861             DWC_OTG_PARAM_TEST(val, 8, 8) &&
4862             DWC_OTG_PARAM_TEST(val, 16, 16) &&
4863             DWC_OTG_PARAM_TEST(val, 32, 32) &&
4864             DWC_OTG_PARAM_TEST(val, 64, 64) &&
4865             DWC_OTG_PARAM_TEST(val, 128, 128) &&
4866             DWC_OTG_PARAM_TEST(val, 256, 256)) {
4867                 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
4868                 return -DWC_E_INVALID;
4869         }
4870         core_if->core_params->dma_burst_size = val;
4871         return 0;
4872 }
4873
4874 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
4875 {
4876         return core_if->core_params->dma_burst_size;
4877 }
4878
4879 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
4880 {
4881         int retval = 0;
4882         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4883                 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
4884                 return -DWC_E_INVALID;
4885         }
4886         if (val && (core_if->snpsid < 0x4F54272A)) {
4887                 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
4888                         DWC_ERROR("%d invalid for parameter pti_enable. Check HW configuration.\n",
4889                                         val);
4890                 }
4891                 retval = -DWC_E_INVALID;
4892                 val = 0;
4893         }
4894         core_if->core_params->pti_enable = val;
4895         return retval;
4896 }
4897
4898 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
4899 {
4900         return core_if->core_params->pti_enable;
4901 }
4902
4903 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
4904 {
4905         int retval = 0;
4906         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4907                 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
4908                 return -DWC_E_INVALID;
4909         }
4910         if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
4911                 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
4912                         DWC_ERROR("%d invalid for parameter mpi_enable. Check HW configuration.\n",
4913                                         val);
4914                 }
4915                 retval = -DWC_E_INVALID;
4916                 val = 0;
4917         }
4918         core_if->core_params->mpi_enable = val;
4919         return retval;
4920 }
4921
4922 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
4923 {
4924         return core_if->core_params->mpi_enable;
4925 }
4926
4927 extern int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if,
4928                                         int32_t val)
4929 {
4930         int retval = 0;
4931         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
4932                 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
4933                 DWC_WARN("ic_usb_cap must be 0 or 1\n");
4934                 return -DWC_E_INVALID;
4935         }
4936
4937         if (val && (core_if->hwcfg3.b.otg_enable_ic_usb == 0)) {
4938                 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
4939                         DWC_ERROR("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
4940                                         val);
4941                 }
4942                 retval = -DWC_E_INVALID;
4943                 val = 0;
4944         }
4945         core_if->core_params->ic_usb_cap = val;
4946         return retval;
4947 }
4948 extern int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
4949 {
4950         return core_if->core_params->ic_usb_cap;
4951 }
4952
4953 extern int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
4954 {
4955         int retval = 0;
4956         int valid = 1;
4957
4958         if(DWC_OTG_PARAM_TEST(val, 0, 3)) {
4959                 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
4960                 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
4961                 return -DWC_E_INVALID;
4962         }
4963
4964         if(val && (core_if->snpsid < 0x4F54281A || !dwc_otg_get_param_thr_ctl(core_if))) {
4965                 valid = 0;
4966         } else if(val && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) < 4)) {
4967                 valid = 0;
4968         }
4969         if(valid == 0) {
4970                 if(dwc_otg_param_initialized(core_if->core_params->ahb_thr_ratio)) {
4971                         DWC_ERROR("%d invalid for parameter ahb_thr_ratio. Chack HW configuration.\n", val);
4972                 }
4973                 retval = -DWC_E_INVALID;
4974                 val = 0;
4975         }
4976
4977         core_if->core_params->ahb_thr_ratio = val;
4978         return retval;
4979 }
4980 extern int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
4981 {
4982         return core_if->core_params->ahb_thr_ratio;
4983 }
4984
4985
4986 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
4987 {
4988         gotgctl_data_t otgctl;
4989         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
4990         return otgctl.b.hstnegscs;
4991 }
4992
4993 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
4994 {
4995         gotgctl_data_t otgctl;
4996         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
4997         return otgctl.b.sesreqscs;
4998 }
4999
5000 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
5001 {
5002         gotgctl_data_t otgctl;
5003         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5004         otgctl.b.hnpreq = val;
5005         dwc_write_reg32(&core_if->core_global_regs->gotgctl, otgctl.d32);
5006 }
5007
5008 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
5009 {
5010         return core_if->snpsid;
5011 }
5012
5013 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
5014 {
5015         gotgctl_data_t otgctl;
5016         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5017         return otgctl.b.currmod;
5018 }
5019
5020 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
5021 {
5022         gusbcfg_data_t usbcfg;
5023         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5024         return usbcfg.b.hnpcap;
5025 }
5026
5027 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
5028 {
5029         gusbcfg_data_t usbcfg;
5030         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5031         usbcfg.b.hnpcap = val;
5032         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
5033 }
5034
5035 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
5036 {
5037         gusbcfg_data_t usbcfg;
5038         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5039         return usbcfg.b.srpcap;
5040 }
5041
5042 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
5043 {
5044         gusbcfg_data_t usbcfg;
5045         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5046         usbcfg.b.srpcap = val;
5047         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
5048 }
5049
5050 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
5051 {
5052         dcfg_data_t dcfg;
5053         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
5054         return dcfg.b.devspd;
5055 }
5056
5057 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
5058 {
5059         dcfg_data_t dcfg;
5060         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
5061         dcfg.b.devspd = val;
5062         dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
5063 }
5064
5065 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
5066 {
5067         hprt0_data_t hprt0;
5068         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5069         return hprt0.b.prtconnsts;
5070 }
5071
5072 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
5073 {
5074         dsts_data_t dsts;
5075         dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
5076         return dsts.b.enumspd;
5077 }
5078
5079 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
5080 {
5081         hprt0_data_t hprt0;
5082         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5083         return hprt0.b.prtpwr;
5084
5085 }
5086
5087 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
5088 {
5089         hprt0_data_t hprt0;
5090         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5091         hprt0.b.prtpwr = val;
5092         dwc_write_reg32(core_if->host_if->hprt0, val);
5093 }
5094
5095 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
5096 {
5097         hprt0_data_t hprt0;
5098         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5099         return hprt0.b.prtsusp;
5100
5101 }
5102
5103 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
5104 {
5105         hprt0_data_t hprt0;
5106         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5107         hprt0.b.prtsusp = val;
5108         dwc_write_reg32(core_if->host_if->hprt0, val);
5109 }
5110
5111 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
5112 {
5113         hprt0_data_t hprt0;
5114         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
5115         hprt0.b.prtres = val;
5116         dwc_write_reg32(core_if->host_if->hprt0, val);
5117 }
5118
5119 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
5120 {
5121         dctl_data_t dctl;
5122         dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
5123         return dctl.b.rmtwkupsig;
5124 }
5125
5126 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
5127 {
5128         glpmcfg_data_t lpmcfg;
5129         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5130
5131         DWC_ASSERT(!
5132                    ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
5133                    "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
5134                    core_if->lx_state, lpmcfg.b.prt_sleep_sts);
5135
5136         return lpmcfg.b.prt_sleep_sts;
5137 }
5138
5139 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
5140 {
5141         glpmcfg_data_t lpmcfg;
5142         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5143         return lpmcfg.b.rem_wkup_en;
5144 }
5145
5146 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
5147 {
5148         glpmcfg_data_t lpmcfg;
5149         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5150         return lpmcfg.b.appl_resp;
5151 }
5152
5153 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
5154 {
5155         glpmcfg_data_t lpmcfg;
5156         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5157         lpmcfg.b.appl_resp = val;
5158         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5159 }
5160
5161 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
5162 {
5163         glpmcfg_data_t lpmcfg;
5164         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5165         return lpmcfg.b.hsic_connect;
5166 }
5167
5168 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
5169 {
5170         glpmcfg_data_t lpmcfg;
5171         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5172         lpmcfg.b.hsic_connect = val;
5173         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5174 }
5175
5176 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
5177 {
5178         glpmcfg_data_t lpmcfg;
5179         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5180         return lpmcfg.b.inv_sel_hsic;
5181
5182 }
5183
5184 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
5185 {
5186         glpmcfg_data_t lpmcfg;
5187         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
5188         lpmcfg.b.inv_sel_hsic = val;
5189         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
5190 }
5191
5192 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
5193 {
5194         return dwc_read_reg32(&core_if->core_global_regs->gotgctl);
5195 }
5196
5197 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
5198 {
5199         dwc_write_reg32(&core_if->core_global_regs->gotgctl, val);
5200 }
5201
5202 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
5203 {
5204         return dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
5205 }
5206
5207 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
5208 {
5209         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, val);
5210 }
5211
5212 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
5213 {
5214         return dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
5215 }
5216
5217 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
5218 {
5219         dwc_write_reg32(&core_if->core_global_regs->grxfsiz, val);
5220 }
5221
5222 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
5223 {
5224         return dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz);
5225 }
5226
5227 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
5228 {
5229         dwc_write_reg32(&core_if->core_global_regs->gnptxfsiz, val);
5230 }
5231
5232 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
5233 {
5234         return dwc_read_reg32(&core_if->core_global_regs->gpvndctl);
5235 }
5236
5237 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
5238 {
5239         dwc_write_reg32(&core_if->core_global_regs->gpvndctl, val);
5240 }
5241
5242 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
5243 {
5244         return dwc_read_reg32(&core_if->core_global_regs->ggpio);
5245 }
5246
5247 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
5248 {
5249         dwc_write_reg32(&core_if->core_global_regs->ggpio, val);
5250 }
5251
5252 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
5253 {
5254         return dwc_read_reg32(core_if->host_if->hprt0);
5255
5256 }
5257
5258 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
5259 {
5260         dwc_write_reg32(core_if->host_if->hprt0, val);
5261 }
5262
5263 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
5264 {
5265         return dwc_read_reg32(&core_if->core_global_regs->guid);
5266 }
5267
5268 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
5269 {
5270         dwc_write_reg32(&core_if->core_global_regs->guid, val);
5271 }
5272
5273 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
5274 {
5275         return dwc_read_reg32(&core_if->core_global_regs->hptxfsiz);
5276 }