USB: support DWC_OTG Driver Version3.10 and used by default
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg_310 / dwc_otg_cil.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
3  * $Revision: #198 $
4  * $Date: 2012/12/21 $
5  * $Change: 2131568 $
6  *
7  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
8  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
9  * otherwise expressly agreed to in writing between Synopsys and you.
10  *
11  * The Software IS NOT an item of Licensed Software or Licensed Product under
12  * any End User Software License Agreement or Agreement for Licensed Product
13  * with Synopsys or any supplement thereto. You are permitted to use and
14  * redistribute this Software in source and binary forms, with or without
15  * modification, provided that redistributions of source code must retain this
16  * notice. You may not view, use, disclose, copy or distribute this file or
17  * any information contained herein except pursuant to this license grant from
18  * Synopsys. If you do not agree with this notice, including the disclaimer
19  * below, then you are not authorized to use the Software.
20  *
21  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
25  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31  * DAMAGE.
32  * ========================================================================== */
33
34 /** @file
35  *
36  * The Core Interface Layer provides basic services for accessing and
37  * managing the DWC_otg hardware. These services are used by both the
38  * Host Controller Driver and the Peripheral Controller Driver.
39  *
40  * The CIL manages the memory map for the core so that the HCD and PCD
41  * don't have to do this separately. It also handles basic tasks like
42  * reading/writing the registers and data FIFOs in the controller.
43  * Some of the data access functions provide encapsulation of several
44  * operations required to perform a task, such as writing multiple
45  * registers to start a transfer. Finally, the CIL performs basic
46  * services that are not specific to either the host or device modes
47  * of operation. These services include management of the OTG Host
48  * Negotiation Protocol (HNP) and Session Request Protocol (SRP). A
49  * Diagnostic API is also provided to allow testing of the controller
50  * hardware.
51  *
52  * The Core Interface Layer has the following requirements:
53  * - Provides basic controller operations.
54  * - Minimal use of OS services. 
55  * - The OS services used will be abstracted by using inline functions
56  *       or macros.
57  *
58  */
59
60 #include "common_port/dwc_os.h"
61 #include "dwc_otg_regs.h"
62 #include "dwc_otg_cil.h"
63 #include "dwc_otg_driver.h"
64 #include "usbdev_rk.h"
65 #include "dwc_otg_hcd.h"
66
67 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
68
69 /**
70  * This function is called to initialize the DWC_otg CSR data
71  * structures. The register addresses in the device and host
72  * structures are initialized from the base address supplied by the
73  * caller. The calling function must make the OS calls to get the
74  * base address of the DWC_otg controller registers. The core_params
75  * argument holds the parameters that specify how the core should be
76  * configured.
77  *
78  * @param reg_base_addr Base address of DWC_otg core registers
79  *
80  */
81 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
82 {
83         dwc_otg_core_if_t *core_if = 0;
84         dwc_otg_dev_if_t *dev_if = 0;
85         dwc_otg_host_if_t *host_if = 0;
86         uint8_t *reg_base = (uint8_t *) reg_base_addr;
87         int i = 0;
88
89         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
90
91         core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
92
93         if (core_if == NULL) {
94                 DWC_DEBUGPL(DBG_CIL,
95                             "Allocation of dwc_otg_core_if_t failed\n");
96                 return 0;
97         }
98         core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
99
100         /*
101          * Allocate the Device Mode structures.
102          */
103         dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
104
105         if (dev_if == NULL) {
106                 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
107                 DWC_FREE(core_if);
108                 return 0;
109         }
110
111         dev_if->dev_global_regs =
112             (dwc_otg_device_global_regs_t *) (reg_base +
113                                               DWC_DEV_GLOBAL_REG_OFFSET);
114
115         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
116                 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
117                     (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
118                      (i * DWC_EP_REG_OFFSET));
119
120                 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
121                     (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
122                      (i * DWC_EP_REG_OFFSET));
123                 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
124                             i, &dev_if->in_ep_regs[i]->diepctl);
125                 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
126                             i, &dev_if->out_ep_regs[i]->doepctl);
127         }
128
129         dev_if->speed = 0;      // unknown
130
131         core_if->dev_if = dev_if;
132
133         /*
134          * Allocate the Host Mode structures.
135          */
136         host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
137
138         if (host_if == NULL) {
139                 DWC_DEBUGPL(DBG_CIL,
140                             "Allocation of dwc_otg_host_if_t failed\n");
141                 DWC_FREE(dev_if);
142                 DWC_FREE(core_if);
143                 return 0;
144         }
145
146         host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
147             (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
148
149         host_if->hprt0 =
150             (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
151
152         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
153                 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
154                     (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
155                      (i * DWC_OTG_CHAN_REGS_OFFSET));
156                 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
157                             i, &host_if->hc_regs[i]->hcchar);
158         }
159
160         host_if->num_host_channels = MAX_EPS_CHANNELS;
161         core_if->host_if = host_if;
162
163         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
164                 core_if->data_fifo[i] =
165                     (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
166                                   (i * DWC_OTG_DATA_FIFO_SIZE));
167                 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n",
168                             i, (unsigned long)core_if->data_fifo[i]);
169         }
170
171         core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
172
173         /* Initiate lx_state to L3 disconnected state */
174         core_if->lx_state = DWC_OTG_L3;
175         /*
176          * Store the contents of the hardware configuration registers here for
177          * easy access later.
178          */
179         core_if->hwcfg1.d32 =
180             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
181         core_if->hwcfg2.d32 =
182             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
183         core_if->hwcfg3.d32 =
184             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
185         core_if->hwcfg4.d32 =
186             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
187
188         /* Force host mode to get HPTXFSIZ exact power on value */
189         {
190                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
191                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
192                 gusbcfg.b.force_host_mode = 1;
193                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
194                 dwc_mdelay(100);
195                 core_if->hptxfsiz.d32 =
196                     DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
197                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
198                 gusbcfg.b.force_host_mode = 0;
199                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
200                 dwc_mdelay(100);
201         }
202
203         DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
204         DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
205         DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
206         DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
207
208         core_if->hcfg.d32 =
209             DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
210         core_if->dcfg.d32 =
211             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
212
213         DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
214         DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
215
216         DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
217         DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
218         DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
219         DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
220                     core_if->hwcfg2.b.num_host_chan);
221         DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
222                     core_if->hwcfg2.b.nonperio_tx_q_depth);
223         DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
224                     core_if->hwcfg2.b.host_perio_tx_q_depth);
225         DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
226                     core_if->hwcfg2.b.dev_token_q_depth);
227
228         DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
229                     core_if->hwcfg3.b.dfifo_depth);
230         DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
231                     core_if->hwcfg3.b.xfer_size_cntr_width);
232
233         /*
234          * Set the SRP sucess bit for FS-I2c
235          */
236         core_if->srp_success = 0;
237         core_if->srp_timer_started = 0;
238
239         /*
240          * Create new workqueue and init works
241          */
242         core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
243         if (core_if->wq_otg == 0) {
244                 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
245                 DWC_FREE(host_if);
246                 DWC_FREE(dev_if);
247                 DWC_FREE(core_if);
248                 return 0;
249         }
250
251         core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
252         DWC_PRINTF("%p\n",&core_if->core_global_regs->gsnpsid);
253         DWC_PRINTF("Core Release: %x.%x%x%x\n",
254                    (core_if->snpsid >> 12 & 0xF),
255                    (core_if->snpsid >> 8 & 0xF),
256                    (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
257
258         core_if->wkp_tasklet = DWC_TASK_ALLOC("wkp_tasklet", w_wakeup_detected, core_if);
259
260         if (dwc_otg_setup_params(core_if)) {
261                 DWC_WARN("Error while setting core params\n");
262         }
263
264         core_if->hibernation_suspend = 0;
265         if (core_if->otg_ver)
266                 core_if->test_mode = 0;
267
268         /** ADP initialization */
269         dwc_otg_adp_init(core_if);
270         
271         return core_if;
272 }
273
274 /**
275  * This function frees the structures allocated by dwc_otg_cil_init().
276  *
277  * @param core_if The core interface pointer returned from
278  *                dwc_otg_cil_init().
279  *
280  */
281 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
282 {
283         dctl_data_t dctl = {.d32 = 0 };
284         /* Disable all interrupts */
285         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
286         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
287
288         dctl.b.sftdiscon = 1;
289         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
290                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0,
291                                  dctl.d32);
292         }
293
294         if (core_if->wq_otg) {
295                 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
296                 DWC_WORKQ_FREE(core_if->wq_otg);
297         }
298         if (core_if->dev_if) {
299                 DWC_FREE(core_if->dev_if);
300         }
301         if (core_if->host_if) {
302                 DWC_FREE(core_if->host_if);
303         }
304
305         /** Remove ADP Stuff  */
306         dwc_otg_adp_remove(core_if);
307         if (core_if->core_params) {
308                 DWC_FREE(core_if->core_params);
309         }
310         if (core_if->wkp_tasklet){
311                 DWC_TASK_FREE(core_if->wkp_tasklet);
312         }
313         if (core_if->srp_timer) {
314                 DWC_TIMER_FREE(core_if->srp_timer);
315         }
316         DWC_FREE(core_if);
317 }
318
319 /**
320  * This function enables the controller's Global Interrupt in the AHB Config
321  * register.
322  *
323  * @param core_if Programming view of DWC_otg controller.
324  */
325 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
326 {
327         gahbcfg_data_t ahbcfg = {.d32 = 0 };
328         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
329         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
330 }
331
332 /**
333  * This function disables the controller's Global Interrupt in the AHB Config
334  * register.
335  *
336  * @param core_if Programming view of DWC_otg controller.
337  */
338 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
339 {
340         gahbcfg_data_t ahbcfg = {.d32 = 0 };
341         ahbcfg.b.glblintrmsk = 1;       /* Disable interrupts */
342         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
343 }
344
345 /**
346  * This function initializes the commmon interrupts, used in both
347  * device and host modes.
348  *
349  * @param core_if Programming view of the DWC_otg controller
350  *
351  */
352 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
353 {
354         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
355         gintmsk_data_t intr_mask = {.d32 = 0 };
356
357         /* Clear any pending OTG Interrupts */
358         DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
359
360         /* Clear any pending interrupts */
361         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
362
363         /*
364          * Enable the interrupts in the GINTMSK.
365          */
366         intr_mask.b.modemismatch = 1;
367         intr_mask.b.otgintr = 1;
368
369         if (!core_if->dma_enable) {
370                 intr_mask.b.rxstsqlvl = 1;
371         }
372
373         intr_mask.b.conidstschng = 1;
374         intr_mask.b.wkupintr = 1;
375         intr_mask.b.disconnect = 0;
376         intr_mask.b.usbsuspend = 1;
377         //intr_mask.b.sessreqintr = 1;
378 #ifdef CONFIG_USB_DWC_OTG_LPM
379         if (core_if->core_params->lpm_enable) {
380                 intr_mask.b.lpmtranrcvd = 1;
381         }
382 #endif
383         DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
384 }
385
386 /*
387  * The restore operation is modified to support Synopsys Emulated Powerdown and
388  * Hibernation. This function is for exiting from Device mode hibernation by
389  * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
390  * @param core_if Programming view of DWC_otg controller.
391  * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
392  * @param reset - indicates whether resume is initiated by Reset.
393  */
394 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
395                                        int rem_wakeup, int reset)
396 {
397         gpwrdn_data_t gpwrdn = {.d32 = 0 };
398         pcgcctl_data_t pcgcctl = {.d32 = 0 };
399         dctl_data_t dctl = {.d32 = 0 };
400
401         int timeout = 2000;
402
403         if (!core_if->hibernation_suspend) {
404                 DWC_PRINTF("Already exited from Hibernation\n");
405                 return 1;
406         }
407
408         DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
409         /* Switch-on voltage to the core */
410         gpwrdn.b.pwrdnswtch = 1;
411         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
412         dwc_udelay(10);
413
414         /* Reset core */
415         gpwrdn.d32 = 0;
416         gpwrdn.b.pwrdnrstn = 1;
417         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
418         dwc_udelay(10);
419
420         /* Assert Restore signal */
421         gpwrdn.d32 = 0;
422         gpwrdn.b.restore = 1;
423         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
424         dwc_udelay(10);
425
426         /* Disable power clamps */
427         gpwrdn.d32 = 0;
428         gpwrdn.b.pwrdnclmp = 1;
429         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
430
431         if (rem_wakeup) {
432                 dwc_udelay(70);
433         }
434
435         /* Deassert Reset core */
436         gpwrdn.d32 = 0;
437         gpwrdn.b.pwrdnrstn = 1;
438         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
439         dwc_udelay(10);
440
441         /* Disable PMU interrupt */
442         gpwrdn.d32 = 0;
443         gpwrdn.b.pmuintsel = 1;
444         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
445
446         /* Mask interrupts from gpwrdn */
447         gpwrdn.d32 = 0;
448         gpwrdn.b.connect_det_msk = 1;
449         gpwrdn.b.srp_det_msk = 1;
450         gpwrdn.b.disconn_det_msk = 1;
451         gpwrdn.b.rst_det_msk = 1;
452         gpwrdn.b.lnstchng_msk = 1;
453         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
454
455         /* Indicates that we are going out from hibernation */
456         core_if->hibernation_suspend = 0;
457
458         /*
459          * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
460          * indicates restore from remote_wakeup
461          */
462         restore_essential_regs(core_if, rem_wakeup, 0);
463
464         /*
465          * Wait a little for seeing new value of variable hibernation_suspend if
466          * Restore done interrupt received before polling
467          */
468         dwc_udelay(10);
469
470         if (core_if->hibernation_suspend == 0) {
471                 /*
472                  * Wait For Restore_done Interrupt. This mechanism of polling the 
473                  * interrupt is introduced to avoid any possible race conditions
474                  */
475                 do {
476                         gintsts_data_t gintsts;
477                         gintsts.d32 =
478                             DWC_READ_REG32(&core_if->core_global_regs->gintsts);
479                         if (gintsts.b.restoredone) {
480                                 gintsts.d32 = 0;
481                                 gintsts.b.restoredone = 1;
482                                 DWC_WRITE_REG32(&core_if->core_global_regs->
483                                                 gintsts, gintsts.d32);
484                                 DWC_PRINTF("Restore Done Interrupt seen\n");
485                                 break;
486                         }
487                         dwc_udelay(10);
488                 } while (--timeout);
489                 if (!timeout) {
490                         DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
491                 }
492         }
493         /* Clear all pending interupts */
494         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
495
496         /* De-assert Restore */
497         gpwrdn.d32 = 0;
498         gpwrdn.b.restore = 1;
499         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
500         dwc_udelay(10);
501
502         if (!rem_wakeup) {
503                 pcgcctl.d32 = 0;
504                 pcgcctl.b.rstpdwnmodule = 1;
505                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
506         }
507
508         /* Restore GUSBCFG and DCFG */
509         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
510                         core_if->gr_backup->gusbcfg_local);
511         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
512                         core_if->dr_backup->dcfg);
513
514         /* De-assert Wakeup Logic */
515         gpwrdn.d32 = 0;
516         gpwrdn.b.pmuactv = 1;
517         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
518         dwc_udelay(10);
519
520         if (!rem_wakeup) {
521                 /* Set Device programming done bit */
522                 dctl.b.pwronprgdone = 1;
523                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
524         } else {
525                 /* Start Remote Wakeup Signaling */
526                 dctl.d32 = core_if->dr_backup->dctl;
527                 dctl.b.rmtwkupsig = 1;
528                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
529         }
530
531         dwc_mdelay(2);
532         /* Clear all pending interupts */
533         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
534
535         /* Restore global registers */
536         dwc_otg_restore_global_regs(core_if);
537         /* Restore device global registers */
538         dwc_otg_restore_dev_regs(core_if, rem_wakeup);
539
540         if (rem_wakeup) {
541                 dwc_mdelay(7);
542                 dctl.d32 = 0;
543                 dctl.b.rmtwkupsig = 1;
544                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
545         }
546
547         core_if->hibernation_suspend = 0;
548         /* The core will be in ON STATE */
549         core_if->lx_state = DWC_OTG_L0;
550         DWC_PRINTF("Hibernation recovery completes here\n");
551
552         return 1;
553 }
554
555 /*
556  * The restore operation is modified to support Synopsys Emulated Powerdown and
557  * Hibernation. This function is for exiting from Host mode hibernation by
558  * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
559  * @param core_if Programming view of DWC_otg controller.
560  * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
561  * @param reset - indicates whether resume is initiated by Reset.
562  */
563 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
564                                      int rem_wakeup, int reset)
565 {
566         gpwrdn_data_t gpwrdn = {.d32 = 0 };
567         hprt0_data_t hprt0 = {.d32 = 0 };
568
569         int timeout = 2000;
570
571         DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
572         /* Switch-on voltage to the core */
573         gpwrdn.b.pwrdnswtch = 1;
574         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
575         dwc_udelay(10);
576
577         /* Reset core */
578         gpwrdn.d32 = 0;
579         gpwrdn.b.pwrdnrstn = 1;
580         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
581         dwc_udelay(10);
582
583         /* Assert Restore signal */
584         gpwrdn.d32 = 0;
585         gpwrdn.b.restore = 1;
586         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
587         dwc_udelay(10);
588
589         /* Disable power clamps */
590         gpwrdn.d32 = 0;
591         gpwrdn.b.pwrdnclmp = 1;
592         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
593
594         if (!rem_wakeup) {
595                 dwc_udelay(50);
596         }
597
598         /* Deassert Reset core */
599         gpwrdn.d32 = 0;
600         gpwrdn.b.pwrdnrstn = 1;
601         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
602         dwc_udelay(10);
603
604         /* Disable PMU interrupt */
605         gpwrdn.d32 = 0;
606         gpwrdn.b.pmuintsel = 1;
607         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
608
609         gpwrdn.d32 = 0;
610         gpwrdn.b.connect_det_msk = 1;
611         gpwrdn.b.srp_det_msk = 1;
612         gpwrdn.b.disconn_det_msk = 1;
613         gpwrdn.b.rst_det_msk = 1;
614         gpwrdn.b.lnstchng_msk = 1;
615         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
616
617         /* Indicates that we are going out from hibernation */
618         core_if->hibernation_suspend = 0;
619
620         /* Set Restore Essential Regs bit in PCGCCTL register */
621         restore_essential_regs(core_if, rem_wakeup, 1);
622
623         /* Wait a little for seeing new value of variable hibernation_suspend if
624          * Restore done interrupt received before polling */
625         dwc_udelay(10);
626
627         if (core_if->hibernation_suspend == 0) {
628                 /* Wait For Restore_done Interrupt. This mechanism of polling the
629                  * interrupt is introduced to avoid any possible race conditions
630                  */
631                 do {
632                         gintsts_data_t gintsts;
633                         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
634                         if (gintsts.b.restoredone) {
635                                 gintsts.d32 = 0;
636                                 gintsts.b.restoredone = 1;
637                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
638                                 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");   
639                                 break;
640                         }
641                         dwc_udelay(10);
642                 } while (--timeout);
643                 if (!timeout) {
644                         DWC_WARN("Restore Done interrupt wasn't generated\n");
645                 }
646         }
647
648         /* Set the flag's value to 0 again after receiving restore done interrupt */
649         core_if->hibernation_suspend = 0;
650
651         /* This step is not described in functional spec but if not wait for this
652          * delay, mismatch interrupts occurred because just after restore core is
653          * in Device mode(gintsts.curmode == 0) */
654         dwc_mdelay(100);
655
656         /* Clear all pending interrupts */
657         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
658
659         /* De-assert Restore */
660         gpwrdn.d32 = 0;
661         gpwrdn.b.restore = 1;
662         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
663         dwc_udelay(10);
664
665         /* Restore GUSBCFG and HCFG */
666         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
667                         core_if->gr_backup->gusbcfg_local);
668         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
669                         core_if->hr_backup->hcfg_local);
670
671         /* De-assert Wakeup Logic */
672         gpwrdn.d32 = 0;
673         gpwrdn.b.pmuactv = 1;
674         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
675         dwc_udelay(10);
676
677         /* Start the Resume operation by programming HPRT0 */
678         hprt0.d32 = core_if->hr_backup->hprt0_local;
679         hprt0.b.prtpwr = 1;
680         hprt0.b.prtena = 0;
681         hprt0.b.prtsusp = 0;
682         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
683
684         DWC_PRINTF("Resume Starts Now\n");
685         if (!reset) {           // Indicates it is Resume Operation
686                 hprt0.d32 = core_if->hr_backup->hprt0_local;
687                 hprt0.b.prtres = 1;
688                 hprt0.b.prtpwr = 1;
689                 hprt0.b.prtena = 0;
690                 hprt0.b.prtsusp = 0;
691                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
692
693                 if (!rem_wakeup)
694                         hprt0.b.prtres = 0;
695                 /* Wait for Resume time and then program HPRT again */
696                 dwc_mdelay(100);
697                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
698
699         } else {                // Indicates it is Reset Operation
700                 hprt0.d32 = core_if->hr_backup->hprt0_local;
701                 hprt0.b.prtrst = 1;
702                 hprt0.b.prtpwr = 1;
703                 hprt0.b.prtena = 0;
704                 hprt0.b.prtsusp = 0;
705                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
706                 /* Wait for Reset time and then program HPRT again */
707                 dwc_mdelay(60);
708                 hprt0.b.prtrst = 0;
709                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
710         }
711         /* Clear all interrupt status */
712         hprt0.d32 = dwc_otg_read_hprt0(core_if);
713         hprt0.b.prtconndet = 1;
714         hprt0.b.prtenchng = 1;
715         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
716
717         /* Clear all pending interupts */
718         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
719
720         /* Restore global registers */
721         dwc_otg_restore_global_regs(core_if);
722         /* Restore host global registers */
723         dwc_otg_restore_host_regs(core_if, reset);
724
725         /* The core will be in ON STATE */
726         core_if->lx_state = DWC_OTG_L0;
727         DWC_PRINTF("Hibernation recovery is complete here\n");
728         return 0;
729 }
730
731 /** Saves some register values into system memory. */
732 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
733 {
734         struct dwc_otg_global_regs_backup *gr;
735         int i;
736
737         gr = core_if->gr_backup;
738         if (!gr) {
739                 gr = DWC_ALLOC(sizeof(*gr));
740                 if (!gr) {
741                         return -DWC_E_NO_MEMORY;
742                 }
743                 core_if->gr_backup = gr;
744         }
745
746         gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
747         gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
748         gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
749         gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
750         gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
751         gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
752         gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
753 #ifdef CONFIG_USB_DWC_OTG_LPM
754         gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
755 #endif
756         gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
757         gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
758         gr->gdfifocfg_local =
759             DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
760         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
761                 gr->dtxfsiz_local[i] =
762                     DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
763         }
764
765         DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
766         DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl   = %08x\n", gr->gotgctl_local);
767         DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk   = %08x\n", gr->gintmsk_local);
768         DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg   = %08x\n", gr->gahbcfg_local);
769         DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg   = %08x\n", gr->gusbcfg_local);
770         DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz   = %08x\n", gr->grxfsiz_local);
771         DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
772                     gr->gnptxfsiz_local);
773         DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz  = %08x\n",
774                     gr->hptxfsiz_local);
775 #ifdef CONFIG_USB_DWC_OTG_LPM
776         DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg   = %08x\n", gr->glpmcfg_local);
777 #endif
778         DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl   = %08x\n", gr->gi2cctl_local);
779         DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl   = %08x\n", gr->pcgcctl_local);
780         DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg   = %08x\n",gr->gdfifocfg_local);
781
782         return 0;
783 }
784
785 /** Saves GINTMSK register before setting the msk bits. */
786 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
787 {
788         struct dwc_otg_global_regs_backup *gr;
789
790         gr = core_if->gr_backup;
791         if (!gr) {
792                 gr = DWC_ALLOC(sizeof(*gr));
793                 if (!gr) {
794                         return -DWC_E_NO_MEMORY;
795                 }
796                 core_if->gr_backup = gr;
797         }
798
799         gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
800
801         DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
802         DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk   = %08x\n", gr->gintmsk_local);
803
804         return 0;
805 }
806
807 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
808 {
809         struct dwc_otg_dev_regs_backup *dr;
810         int i;
811
812         dr = core_if->dr_backup;
813         if (!dr) {
814                 dr = DWC_ALLOC(sizeof(*dr));
815                 if (!dr) {
816                         return -DWC_E_NO_MEMORY;
817                 }
818                 core_if->dr_backup = dr;
819         }
820
821         dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
822         dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
823         dr->daintmsk =
824             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
825         dr->diepmsk =
826             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
827         dr->doepmsk =
828             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
829
830         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
831                 dr->diepctl[i] =
832                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
833                 dr->dieptsiz[i] =
834                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
835                 dr->diepdma[i] =
836                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
837         }
838
839         DWC_DEBUGPL(DBG_ANY,
840                     "=============Backing Host registers==============\n");
841         DWC_DEBUGPL(DBG_ANY, "Backed up dcfg            = %08x\n", dr->dcfg);
842         DWC_DEBUGPL(DBG_ANY, "Backed up dctl        = %08x\n", dr->dctl);
843         DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk            = %08x\n",
844                     dr->daintmsk);
845         DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk        = %08x\n", dr->diepmsk);
846         DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk        = %08x\n", dr->doepmsk);
847         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
848                 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d]        = %08x\n", i,
849                             dr->diepctl[i]);
850                 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d]        = %08x\n",
851                             i, dr->dieptsiz[i]);
852                 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d]        = %08x\n", i,
853                             dr->diepdma[i]);
854         }
855
856         return 0;
857 }
858
859 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
860 {
861         struct dwc_otg_host_regs_backup *hr;
862         int i;
863
864         hr = core_if->hr_backup;
865         if (!hr) {
866                 hr = DWC_ALLOC(sizeof(*hr));
867                 if (!hr) {
868                         return -DWC_E_NO_MEMORY;
869                 }
870                 core_if->hr_backup = hr;
871         }
872
873         hr->hcfg_local =
874             DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
875         hr->haintmsk_local =
876             DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
877         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
878                 hr->hcintmsk_local[i] =
879                     DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
880         }
881         hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
882         hr->hfir_local =
883             DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
884
885         DWC_DEBUGPL(DBG_ANY,
886                     "=============Backing Host registers===============\n");
887         DWC_DEBUGPL(DBG_ANY, "Backed up hcfg            = %08x\n",
888                     hr->hcfg_local);
889         DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
890         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
891                 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
892                             hr->hcintmsk_local[i]);
893         }
894         DWC_DEBUGPL(DBG_ANY, "Backed up hprt0           = %08x\n",
895                     hr->hprt0_local);
896         DWC_DEBUGPL(DBG_ANY, "Backed up hfir           = %08x\n",
897                     hr->hfir_local);
898
899         return 0;
900 }
901
902 int dwc_otg_restore_global_regs(dwc_otg_core_if_t * core_if)
903 {
904         struct dwc_otg_global_regs_backup *gr;
905         int i;
906
907         gr = core_if->gr_backup;
908         if (!gr) {
909                 return -DWC_E_INVALID;
910         }
911
912         DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
913         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
914         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
915         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
916         DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
917         DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
918                         gr->gnptxfsiz_local);
919         DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
920                         gr->hptxfsiz_local);
921         DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
922                         gr->gdfifocfg_local);
923         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
924                 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
925                                 gr->dtxfsiz_local[i]);
926         }
927
928         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
929         DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
930         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
931                         (gr->gahbcfg_local));
932         return 0;
933 }
934
935 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
936 {
937         struct dwc_otg_dev_regs_backup *dr;
938         int i;
939
940         dr = core_if->dr_backup;
941
942         if (!dr) {
943                 return -DWC_E_INVALID;
944         }
945
946         if (!rem_wakeup) {
947                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl,
948                                 dr->dctl);
949         }
950         
951         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
952         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
953         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
954
955         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
956                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
957                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
958                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
959         }
960
961         return 0;
962 }
963
964 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
965 {
966         struct dwc_otg_host_regs_backup *hr;
967         int i;
968         hr = core_if->hr_backup;
969
970         if (!hr) {
971                 return -DWC_E_INVALID;
972         }
973
974         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
975         //if (!reset)
976         //{
977         //      DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
978         //}
979
980         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
981                         hr->haintmsk_local);
982         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
983                 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
984                                 hr->hcintmsk_local[i]);
985         }
986
987         return 0;
988 }
989
990 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
991 {
992         struct dwc_otg_global_regs_backup *gr;
993
994         gr = core_if->gr_backup;
995
996         /* Restore values for LPM and I2C */
997 #ifdef CONFIG_USB_DWC_OTG_LPM
998         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
999 #endif
1000         DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
1001
1002         return 0;
1003 }
1004
1005 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
1006 {
1007         struct dwc_otg_global_regs_backup *gr;
1008         pcgcctl_data_t pcgcctl = {.d32 = 0 };
1009         gahbcfg_data_t gahbcfg = {.d32 = 0 };
1010         gusbcfg_data_t gusbcfg = {.d32 = 0 };
1011         gintmsk_data_t gintmsk = {.d32 = 0 };
1012
1013         /* Restore LPM and I2C registers */
1014         restore_lpm_i2c_regs(core_if);
1015
1016         /* Set PCGCCTL to 0 */
1017         DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
1018
1019         gr = core_if->gr_backup;
1020         /* Load restore values for [31:14] bits */
1021         DWC_WRITE_REG32(core_if->pcgcctl,
1022                         ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
1023
1024         /* Umnask global Interrupt in GAHBCFG and restore it */
1025         gahbcfg.d32 = gr->gahbcfg_local;
1026         gahbcfg.b.glblintrmsk = 1;
1027         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
1028
1029         /* Clear all pending interupts */
1030         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
1031
1032         /* Unmask restore done interrupt */
1033         gintmsk.b.restoredone = 1;
1034         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1035
1036         /* Restore GUSBCFG and HCFG/DCFG */
1037         gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
1038         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
1039
1040         if (is_host) {
1041                 hcfg_data_t hcfg = {.d32 = 0 };
1042                 hcfg.d32 = core_if->hr_backup->hcfg_local;
1043                 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
1044                                 hcfg.d32);
1045
1046                 /* Load restore values for [31:14] bits */
1047                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1048                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1049
1050                 if (rmode)
1051                         pcgcctl.b.restoremode = 1;
1052                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1053                 dwc_udelay(10);
1054
1055                 /* Load restore values for [31:14] bits and set EssRegRestored bit */
1056                 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
1057                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1058                 pcgcctl.b.ess_reg_restored = 1;
1059                 if (rmode)
1060                         pcgcctl.b.restoremode = 1;
1061                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1062         } else {
1063                 dcfg_data_t dcfg = {.d32 = 0 };
1064                 dcfg.d32 = core_if->dr_backup->dcfg;
1065                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1066
1067                 /* Load restore values for [31:14] bits */
1068                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1069                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1070                 if (!rmode) {
1071                         pcgcctl.d32 |= 0x208;
1072                 }
1073                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1074                 dwc_udelay(10);
1075
1076                 /* Load restore values for [31:14] bits */
1077                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
1078                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
1079                 pcgcctl.b.ess_reg_restored = 1;
1080                 if (!rmode)
1081                         pcgcctl.d32 |= 0x208;
1082                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
1083         }
1084
1085         return 0;
1086 }
1087
1088 /**
1089  * Initializes the FSLSPClkSel field of the HCFG register depending on the PHY
1090  * type.
1091  */
1092 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
1093 {
1094         uint32_t val;
1095         hcfg_data_t hcfg;
1096
1097         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1098              (core_if->hwcfg2.b.fs_phy_type == 1) &&
1099              (core_if->core_params->ulpi_fs_ls)) ||
1100             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1101                 /* Full speed PHY */
1102                 val = DWC_HCFG_48_MHZ;
1103         } else {
1104                 /* High speed PHY running at full speed or high speed */
1105                 val = DWC_HCFG_30_60_MHZ;
1106         }
1107
1108         DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
1109         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
1110         hcfg.b.fslspclksel = val;
1111         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
1112 }
1113
1114 /**
1115  * Initializes the DevSpd field of the DCFG register depending on the PHY type
1116  * and the enumeration speed of the device.
1117  */
1118 static void init_devspd(dwc_otg_core_if_t * core_if)
1119 {
1120         uint32_t val;
1121         dcfg_data_t dcfg;
1122
1123         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
1124              (core_if->hwcfg2.b.fs_phy_type == 1) &&
1125              (core_if->core_params->ulpi_fs_ls)) ||
1126             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1127                 /* Full speed PHY */
1128                 val = 0x3;
1129         } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
1130                 /* High speed PHY running at full speed */
1131                 val = 0x1;
1132         } else {
1133                 /* High speed PHY running at high speed */
1134                 val = 0x0;
1135         }
1136
1137         DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
1138
1139         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
1140         dcfg.b.devspd = val;
1141         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
1142 }
1143
1144 /**
1145  * This function calculates the number of IN EPS
1146  * using GHWCFG1 and GHWCFG2 registers values
1147  *
1148  * @param core_if Programming view of the DWC_otg controller
1149  */
1150 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
1151 {
1152         uint32_t num_in_eps = 0;
1153         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1154         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
1155         uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
1156         int i;
1157
1158         for (i = 0; i < num_eps; ++i) {
1159                 if (!(hwcfg1 & 0x1))
1160                         num_in_eps++;
1161
1162                 hwcfg1 >>= 2;
1163         }
1164
1165         if (core_if->hwcfg4.b.ded_fifo_en) {
1166                 num_in_eps =
1167                     (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
1168         }
1169
1170         return num_in_eps;
1171 }
1172
1173 /**
1174  * This function calculates the number of OUT EPS
1175  * using GHWCFG1 and GHWCFG2 registers values
1176  *
1177  * @param core_if Programming view of the DWC_otg controller
1178  */
1179 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
1180 {
1181         uint32_t num_out_eps = 0;
1182         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
1183         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
1184         int i;
1185
1186         for (i = 0; i < num_eps; ++i) {
1187                 if (!(hwcfg1 & 0x1))
1188                         num_out_eps++;
1189
1190                 hwcfg1 >>= 2;
1191         }
1192         return num_out_eps;
1193 }
1194
1195 /**
1196  * This function initializes the DWC_otg controller registers and
1197  * prepares the core for device mode or host mode operation.
1198  *
1199  * @param core_if Programming view of the DWC_otg controller
1200  *
1201  */
1202 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
1203 {
1204         int i = 0;
1205         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1206         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1207         gahbcfg_data_t ahbcfg = {.d32 = 0 };
1208         gusbcfg_data_t usbcfg = {.d32 = 0 };
1209         gi2cctl_data_t i2cctl = {.d32 = 0 };
1210
1211         DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
1212
1213         /* Common Initialization */
1214         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1215
1216         /* Program the ULPI External VBUS bit if needed */
1217         usbcfg.b.ulpi_ext_vbus_drv =
1218             (core_if->core_params->phy_ulpi_ext_vbus ==
1219              DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
1220
1221         /* Set external TS Dline pulsing */
1222         usbcfg.b.term_sel_dl_pulse =
1223             (core_if->core_params->ts_dline == 1) ? 1 : 0;
1224         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1225
1226         /* Reset the Controller */
1227         dwc_otg_core_reset(core_if);
1228
1229         core_if->adp_enable = core_if->core_params->adp_supp_enable;
1230         core_if->power_down = core_if->core_params->power_down;
1231
1232         /* Initialize parameters from Hardware configuration registers. */
1233         dev_if->num_in_eps = calc_num_in_eps(core_if);
1234         dev_if->num_out_eps = calc_num_out_eps(core_if);
1235
1236         DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
1237                     core_if->hwcfg4.b.num_dev_perio_in_ep);
1238
1239         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1240                 dev_if->perio_tx_fifo_size[i] =
1241                     DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1242                 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
1243                             i, dev_if->perio_tx_fifo_size[i]);
1244         }
1245
1246         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1247                 dev_if->tx_fifo_size[i] =
1248                     DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
1249                 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
1250                             i, dev_if->tx_fifo_size[i]);
1251         }
1252
1253         core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
1254         core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
1255         core_if->nperio_tx_fifo_size =
1256             DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
1257
1258         DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
1259         DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
1260         DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
1261                     core_if->nperio_tx_fifo_size);
1262
1263         /* This programming sequence needs to happen in FS mode before any other
1264          * programming occurs */
1265         if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
1266             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
1267                 /* If FS mode with FS PHY */
1268
1269                 /* core_init() is now called on every switch so only call the
1270                  * following for the first time through. */
1271                 if (!core_if->phy_init_done) {
1272                         core_if->phy_init_done = 1;
1273                         DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
1274                         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1275                         usbcfg.b.physel = 1;
1276                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1277
1278                         /* Reset after a PHY select */
1279                         dwc_otg_core_reset(core_if);
1280                 }
1281
1282                 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
1283                  * do this on HNP Dev/Host mode switches (done in dev_init and
1284                  * host_init). */
1285                 if (dwc_otg_is_host_mode(core_if)) {
1286                         init_fslspclksel(core_if);
1287                 } else {
1288                         init_devspd(core_if);
1289                 }
1290
1291                 if (core_if->core_params->i2c_enable) {
1292                         DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
1293                         /* Program GUSBCFG.OtgUtmifsSel to I2C */
1294                         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1295                         usbcfg.b.otgutmifssel = 1;
1296                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1297
1298                         /* Program GI2CCTL.I2CEn */
1299                         i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
1300                         i2cctl.b.i2cdevaddr = 1;
1301                         i2cctl.b.i2cen = 0;
1302                         DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1303                         i2cctl.b.i2cen = 1;
1304                         DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
1305                 }
1306
1307         } /* endif speed == DWC_SPEED_PARAM_FULL */
1308         else {
1309                 /* High speed PHY. */
1310                 if (!core_if->phy_init_done) {
1311                         core_if->phy_init_done = 1;
1312                         /* HS PHY parameters.  These parameters are preserved
1313                          * during soft reset so only program the first time.  Do
1314                          * a soft reset immediately after setting phyif.  */
1315
1316                         if (core_if->core_params->phy_type == 2) {
1317                                 /* ULPI interface */
1318                                 usbcfg.b.ulpi_utmi_sel = 1;
1319                                 usbcfg.b.phyif = 0;
1320                                 usbcfg.b.ddrsel =
1321                                     core_if->core_params->phy_ulpi_ddr;
1322                         } else if (core_if->core_params->phy_type == 1) {
1323                                 /* UTMI+ interface */
1324                                 usbcfg.b.ulpi_utmi_sel = 0;
1325                                 if (core_if->core_params->phy_utmi_width == 16) {
1326                                         usbcfg.b.phyif = 1;
1327
1328                                 } else {
1329                                         usbcfg.b.phyif = 0;
1330                                 }
1331                         } else {
1332                                 DWC_ERROR("FS PHY TYPE\n");
1333                         }
1334                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1335                         /* Reset after setting the PHY parameters */
1336                         dwc_otg_core_reset(core_if);
1337                 }
1338         }
1339
1340         if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
1341             (core_if->hwcfg2.b.fs_phy_type == 1) &&
1342             (core_if->core_params->ulpi_fs_ls)) {
1343                 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
1344                 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1345                 usbcfg.b.ulpi_fsls = 1;
1346                 usbcfg.b.ulpi_clk_sus_m = 1;
1347                 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1348         } else {
1349                 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1350                 usbcfg.b.ulpi_fsls = 0;
1351                 usbcfg.b.ulpi_clk_sus_m = 0;
1352                 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1353         }
1354
1355         /* Program the GAHBCFG Register. */
1356         switch (core_if->hwcfg2.b.architecture) {
1357
1358         case DWC_SLAVE_ONLY_ARCH:
1359                 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
1360                 ahbcfg.b.nptxfemplvl_txfemplvl =
1361                     DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1362                 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
1363                 core_if->dma_enable = 0;
1364                 core_if->dma_desc_enable = 0;
1365                 break;
1366
1367         case DWC_EXT_DMA_ARCH:
1368                 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
1369                 {
1370                         uint8_t brst_sz = core_if->core_params->dma_burst_size;
1371                         ahbcfg.b.hburstlen = 0;
1372                         while (brst_sz > 1) {
1373                                 ahbcfg.b.hburstlen++;
1374                                 brst_sz >>= 1;
1375                         }
1376                 }
1377                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1378                 core_if->dma_desc_enable =
1379                     (core_if->core_params->dma_desc_enable != 0);
1380                 break;
1381
1382         case DWC_INT_DMA_ARCH:
1383                 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
1384                 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for 
1385                    Host mode ISOC in issue fix - vahrama */
1386                 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1387                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
1388                 core_if->dma_desc_enable =
1389                     (core_if->core_params->dma_desc_enable != 0);
1390                 break;
1391
1392         }
1393         if (core_if->dma_enable) {
1394                 if (core_if->dma_desc_enable) {
1395                         DWC_PRINTF("Using Descriptor DMA mode\n");
1396                 } else {
1397                         DWC_PRINTF("Using Buffer DMA mode\n");
1398                 }
1399         } else {
1400                 DWC_PRINTF("Using Slave mode\n");
1401                 core_if->dma_desc_enable = 0;
1402         }
1403
1404         if (core_if->core_params->ahb_single) {
1405                 ahbcfg.b.ahbsingle = 1;
1406         }
1407
1408         ahbcfg.b.dmaenable = core_if->dma_enable;
1409         DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
1410
1411         core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
1412
1413         core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
1414         core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
1415         DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
1416                    ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
1417         DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
1418                    ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
1419
1420         /*
1421          * Program the GUSBCFG register.
1422          */
1423         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
1424
1425         switch (core_if->hwcfg2.b.op_mode) {
1426         case DWC_MODE_HNP_SRP_CAPABLE:
1427                 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
1428                                    DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
1429                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1430                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1431                 break;
1432
1433         case DWC_MODE_SRP_ONLY_CAPABLE:
1434                 usbcfg.b.hnpcap = 0;
1435                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1436                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1437                 break;
1438
1439         case DWC_MODE_NO_HNP_SRP_CAPABLE:
1440                 usbcfg.b.hnpcap = 0;
1441                 usbcfg.b.srpcap = 0;
1442                 break;
1443
1444         case DWC_MODE_SRP_CAPABLE_DEVICE:
1445                 usbcfg.b.hnpcap = 0;
1446                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1447                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1448                 break;
1449
1450         case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
1451                 usbcfg.b.hnpcap = 0;
1452                 usbcfg.b.srpcap = 0;
1453                 break;
1454
1455         case DWC_MODE_SRP_CAPABLE_HOST:
1456                 usbcfg.b.hnpcap = 0;
1457                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
1458                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
1459                 break;
1460
1461         case DWC_MODE_NO_SRP_CAPABLE_HOST:
1462                 usbcfg.b.hnpcap = 0;
1463                 usbcfg.b.srpcap = 0;
1464                 break;
1465         }
1466
1467         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
1468
1469 #ifdef CONFIG_USB_DWC_OTG_LPM
1470         if (core_if->core_params->lpm_enable) {
1471                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
1472
1473                 /* To enable LPM support set lpm_cap_en bit */
1474                 lpmcfg.b.lpm_cap_en = 1;
1475
1476                 /* Make AppL1Res ACK */
1477                 lpmcfg.b.appl_resp = 1;
1478
1479                 /* Retry 3 times */
1480                 lpmcfg.b.retry_count = 3;
1481
1482                 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
1483                                  0, lpmcfg.d32);
1484
1485         }
1486 #endif
1487         if (core_if->core_params->ic_usb_cap) {
1488                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
1489                 gusbcfg.b.ic_usb_cap = 1;
1490                 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
1491                                  0, gusbcfg.d32);
1492         }
1493         {
1494                 gotgctl_data_t gotgctl = {.d32 = 0 };
1495                 gotgctl.b.otgver = core_if->core_params->otg_ver;
1496                 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
1497                                  gotgctl.d32);
1498                 /* Set OTG version supported */
1499                 core_if->otg_ver = core_if->core_params->otg_ver;
1500                 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
1501                            core_if->core_params->otg_ver, core_if->otg_ver);
1502         }
1503
1504         /* Enable common interrupts */
1505         dwc_otg_enable_common_interrupts(core_if);
1506
1507         /* Do device or host intialization based on mode during PCD
1508          * and HCD initialization  */
1509         if (dwc_otg_is_host_mode(core_if)) {
1510                 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
1511                 core_if->op_state = A_HOST;
1512         } else {
1513                 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
1514                 core_if->op_state = B_PERIPHERAL;
1515 #ifdef DWC_DEVICE_ONLY
1516                 dwc_otg_core_dev_init(core_if);
1517 #endif
1518         }
1519 }
1520
1521 /**
1522  * This function enables the Device mode interrupts.
1523  *
1524  * @param core_if Programming view of DWC_otg controller
1525  */
1526 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
1527 {
1528         gintmsk_data_t intr_mask = {.d32 = 0 };
1529         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1530
1531         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
1532
1533         /* Disable all interrupts. */
1534         DWC_WRITE_REG32(&global_regs->gintmsk, 0);
1535
1536         /* Clear any pending interrupts */
1537         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
1538
1539         /* Enable the common interrupts */
1540         dwc_otg_enable_common_interrupts(core_if);
1541
1542         /* Enable interrupts */
1543         intr_mask.b.usbreset = 1;
1544         intr_mask.b.enumdone = 1;
1545         /* Disable Disconnect interrupt in Device mode */
1546         intr_mask.b.disconnect = 0;
1547
1548         if (!core_if->multiproc_int_enable) {
1549                 intr_mask.b.inepintr = 1;
1550                 intr_mask.b.outepintr = 1;
1551         }
1552
1553         intr_mask.b.erlysuspend = 1;
1554
1555         if (core_if->en_multiple_tx_fifo == 0) {
1556                 intr_mask.b.epmismatch = 1;
1557         }
1558
1559         //intr_mask.b.incomplisoout = 1;
1560         intr_mask.b.incomplisoin = 1;
1561
1562 /* Enable the ignore frame number for ISOC xfers - MAS */
1563 /* Disable to support high bandwith ISOC transfers - manukz */
1564 #if 0
1565 #ifdef DWC_UTE_PER_IO
1566         if (core_if->dma_enable) {
1567                 if (core_if->dma_desc_enable) {
1568                         dctl_data_t dctl1 = {.d32 = 0 };
1569                         dctl1.b.ifrmnum = 1;
1570                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
1571                                          dctl, 0, dctl1.d32);
1572                         DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
1573                                   DWC_READ_REG32(&core_if->dev_if->
1574                                                  dev_global_regs->dctl));
1575                 }
1576         }
1577 #endif
1578 #endif
1579 #ifdef DWC_EN_ISOC
1580         if (core_if->dma_enable) {
1581                 if (core_if->dma_desc_enable == 0) {
1582                         if (core_if->pti_enh_enable) {
1583                                 dctl_data_t dctl = {.d32 = 0 };
1584                                 dctl.b.ifrmnum = 1;
1585                                 DWC_MODIFY_REG32(&core_if->
1586                                                  dev_if->dev_global_regs->dctl,
1587                                                  0, dctl.d32);
1588                         } else {
1589                                 intr_mask.b.incomplisoin = 1;
1590                                 intr_mask.b.incomplisoout = 1;
1591                         }
1592                 }
1593         } else {
1594                 intr_mask.b.incomplisoin = 1;
1595                 intr_mask.b.incomplisoout = 1;
1596         }
1597 #endif /* DWC_EN_ISOC */
1598
1599         /** @todo NGS: Should this be a module parameter? */
1600 #ifdef USE_PERIODIC_EP
1601         intr_mask.b.isooutdrop = 1;
1602         intr_mask.b.eopframe = 1;
1603         intr_mask.b.incomplisoin = 1;
1604         intr_mask.b.incomplisoout = 1;
1605 #endif
1606
1607         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
1608
1609         DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
1610                     DWC_READ_REG32(&global_regs->gintmsk));
1611 }
1612
1613 /**
1614  * This function initializes the DWC_otg controller registers for
1615  * device mode.
1616  *
1617  * @param core_if Programming view of DWC_otg controller
1618  *
1619  */
1620 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
1621 {
1622         int i;
1623         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
1624         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
1625         dwc_otg_core_params_t *params = core_if->core_params;
1626         dcfg_data_t dcfg = {.d32 = 0 };
1627         depctl_data_t diepctl = {.d32 = 0 };
1628         grstctl_t resetctl = {.d32 = 0 };
1629         uint32_t rx_fifo_size;
1630         fifosize_data_t nptxfifosize;
1631         fifosize_data_t txfifosize;
1632         dthrctl_data_t dthrctl;
1633         fifosize_data_t ptxfifosize;
1634 //      uint16_t rxfsiz, nptxfsiz;
1635 //      gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
1636 //      hwcfg3_data_t hwcfg3 = {.d32 = 0 };
1637         gotgctl_data_t gotgctl = {.d32 = 0 };
1638         gahbcfg_data_t gahbcfg = {.d32 = 0};
1639         
1640         /* Restart the Phy Clock */
1641         pcgcctl_data_t pcgcctl = {.d32 = 0 };
1642         /* Restart the Phy Clock */
1643         pcgcctl.b.stoppclk = 1;
1644         DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
1645         dwc_udelay(10);
1646
1647         gahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
1648         DWC_MODIFY_REG32(&global_regs->gahbcfg, 0 , gahbcfg.b.hburstlen);
1649
1650         /* Device configuration register */
1651         init_devspd(core_if);
1652         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1653         dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
1654         dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
1655         /* Enable Device OUT NAK in case of DDMA mode */
1656         if (core_if->core_params->dev_out_nak) {
1657                 dcfg.b.endevoutnak = 1;
1658         }
1659
1660         if (core_if->core_params->cont_on_bna) {
1661                 dctl_data_t dctl = {.d32 = 0 };
1662                 dctl.b.encontonbna = 1;
1663                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1664         }
1665         /** should be done before every reset */
1666         if (core_if->otg_ver) {
1667                 core_if->otg_sts = 0;
1668                 gotgctl.b.devhnpen = 1;
1669                 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, gotgctl.d32, 0);
1670         }
1671         
1672         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1673
1674         /* Configure data FIFO sizes */
1675         
1676         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
1677 #ifdef DWC_UTE_CFI
1678                 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
1679                 core_if->init_rxfsiz = params->dev_rx_fifo_size;
1680 #endif
1681                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
1682                             DWC_READ_REG32(&global_regs->grxfsiz));
1683
1684                 /** Set Periodic Tx FIFO Mask all bits 0 */
1685                 core_if->p_tx_msk = 0;
1686
1687                 /** Set Tx FIFO Mask all bits 0 */
1688                 core_if->tx_msk = 0;
1689                 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
1690                  * and ded_fifo_en is 1 in default*/
1691                 if (core_if->en_multiple_tx_fifo == 0) {
1692                         /* Non-periodic Tx FIFO */
1693                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1694                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
1695
1696                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1697                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1698
1699                         DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1700                                         nptxfifosize.d32);
1701
1702                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1703                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
1704
1705                         /**@todo NGS: Fix Periodic FIFO Sizing! */
1706                         /*
1707                          * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
1708                          * Indexes of the FIFO size module parameters in the
1709                          * dev_perio_tx_fifo_size array and the FIFO size registers in
1710                          * the dptxfsiz array run from 0 to 14.
1711                          */
1712                         /** @todo Finish debug of this */
1713                         ptxfifosize.b.startaddr =
1714                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1715                         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
1716                                 ptxfifosize.b.depth =
1717                                     params->dev_perio_tx_fifo_size[i];
1718                                 DWC_DEBUGPL(DBG_CIL,
1719                                             "initial dtxfsiz[%d]=%08x\n", i,
1720                                             DWC_READ_REG32(&global_regs->dtxfsiz
1721                                                            [i]));
1722                                 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1723                                                 ptxfifosize.d32);
1724                                 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
1725                                             i,
1726                                             DWC_READ_REG32(&global_regs->dtxfsiz
1727                                                            [i]));
1728                                 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
1729                         }
1730                 } else {
1731                         /*
1732                          * Tx FIFOs These FIFOs are numbered from 1 to 15.
1733                          * Indexes of the FIFO size module parameters in the
1734                          * dev_tx_fifo_size array and the FIFO size registers in
1735                          * the dtxfsiz array run from 0 to 14.
1736                          */
1737
1738                         /* Non-periodic Tx FIFO */
1739                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
1740                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
1741
1742 #ifdef DWC_UTE_CFI
1743                         core_if->pwron_gnptxfsiz =
1744                             (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1745                         core_if->init_gnptxfsiz =
1746                             params->dev_nperio_tx_fifo_size;
1747 #endif
1748                         rx_fifo_size = params->dev_rx_fifo_size;
1749                         DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
1750                         DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
1751                                     DWC_READ_REG32(&global_regs->grxfsiz));
1752
1753                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
1754                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
1755                         DWC_WRITE_REG32(&global_regs->gnptxfsiz,
1756                                         nptxfifosize.d32);
1757
1758                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
1759                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
1760
1761                         txfifosize.b.startaddr =
1762                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
1763
1764                         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
1765
1766                                 txfifosize.b.depth =
1767                                     params->dev_tx_fifo_size[i];
1768
1769                                 DWC_DEBUGPL(DBG_CIL,
1770                                             "initial dtxfsiz[%d]=%08x\n",
1771                                             i,
1772                                             DWC_READ_REG32(&global_regs->dtxfsiz
1773                                                            [i]));
1774
1775 #ifdef DWC_UTE_CFI
1776                                 core_if->pwron_txfsiz[i] =
1777                                     (DWC_READ_REG32
1778                                      (&global_regs->dtxfsiz[i]) >> 16);
1779                                 core_if->init_txfsiz[i] =
1780                                     params->dev_tx_fifo_size[i];
1781 #endif
1782                                 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
1783                                                 txfifosize.d32);
1784
1785                                 DWC_DEBUGPL(DBG_CIL,
1786                                             "new dtxfsiz[%d]=%08x\n",
1787                                             i,
1788                                             DWC_READ_REG32(&global_regs->dtxfsiz
1789                                                            [i]));
1790
1791                                 txfifosize.b.startaddr += txfifosize.b.depth;
1792                         }
1793                         #if 0
1794                         /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO 
1795                          * Before 3.00a EpInfoBase was being configured in ep enable/disable 
1796                          * routine as well. Starting from 3.00a it will be set to the end of
1797                          * allocated FIFO space here due to ep 0 OUT always keeping enabled
1798                          */
1799                         gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
1800                         hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
1801                         gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
1802                         DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1803                         if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
1804                                 rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
1805                                 nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
1806                                 gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
1807                         } else {
1808                                 gdfifocfg.b.epinfobase = txfifosize.b.startaddr;
1809                         }
1810                         //DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
1811                         #endif
1812                 }
1813         }
1814
1815         /* Flush the FIFOs */
1816         dwc_otg_flush_tx_fifo(core_if, 0x10);   /* all Tx FIFOs */
1817         dwc_otg_flush_rx_fifo(core_if);
1818
1819         /* Flush the Learning Queue. */
1820         resetctl.b.intknqflsh = 1;
1821         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
1822
1823         if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
1824                 core_if->start_predict = 0;
1825                 for (i = 0; i <= core_if->dev_if->num_in_eps; ++i) {
1826                         core_if->nextep_seq[i] = 0xff;  // 0xff - EP not active
1827                 }
1828                 core_if->nextep_seq[0] = 0;
1829                 core_if->first_in_nextep_seq = 0;
1830                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
1831                 diepctl.b.nextep = 0;
1832                 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
1833
1834                 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
1835                 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
1836                 dcfg.b.epmscnt = 2;
1837                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
1838
1839                 DWC_DEBUGPL(DBG_CILV,
1840                             "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
1841                             __func__, core_if->first_in_nextep_seq);
1842                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
1843                         DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]);
1844                 }
1845                 DWC_DEBUGPL(DBG_CILV, "\n");
1846         }
1847
1848         /* Clear all pending Device Interrupts */
1849         /** @todo - if the condition needed to be checked
1850          *  or in any case all pending interrutps should be cleared?
1851      */
1852         if (core_if->multiproc_int_enable) {
1853                 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
1854                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
1855                                         diepeachintmsk[i], 0);
1856                 }
1857
1858                 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
1859                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
1860                                         doepeachintmsk[i], 0);
1861                 }
1862
1863                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
1864                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
1865         } else {
1866                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
1867                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
1868                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
1869                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
1870         }
1871
1872         for (i = 0; i <= dev_if->num_in_eps; i++) {
1873                 depctl_data_t depctl;
1874                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
1875                 if (depctl.b.epena) {
1876                         depctl.d32 = 0;
1877                         depctl.b.epdis = 1;
1878                         depctl.b.snak = 1;
1879                 } else {
1880                         depctl.d32 = 0;
1881                 }
1882
1883                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
1884
1885                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
1886                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
1887                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
1888         }
1889
1890         for (i = 1; i <= dev_if->num_out_eps; i++) {
1891                 depctl_data_t depctl;
1892                 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
1893                 if (depctl.b.epena) {
1894                         int j = 0;
1895                         dctl_data_t dctl = {.d32 = 0 };
1896                         gintmsk_data_t gintsts = {.d32 = 0 };
1897                         doepint_data_t doepint = {.d32 = 0 };
1898                         dctl.b.sgoutnak = 1;
1899                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1900                         do {
1901                                 j++;
1902                                 dwc_udelay(10);
1903                                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
1904                                 if (j == 100000) {
1905                                         DWC_ERROR("SNAK as not set during 10s\n");
1906                                         break;
1907                                 }
1908                         } while (!gintsts.b.goutnakeff);
1909                         gintsts.d32 = 0;
1910                         gintsts.b.goutnakeff = 1;
1911                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
1912
1913                         depctl.d32 = 0;
1914                         depctl.b.epdis = 1;
1915                         depctl.b.snak = 1;
1916                         j = 0;
1917                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1918                         do {
1919                                 dwc_udelay(10);
1920                                 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
1921                                         out_ep_regs[i]->doepint);
1922                                 if (j == 100000) {
1923                                         DWC_ERROR("EPDIS was not set during 10s\n");
1924                                         break;
1925                                 }
1926                         } while (!doepint.b.epdisabled);
1927
1928                         doepint.b.epdisabled = 1;
1929                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[i]->doepint, doepint.d32);
1930
1931                         dctl.d32 = 0;
1932                         dctl.b.cgoutnak = 1;
1933                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
1934                 } else {
1935                         depctl.d32 = 0;
1936                 }
1937
1938                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
1939                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
1940                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
1941                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
1942         }
1943
1944         if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
1945                 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
1946                 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
1947                 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
1948
1949                 dev_if->rx_thr_length = params->rx_thr_length;
1950                 dev_if->tx_thr_length = params->tx_thr_length;
1951
1952                 dev_if->setup_desc_index = 0;
1953
1954                 dthrctl.d32 = 0;
1955                 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
1956                 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
1957                 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
1958                 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
1959                 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
1960                 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
1961
1962                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
1963                                 dthrctl.d32);
1964
1965                 DWC_DEBUGPL(DBG_CIL,
1966                             "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
1967                             dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
1968                             dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
1969                             dthrctl.b.rx_thr_len);
1970
1971         }
1972
1973         dwc_otg_enable_device_interrupts(core_if);
1974
1975         {
1976                 diepmsk_data_t msk = {.d32 = 0 };
1977                 msk.b.txfifoundrn = 1;
1978                 if (core_if->multiproc_int_enable) {
1979                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->
1980                                          diepeachintmsk[0], msk.d32, msk.d32);
1981                 } else {
1982                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
1983                                          msk.d32, msk.d32);
1984                 }
1985         }
1986
1987         if (core_if->multiproc_int_enable) {
1988                 /* Set NAK on Babble */
1989                 dctl_data_t dctl = {.d32 = 0 };
1990                 dctl.b.nakonbble = 1;
1991                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
1992         }
1993 }
1994
1995 /**
1996  * This function enables the Host mode interrupts.
1997  *
1998  * @param core_if Programming view of DWC_otg controller
1999  */
2000 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
2001 {
2002         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2003         gintmsk_data_t intr_mask = {.d32 = 0 };
2004
2005         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
2006
2007         /* Disable all interrupts. */
2008         DWC_WRITE_REG32(&global_regs->gintmsk, 0);
2009
2010         /* Clear any pending interrupts. */
2011         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
2012
2013         /* Enable the common interrupts */
2014         dwc_otg_enable_common_interrupts(core_if);
2015
2016         /*
2017          * Enable host mode interrupts without disturbing common
2018          * interrupts.
2019          */
2020
2021         intr_mask.b.disconnect = 1;
2022         intr_mask.b.portintr = 1;
2023         intr_mask.b.hcintr = 1;
2024
2025         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
2026 }
2027
2028 /**
2029  * This function disables the Host Mode interrupts.
2030  *
2031  * @param core_if Programming view of DWC_otg controller
2032  */
2033 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
2034 {
2035         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2036         gintmsk_data_t intr_mask = {.d32 = 0 };
2037
2038         DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
2039
2040         /*
2041          * Disable host mode interrupts without disturbing common
2042          * interrupts.
2043          */
2044         intr_mask.b.sofintr = 1;
2045         intr_mask.b.portintr = 1;
2046         intr_mask.b.hcintr = 1;
2047         intr_mask.b.ptxfempty = 1;
2048         intr_mask.b.nptxfempty = 1;
2049
2050         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
2051 }
2052
2053 /**
2054  * This function initializes the DWC_otg controller registers for
2055  * host mode.
2056  *
2057  * This function flushes the Tx and Rx FIFOs and it flushes any entries in the
2058  * request queues. Host channels are reset to ensure that they are ready for
2059  * performing transfers.
2060  *
2061  * @param core_if Programming view of DWC_otg controller
2062  *
2063  */
2064 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
2065 {
2066         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
2067         dwc_otg_host_if_t *host_if = core_if->host_if;
2068         dwc_otg_core_params_t *params = core_if->core_params;
2069         hprt0_data_t hprt0 = {.d32 = 0 };
2070         fifosize_data_t nptxfifosize;
2071         fifosize_data_t ptxfifosize;
2072 //      uint16_t rxfsiz, nptxfsiz, hptxfsiz;
2073 //      gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
2074         int i;
2075         hcchar_data_t hcchar;
2076         hcfg_data_t hcfg;
2077         hfir_data_t hfir;
2078         dwc_otg_hc_regs_t *hc_regs;
2079         int num_channels;
2080         gotgctl_data_t gotgctl = {.d32 = 0 };
2081         pcgcctl_data_t pcgcctl = {.d32 = 0 };
2082         struct dwc_otg_platform_data *pldata;
2083         pldata = core_if->otg_dev->pldata;
2084
2085
2086
2087         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
2088
2089         /* Restart the Phy Clock */
2090         pcgcctl.b.stoppclk = 1;
2091         DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
2092         dwc_udelay(10);
2093         
2094         if ((core_if->otg_ver == 1) && (core_if->op_state == A_HOST)) { 
2095                 DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
2096                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2097                 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2098                 if (hprt0.b.prtpwr == 0) {
2099                         hprt0.b.prtpwr = 1;
2100                         DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2101                 }
2102         }
2103
2104         /* Initialize Host Configuration Register */
2105         init_fslspclksel(core_if);
2106         if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
2107                 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2108                 hcfg.b.fslssupp = 1;
2109                 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2110
2111         }
2112
2113         /* This bit allows dynamic reloading of the HFIR register
2114          * during runtime. This bit needs to be programmed during 
2115          * initial configuration and its value must not be changed
2116          * during runtime.*/
2117         if (core_if->core_params->reload_ctl == 1) {
2118                 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
2119                 hfir.b.hfirrldctrl = 1;
2120                 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
2121         }
2122
2123         if (core_if->core_params->dma_desc_enable) {
2124                 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
2125                 if (!
2126                     (core_if->hwcfg4.b.desc_dma
2127                      && (core_if->snpsid >= OTG_CORE_REV_2_90a)
2128                      && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
2129                          || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
2130                          || (op_mode ==
2131                              DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
2132                          || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
2133                          || (op_mode ==
2134                              DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
2135
2136                         DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
2137                                   "Either core version is below 2.90a or "
2138                                   "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
2139                                   "To run the driver in Buffer DMA host mode set dma_desc_enable "
2140                                   "module parameter to 0.\n");
2141                         return;
2142                 }
2143                 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
2144                 hcfg.b.descdma = 1;
2145                 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
2146         }
2147
2148         /* Configure data FIFO sizes */
2149         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
2150                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
2151                             core_if->total_fifo_size);
2152                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
2153                             params->host_rx_fifo_size);
2154                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
2155                             params->host_nperio_tx_fifo_size);
2156                 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
2157                             params->host_perio_tx_fifo_size);
2158
2159                 /* Rx FIFO */
2160                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
2161                             DWC_READ_REG32(&global_regs->grxfsiz));
2162                 DWC_WRITE_REG32(&global_regs->grxfsiz, 0x0200);//params->host_rx_fifo_size);
2163                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
2164                             DWC_READ_REG32(&global_regs->grxfsiz));
2165
2166                 /* Non-periodic Tx FIFO */
2167                 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
2168                             DWC_READ_REG32(&global_regs->gnptxfsiz));
2169                 nptxfifosize.b.depth = 0x0080;//params->host_nperio_tx_fifo_size;
2170                 nptxfifosize.b.startaddr = 0x0200;//params->host_rx_fifo_size;
2171                 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
2172                 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
2173                             DWC_READ_REG32(&global_regs->gnptxfsiz));
2174
2175                 /* Periodic Tx FIFO */
2176                 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
2177                             DWC_READ_REG32(&global_regs->hptxfsiz));
2178                 ptxfifosize.b.depth = 0x0100;//params->host_perio_tx_fifo_size;
2179                 ptxfifosize.b.startaddr = 0x0280;//nptxfifosize.b.startaddr + nptxfifosize.b.depth;
2180                 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
2181                 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
2182                             DWC_READ_REG32(&global_regs->hptxfsiz));
2183         #if 0
2184                 /* core_if->en_multiple_tx_fifo equals core_if->hwcfg4.b.ded_fifo_en,
2185                  * and ded_fifo_en is 1 in default
2186                  */
2187                 if (core_if->en_multiple_tx_fifo) {
2188                         /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
2189                         gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
2190                         rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
2191                         nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
2192                         hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
2193                         gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
2194                         DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
2195                 }
2196                 #endif
2197         }
2198
2199         /* TODO - check this */
2200         /* Clear Host Set HNP Enable in the OTG Control Register */
2201         gotgctl.b.hstsethnpen = 1;
2202         DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2203         /* Make sure the FIFOs are flushed. */
2204         dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ );
2205         dwc_otg_flush_rx_fifo(core_if);
2206
2207         /* Clear Host Set HNP Enable in the OTG Control Register */
2208         gotgctl.b.hstsethnpen = 1;
2209         DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
2210
2211         if (!core_if->core_params->dma_desc_enable) {
2212                 /* Flush out any leftover queued requests. */
2213                 num_channels = core_if->core_params->host_channels;
2214
2215                 for (i = 0; i < num_channels; i++) {
2216                         hc_regs = core_if->host_if->hc_regs[i];
2217                         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2218                         hcchar.b.chen = 0;
2219                         hcchar.b.chdis = 1;
2220                         hcchar.b.epdir = 0;
2221                         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2222                 }
2223
2224                 /* Halt all channels to put them into a known state. */
2225                 for (i = 0; i < num_channels; i++) {
2226                         int count = 0;
2227                         hc_regs = core_if->host_if->hc_regs[i];
2228                         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2229                         hcchar.b.chen = 1;
2230                         hcchar.b.chdis = 1;
2231                         hcchar.b.epdir = 0;
2232                         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2233                         DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
2234                         do {
2235                                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2236                                 if (++count > 1000) {
2237                                         DWC_ERROR
2238                                             ("%s: Unable to clear halt on channel %d\n",
2239                                              __func__, i);
2240                                         break;
2241                                 }
2242                                 dwc_udelay(1);
2243                         } while (hcchar.b.chen);
2244                 }
2245         }
2246
2247         /* Turn on the vbus power. */
2248         if ((core_if->otg_ver == 0) && (core_if->op_state == A_HOST)) {
2249                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
2250                 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
2251                 if (hprt0.b.prtpwr == 0) {
2252                         hprt0.b.prtpwr = 1;
2253                         DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
2254                 }
2255                 if(pldata->power_enable)
2256                     pldata->power_enable(1);
2257         }
2258
2259         dwc_otg_enable_host_interrupts(core_if);
2260 }
2261
2262 /**
2263  * Prepares a host channel for transferring packets to/from a specific
2264  * endpoint. The HCCHARn register is set up with the characteristics specified
2265  * in _hc. Host channel interrupts that may need to be serviced while this
2266  * transfer is in progress are enabled.
2267  *
2268  * @param core_if Programming view of DWC_otg controller
2269  * @param hc Information needed to initialize the host channel
2270  */
2271 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2272 {
2273         uint32_t intr_enable;
2274         hcintmsk_data_t hc_intr_mask;
2275         gintmsk_data_t gintmsk = {.d32 = 0 };
2276         hcchar_data_t hcchar;
2277         hcsplt_data_t hcsplt;
2278
2279         uint8_t hc_num = hc->hc_num;
2280         dwc_otg_host_if_t *host_if = core_if->host_if;
2281         dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
2282
2283         /* Clear old interrupt conditions for this host channel. */
2284         hc_intr_mask.d32 = 0xFFFFFFFF;
2285         hc_intr_mask.b.reserved14_31 = 0;
2286         DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
2287
2288         /* Enable channel interrupts required for this transfer. */
2289         hc_intr_mask.d32 = 0;
2290         hc_intr_mask.b.chhltd = 1;
2291         if (core_if->dma_enable) {
2292                 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
2293                 if (!core_if->dma_desc_enable)
2294                         hc_intr_mask.b.ahberr = 1;
2295                 else {
2296                         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2297                                 hc_intr_mask.b.xfercompl = 1;
2298                 }
2299
2300                 if (hc->error_state && !hc->do_split &&
2301                     hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
2302                         hc_intr_mask.b.ack = 1;
2303                         if (hc->ep_is_in) {
2304                                 hc_intr_mask.b.datatglerr = 1;
2305                                 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2306                                         hc_intr_mask.b.nak = 1;
2307                                 }
2308                         }
2309                 }
2310         } else {
2311                 switch (hc->ep_type) {
2312                 case DWC_OTG_EP_TYPE_CONTROL:
2313                 case DWC_OTG_EP_TYPE_BULK:
2314                         hc_intr_mask.b.xfercompl = 1;
2315                         hc_intr_mask.b.stall = 1;
2316                         hc_intr_mask.b.xacterr = 1;
2317                         hc_intr_mask.b.datatglerr = 1;
2318                         if (hc->ep_is_in) {
2319                                 hc_intr_mask.b.bblerr = 1;
2320                         } else {
2321                                 hc_intr_mask.b.nak = 1;
2322                                 hc_intr_mask.b.nyet = 1;
2323                                 if (hc->do_ping) {
2324                                         hc_intr_mask.b.ack = 1;
2325                                 }
2326                         }
2327
2328                         if (hc->do_split) {
2329                                 hc_intr_mask.b.nak = 1;
2330                                 if (hc->complete_split) {
2331                                         hc_intr_mask.b.nyet = 1;
2332                                 } else {
2333                                         hc_intr_mask.b.ack = 1;
2334                                 }
2335                         }
2336
2337                         if (hc->error_state) {
2338                                 hc_intr_mask.b.ack = 1;
2339                         }
2340                         break;
2341                 case DWC_OTG_EP_TYPE_INTR:
2342                         hc_intr_mask.b.xfercompl = 1;
2343                         hc_intr_mask.b.nak = 1;
2344                         hc_intr_mask.b.stall = 1;
2345                         hc_intr_mask.b.xacterr = 1;
2346                         hc_intr_mask.b.datatglerr = 1;
2347                         hc_intr_mask.b.frmovrun = 1;
2348
2349                         if (hc->ep_is_in) {
2350                                 hc_intr_mask.b.bblerr = 1;
2351                         }
2352                         if (hc->error_state) {
2353                                 hc_intr_mask.b.ack = 1;
2354                         }
2355                         if (hc->do_split) {
2356                                 if (hc->complete_split) {
2357                                         hc_intr_mask.b.nyet = 1;
2358                                 } else {
2359                                         hc_intr_mask.b.ack = 1;
2360                                 }
2361                         }
2362                         break;
2363                 case DWC_OTG_EP_TYPE_ISOC:
2364                         hc_intr_mask.b.xfercompl = 1;
2365                         hc_intr_mask.b.frmovrun = 1;
2366                         hc_intr_mask.b.ack = 1;
2367
2368                         if (hc->ep_is_in) {
2369                                 hc_intr_mask.b.xacterr = 1;
2370                                 hc_intr_mask.b.bblerr = 1;
2371                         }
2372                         break;
2373                 }
2374         }
2375         DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
2376
2377         /* Enable the top level host channel interrupt. */
2378         intr_enable = (1 << hc_num);
2379         DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
2380
2381         /* Make sure host channel interrupts are enabled. */
2382         gintmsk.b.hcintr = 1;
2383         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
2384
2385         /*
2386          * Program the HCCHARn register with the endpoint characteristics for
2387          * the current transfer.
2388          */
2389         hcchar.d32 = 0;
2390         hcchar.b.devaddr = hc->dev_addr;
2391         hcchar.b.epnum = hc->ep_num;
2392         hcchar.b.epdir = hc->ep_is_in;
2393         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
2394         hcchar.b.eptype = hc->ep_type;
2395         hcchar.b.mps = hc->max_packet;
2396
2397         DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
2398
2399         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2400         DWC_DEBUGPL(DBG_HCDV, "  Dev Addr: %d\n", hcchar.b.devaddr);
2401         DWC_DEBUGPL(DBG_HCDV, "  Ep Num: %d\n", hcchar.b.epnum);
2402         DWC_DEBUGPL(DBG_HCDV, "  Is In: %d\n", hcchar.b.epdir);
2403         DWC_DEBUGPL(DBG_HCDV, "  Is Low Speed: %d\n", hcchar.b.lspddev);
2404         DWC_DEBUGPL(DBG_HCDV, "  Ep Type: %d\n", hcchar.b.eptype);
2405         DWC_DEBUGPL(DBG_HCDV, "  Max Pkt: %d\n", hcchar.b.mps);
2406         DWC_DEBUGPL(DBG_HCDV, "  Multi Cnt: %d\n", hcchar.b.multicnt);
2407
2408         /*
2409          * Program the HCSPLIT register for SPLITs
2410          */
2411         hcsplt.d32 = 0;
2412         if (hc->do_split) {
2413                 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
2414                             hc->hc_num,
2415                             hc->complete_split ? "CSPLIT" : "SSPLIT");
2416                 hcsplt.b.compsplt = hc->complete_split;
2417                 hcsplt.b.xactpos = hc->xact_pos;
2418                 hcsplt.b.hubaddr = hc->hub_addr;
2419                 hcsplt.b.prtaddr = hc->port_addr;
2420                 DWC_DEBUGPL(DBG_HCDV, "   comp split %d\n", hc->complete_split);
2421                 DWC_DEBUGPL(DBG_HCDV, "   xact pos %d\n", hc->xact_pos);
2422                 DWC_DEBUGPL(DBG_HCDV, "   hub addr %d\n", hc->hub_addr);
2423                 DWC_DEBUGPL(DBG_HCDV, "   port addr %d\n", hc->port_addr);
2424                 DWC_DEBUGPL(DBG_HCDV, "   is_in %d\n", hc->ep_is_in);
2425                 DWC_DEBUGPL(DBG_HCDV, "   Max Pkt: %d\n", hcchar.b.mps);
2426                 DWC_DEBUGPL(DBG_HCDV, "   xferlen: %d\n", hc->xfer_len);
2427         }
2428         DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
2429
2430 }
2431
2432 /**
2433  * Attempts to halt a host channel. This function should only be called in
2434  * Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
2435  * normal circumstances in DMA mode, the controller halts the channel when the
2436  * transfer is complete or a condition occurs that requires application
2437  * intervention.
2438  *
2439  * In slave mode, checks for a free request queue entry, then sets the Channel
2440  * Enable and Channel Disable bits of the Host Channel Characteristics
2441  * register of the specified channel to intiate the halt. If there is no free
2442  * request queue entry, sets only the Channel Disable bit of the HCCHARn
2443  * register to flush requests for this channel. In the latter case, sets a
2444  * flag to indicate that the host channel needs to be halted when a request
2445  * queue slot is open.
2446  *
2447  * In DMA mode, always sets the Channel Enable and Channel Disable bits of the
2448  * HCCHARn register. The controller ensures there is space in the request
2449  * queue before submitting the halt request.
2450  *
2451  * Some time may elapse before the core flushes any posted requests for this
2452  * host channel and halts. The Channel Halted interrupt handler completes the
2453  * deactivation of the host channel.
2454  *
2455  * @param core_if Controller register interface.
2456  * @param hc Host channel to halt.
2457  * @param halt_status Reason for halting the channel.
2458  */
2459 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
2460                      dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
2461 {
2462         gnptxsts_data_t nptxsts;
2463         hptxsts_data_t hptxsts;
2464         hcchar_data_t hcchar;
2465         dwc_otg_hc_regs_t *hc_regs;
2466         dwc_otg_core_global_regs_t *global_regs;
2467         dwc_otg_host_global_regs_t *host_global_regs;
2468
2469         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2470         global_regs = core_if->core_global_regs;
2471         host_global_regs = core_if->host_if->host_global_regs;
2472
2473         DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
2474                    "halt_status = %d\n", halt_status);
2475
2476         if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
2477             halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
2478                 /*
2479                  * Disable all channel interrupts except Ch Halted. The QTD
2480                  * and QH state associated with this transfer has been cleared
2481                  * (in the case of URB_DEQUEUE), so the channel needs to be
2482                  * shut down carefully to prevent crashes.
2483                  */
2484                 hcintmsk_data_t hcintmsk;
2485                 hcintmsk.d32 = 0;
2486                 hcintmsk.b.chhltd = 1;
2487                 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
2488
2489                 /*
2490                  * Make sure no other interrupts besides halt are currently
2491                  * pending. Handling another interrupt could cause a crash due
2492                  * to the QTD and QH state.
2493                  */
2494                 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
2495
2496                 /*
2497                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
2498                  * even if the channel was already halted for some other
2499                  * reason.
2500                  */
2501                 hc->halt_status = halt_status;
2502
2503                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2504                 if (hcchar.b.chen == 0) {
2505                         /*
2506                          * The channel is either already halted or it hasn't
2507                          * started yet. In DMA mode, the transfer may halt if
2508                          * it finishes normally or a condition occurs that
2509                          * requires driver intervention. Don't want to halt
2510                          * the channel again. In either Slave or DMA mode,
2511                          * it's possible that the transfer has been assigned
2512                          * to a channel, but not started yet when an URB is
2513                          * dequeued. Don't want to halt a channel that hasn't
2514                          * started yet.
2515                          */
2516                         return;
2517                 }
2518         }
2519         if (hc->halt_pending) {
2520                 /*
2521                  * A halt has already been issued for this channel. This might
2522                  * happen when a transfer is aborted by a higher level in
2523                  * the stack.
2524                  */
2525 #ifdef DEBUG
2526                 DWC_PRINTF
2527                     ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
2528                      __func__, hc->hc_num);
2529
2530 #endif
2531                 return;
2532         }
2533
2534         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2535
2536         /* No need to set the bit in DDMA for disabling the channel */
2537         //TODO check it everywhere channel is disabled          
2538         if (!core_if->core_params->dma_desc_enable)
2539                 hcchar.b.chen = 1;
2540         hcchar.b.chdis = 1;
2541
2542         if (!core_if->dma_enable) {
2543                 /* Check for space in the request queue to issue the halt. */
2544                 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
2545                     hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
2546                         nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
2547                         if (nptxsts.b.nptxqspcavail == 0) {
2548                                 hcchar.b.chen = 0;
2549                         }
2550                 } else {
2551                         hptxsts.d32 =
2552                             DWC_READ_REG32(&host_global_regs->hptxsts);
2553                         if ((hptxsts.b.ptxqspcavail == 0)
2554                             || (core_if->queuing_high_bandwidth)) {
2555                                 hcchar.b.chen = 0;
2556                         }
2557                 }
2558         }
2559         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2560
2561         hc->halt_status = halt_status;
2562
2563         if (hcchar.b.chen) {
2564                 hc->halt_pending = 1;
2565                 hc->halt_on_queue = 0;
2566         } else {
2567                 hc->halt_on_queue = 1;
2568         }
2569
2570         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2571         DWC_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n", hcchar.d32);
2572         DWC_DEBUGPL(DBG_HCDV, "  halt_pending: %d\n", hc->halt_pending);
2573         DWC_DEBUGPL(DBG_HCDV, "  halt_on_queue: %d\n", hc->halt_on_queue);
2574         DWC_DEBUGPL(DBG_HCDV, "  halt_status: %d\n", hc->halt_status);
2575
2576         return;
2577 }
2578
2579 /**
2580  * Clears the transfer state for a host channel. This function is normally
2581  * called after a transfer is done and the host channel is being released.
2582  *
2583  * @param core_if Programming view of DWC_otg controller.
2584  * @param hc Identifies the host channel to clean up.
2585  */
2586 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2587 {
2588         dwc_otg_hc_regs_t *hc_regs;
2589
2590         hc->xfer_started = 0;
2591
2592         /*
2593          * Clear channel interrupt enables and any unhandled channel interrupt
2594          * conditions.
2595          */
2596         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2597         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
2598         DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
2599 #ifdef DEBUG
2600         DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
2601 #endif
2602 }
2603
2604 /**
2605  * Sets the channel property that indicates in which frame a periodic transfer
2606  * should occur. This is always set to the _next_ frame. This function has no
2607  * effect on non-periodic transfers.
2608  *
2609  * @param core_if Programming view of DWC_otg controller.
2610  * @param hc Identifies the host channel to set up and its properties.
2611  * @param hcchar Current value of the HCCHAR register for the specified host
2612  * channel.
2613  */
2614 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
2615                                          dwc_hc_t * hc, hcchar_data_t * hcchar)
2616 {
2617         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2618             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2619                 hfnum_data_t hfnum;
2620                 hfnum.d32 =
2621                     DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
2622
2623                 /* 1 if _next_ frame is odd, 0 if it's even */
2624                 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
2625 #ifdef DEBUG
2626                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
2627                     && !hc->complete_split) {
2628                         switch (hfnum.b.frnum & 0x7) {
2629                         case 7:
2630                                 core_if->hfnum_7_samples++;
2631                                 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
2632                                 break;
2633                         case 0:
2634                                 core_if->hfnum_0_samples++;
2635                                 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
2636                                 break;
2637                         default:
2638                                 core_if->hfnum_other_samples++;
2639                                 core_if->hfnum_other_frrem_accum +=
2640                                     hfnum.b.frrem;
2641                                 break;
2642                         }
2643                 }
2644 #endif
2645         }
2646 }
2647
2648 #ifdef DEBUG
2649 void hc_xfer_timeout(void *ptr)
2650 {
2651         hc_xfer_info_t *xfer_info = NULL;
2652         int hc_num = 0;
2653
2654         if (ptr)
2655                 xfer_info = (hc_xfer_info_t *) ptr;
2656
2657         if (!xfer_info->hc) {
2658                 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
2659                 return;
2660         }
2661
2662         hc_num = xfer_info->hc->hc_num;
2663         DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
2664         DWC_WARN("      start_hcchar_val 0x%08x\n",
2665                  xfer_info->core_if->start_hcchar_val[hc_num]);
2666 }
2667 #endif
2668
2669 void ep_xfer_timeout(void *ptr)
2670 {
2671         ep_xfer_info_t *xfer_info = NULL;
2672         int ep_num = 0;
2673         dctl_data_t dctl = {.d32 = 0 };
2674         gintsts_data_t gintsts = {.d32 = 0 };
2675         gintmsk_data_t gintmsk = {.d32 = 0 };
2676
2677         if (ptr)
2678                 xfer_info = (ep_xfer_info_t *) ptr;
2679
2680         if (!xfer_info->ep) {
2681                 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
2682                 return;
2683         }
2684
2685         ep_num = xfer_info->ep->num;
2686         DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
2687         /* Put the sate to 2 as it was time outed */
2688         xfer_info->state = 2;
2689
2690         dctl.d32 =
2691             DWC_READ_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl);
2692         gintsts.d32 =
2693             DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintsts);
2694         gintmsk.d32 =
2695             DWC_READ_REG32(&xfer_info->core_if->core_global_regs->gintmsk);
2696
2697         if (!gintmsk.b.goutnakeff) {
2698                 /* Unmask it */
2699                 gintmsk.b.goutnakeff = 1;
2700                 DWC_WRITE_REG32(&xfer_info->core_if->core_global_regs->gintmsk,
2701                                 gintmsk.d32);
2702
2703         }
2704
2705         if (!gintsts.b.goutnakeff) {
2706                 dctl.b.sgoutnak = 1;
2707         }
2708         DWC_WRITE_REG32(&xfer_info->core_if->dev_if->dev_global_regs->dctl,
2709                         dctl.d32);
2710
2711 }
2712
2713 void set_pid_isoc(dwc_hc_t * hc)
2714 {
2715         /* Set up the initial PID for the transfer. */
2716         if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
2717                 if (hc->ep_is_in) {
2718                         if (hc->multi_count == 1) {
2719                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2720                         } else if (hc->multi_count == 2) {
2721                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
2722                         } else {
2723                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
2724                         }
2725                 } else {
2726                         if (hc->multi_count == 1) {
2727                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2728                         } else {
2729                                 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
2730                         }
2731                 }
2732         } else {
2733                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
2734         }
2735 }
2736
2737 /**
2738  * This function does the setup for a data transfer for a host channel and
2739  * starts the transfer. May be called in either Slave mode or DMA mode. In
2740  * Slave mode, the caller must ensure that there is sufficient space in the
2741  * request queue and Tx Data FIFO.
2742  *
2743  * For an OUT transfer in Slave mode, it loads a data packet into the
2744  * appropriate FIFO. If necessary, additional data packets will be loaded in
2745  * the Host ISR.
2746  *
2747  * For an IN transfer in Slave mode, a data packet is requested. The data
2748  * packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
2749  * additional data packets are requested in the Host ISR.
2750  *
2751  * For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
2752  * register along with a packet count of 1 and the channel is enabled. This
2753  * causes a single PING transaction to occur. Other fields in HCTSIZ are
2754  * simply set to 0 since no data transfer occurs in this case.
2755  *
2756  * For a PING transfer in DMA mode, the HCTSIZ register is initialized with
2757  * all the information required to perform the subsequent data transfer. In
2758  * addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
2759  * controller performs the entire PING protocol, then starts the data
2760  * transfer.
2761  *
2762  * @param core_if Programming view of DWC_otg controller.
2763  * @param hc Information needed to initialize the host channel. The xfer_len
2764  * value may be reduced to accommodate the max widths of the XferSize and
2765  * PktCnt fields in the HCTSIZn register. The multi_count value may be changed
2766  * to reflect the final xfer_len value.
2767  */
2768 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2769 {
2770         hcchar_data_t hcchar;
2771         hctsiz_data_t hctsiz;
2772         uint16_t num_packets;
2773         uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
2774         uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
2775         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2776
2777         hctsiz.d32 = 0;
2778
2779         if (hc->do_ping) {
2780                 if (!core_if->dma_enable) {
2781                         dwc_otg_hc_do_ping(core_if, hc);
2782                         hc->xfer_started = 1;
2783                         return;
2784                 } else {
2785                         hctsiz.b.dopng = 1;
2786                 }
2787         }
2788
2789         if (hc->do_split) {
2790                 num_packets = 1;
2791
2792                 if (hc->complete_split && !hc->ep_is_in) {
2793                         /* For CSPLIT OUT Transfer, set the size to 0 so the
2794                          * core doesn't expect any data written to the FIFO */
2795                         hc->xfer_len = 0;
2796                 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
2797                         hc->xfer_len = hc->max_packet;
2798                 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
2799                         hc->xfer_len = 188;
2800                 }
2801
2802                 hctsiz.b.xfersize = hc->xfer_len;
2803         } else {
2804                 /*
2805                  * Ensure that the transfer length and packet count will fit
2806                  * in the widths allocated for them in the HCTSIZn register.
2807                  */
2808                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2809                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2810                         /*
2811                          * Make sure the transfer size is no larger than one
2812                          * (micro)frame's worth of data. (A check was done
2813                          * when the periodic transfer was accepted to ensure
2814                          * that a (micro)frame's worth of data can be
2815                          * programmed into a channel.)
2816                          */
2817                         uint32_t max_periodic_len =
2818                             hc->multi_count * hc->max_packet;
2819                         if (hc->xfer_len > max_periodic_len) {
2820                                 hc->xfer_len = max_periodic_len;
2821                         } else {
2822                         }
2823                 } else if (hc->xfer_len > max_hc_xfer_size) {
2824                         /* Make sure that xfer_len is a multiple of max packet size. */
2825                         hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
2826                 }
2827
2828                 if (hc->xfer_len > 0) {
2829                         num_packets =
2830                             (hc->xfer_len + hc->max_packet -
2831                              1) / hc->max_packet;
2832                         if (num_packets > max_hc_pkt_count) {
2833                                 num_packets = max_hc_pkt_count;
2834                                 hc->xfer_len = num_packets * hc->max_packet;
2835                         }
2836                 } else {
2837                         /* Need 1 packet for transfer length of 0. */
2838                         num_packets = 1;
2839                 }
2840
2841                 if (hc->ep_is_in) {
2842                         /* Always program an integral # of max packets for IN transfers. */
2843                         hc->xfer_len = num_packets * hc->max_packet;
2844                 }
2845
2846                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
2847                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
2848                         /*
2849                          * Make sure that the multi_count field matches the
2850                          * actual transfer length.
2851                          */
2852                         hc->multi_count = num_packets;
2853                 }
2854
2855                 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2856                         set_pid_isoc(hc);
2857
2858                 hctsiz.b.xfersize = hc->xfer_len;
2859         }
2860
2861         hc->start_pkt_count = num_packets;
2862         hctsiz.b.pktcnt = num_packets;
2863         hctsiz.b.pid = hc->data_pid_start;
2864         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2865
2866         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2867         DWC_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
2868         DWC_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n", hctsiz.b.pktcnt);
2869         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
2870
2871         if (core_if->dma_enable) {
2872                 dwc_dma_t dma_addr;
2873                 if (hc->align_buff) {
2874                         dma_addr = hc->align_buff;
2875                 } else {
2876                         dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
2877                 }
2878                 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
2879         }
2880
2881         /* Start the split */
2882         if (hc->do_split) {
2883                 hcsplt_data_t hcsplt;
2884                 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
2885                 hcsplt.b.spltena = 1;
2886                 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
2887         }
2888
2889         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2890         hcchar.b.multicnt = hc->multi_count;
2891         hc_set_even_odd_frame(core_if, hc, &hcchar);
2892 #ifdef DEBUG
2893         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2894         if (hcchar.b.chdis) {
2895                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2896                          __func__, hc->hc_num, hcchar.d32);
2897         }
2898 #endif
2899
2900         /* Set host channel enable after all other setup is complete. */
2901         hcchar.b.chen = 1;
2902         hcchar.b.chdis = 0;
2903         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2904
2905         hc->xfer_started = 1;
2906         hc->requests++;
2907
2908         if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
2909                 /* Load OUT packet into the appropriate Tx FIFO. */
2910                 dwc_otg_hc_write_packet(core_if, hc);
2911         }
2912 #ifdef DEBUG
2913         if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
2914                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2915                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2916
2917                 /* Start a timer for this transfer. */
2918                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2919         }
2920 #endif
2921 }
2922
2923 /**
2924  * This function does the setup for a data transfer for a host channel
2925  * and starts the transfer in Descriptor DMA mode.
2926  *
2927  * Initializes HCTSIZ register. For a PING transfer the Do Ping bit is set.
2928  * Sets PID and NTD values. For periodic transfers
2929  * initializes SCHED_INFO field with micro-frame bitmap.
2930  *
2931  * Initializes HCDMA register with descriptor list address and CTD value
2932  * then starts the transfer via enabling the channel.
2933  *
2934  * @param core_if Programming view of DWC_otg controller.
2935  * @param hc Information needed to initialize the host channel.
2936  */
2937 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
2938 {
2939         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
2940         hcchar_data_t hcchar;
2941         hctsiz_data_t hctsiz;
2942         hcdma_data_t hcdma;
2943
2944         hctsiz.d32 = 0;
2945
2946         if (hc->do_ping)
2947                 hctsiz.b_ddma.dopng = 1;
2948
2949         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
2950                 set_pid_isoc(hc);
2951
2952         /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
2953         hctsiz.b_ddma.pid = hc->data_pid_start;
2954         hctsiz.b_ddma.ntd = hc->ntd - 1;        /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
2955         hctsiz.b_ddma.schinfo = hc->schinfo;    /* Non-zero only for high-speed interrupt endpoints */
2956
2957         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
2958         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
2959         DWC_DEBUGPL(DBG_HCDV, "  NTD: %d\n", hctsiz.b_ddma.ntd);
2960
2961         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
2962
2963         hcdma.d32 = 0;
2964         hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
2965
2966         /* Always start from first descriptor. */
2967         hcdma.b.ctd = 0;
2968         DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
2969
2970         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
2971         hcchar.b.multicnt = hc->multi_count;
2972
2973 #ifdef DEBUG
2974         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
2975         if (hcchar.b.chdis) {
2976                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
2977                          __func__, hc->hc_num, hcchar.d32);
2978         }
2979 #endif
2980
2981         /* Set host channel enable after all other setup is complete. */
2982         hcchar.b.chen = 1;
2983         hcchar.b.chdis = 0;
2984
2985         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
2986
2987         hc->xfer_started = 1;
2988         hc->requests++;
2989
2990 #ifdef DEBUG
2991         if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
2992             && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
2993                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
2994                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
2995                 /* Start a timer for this transfer. */
2996                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
2997         }
2998 #endif
2999
3000 }
3001
3002 /**
3003  * This function continues a data transfer that was started by previous call
3004  * to <code>dwc_otg_hc_start_transfer</code>. The caller must ensure there is
3005  * sufficient space in the request queue and Tx Data FIFO. This function
3006  * should only be called in Slave mode. In DMA mode, the controller acts
3007  * autonomously to complete transfers programmed to a host channel.
3008  *
3009  * For an OUT transfer, a new data packet is loaded into the appropriate FIFO
3010  * if there is any data remaining to be queued. For an IN transfer, another
3011  * data packet is always requested. For the SETUP phase of a control transfer,
3012  * this function does nothing.
3013  *
3014  * @return 1 if a new request is queued, 0 if no more requests are required
3015  * for this transfer.
3016  */
3017 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3018 {
3019         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3020
3021         if (hc->do_split) {
3022                 /* SPLITs always queue just once per channel */
3023                 return 0;
3024         } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
3025                 /* SETUPs are queued only once since they can't be NAKed. */
3026                 return 0;
3027         } else if (hc->ep_is_in) {
3028                 /*
3029                  * Always queue another request for other IN transfers. If
3030                  * back-to-back INs are issued and NAKs are received for both,
3031                  * the driver may still be processing the first NAK when the
3032                  * second NAK is received. When the interrupt handler clears
3033                  * the NAK interrupt for the first NAK, the second NAK will
3034                  * not be seen. So we can't depend on the NAK interrupt
3035                  * handler to requeue a NAKed request. Instead, IN requests
3036                  * are issued each time this function is called. When the
3037                  * transfer completes, the extra requests for the channel will
3038                  * be flushed.
3039                  */
3040                 hcchar_data_t hcchar;
3041                 dwc_otg_hc_regs_t *hc_regs =
3042                     core_if->host_if->hc_regs[hc->hc_num];
3043
3044                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3045                 hc_set_even_odd_frame(core_if, hc, &hcchar);
3046                 hcchar.b.chen = 1;
3047                 hcchar.b.chdis = 0;
3048                 DWC_DEBUGPL(DBG_HCDV, "  IN xfer: hcchar = 0x%08x\n",
3049                             hcchar.d32);
3050                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3051                 hc->requests++;
3052                 return 1;
3053         } else {
3054                 /* OUT transfers. */
3055                 if (hc->xfer_count < hc->xfer_len) {
3056                         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
3057                             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
3058                                 hcchar_data_t hcchar;
3059                                 dwc_otg_hc_regs_t *hc_regs;
3060                                 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3061                                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3062                                 hc_set_even_odd_frame(core_if, hc, &hcchar);
3063                         }
3064
3065                         /* Load OUT packet into the appropriate Tx FIFO. */
3066                         dwc_otg_hc_write_packet(core_if, hc);
3067                         hc->requests++;
3068                         return 1;
3069                 } else {
3070                         return 0;
3071                 }
3072         }
3073 }
3074
3075 /**
3076  * Starts a PING transfer. This function should only be called in Slave mode.
3077  * The Do Ping bit is set in the HCTSIZ register, then the channel is enabled.
3078  */
3079 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3080 {
3081         hcchar_data_t hcchar;
3082         hctsiz_data_t hctsiz;
3083         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
3084
3085         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
3086
3087         hctsiz.d32 = 0;
3088         hctsiz.b.dopng = 1;
3089         hctsiz.b.pktcnt = 1;
3090         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
3091
3092         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
3093         hcchar.b.chen = 1;
3094         hcchar.b.chdis = 0;
3095         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
3096 }
3097
3098 /*
3099  * This function writes a packet into the Tx FIFO associated with the Host
3100  * Channel. For a channel associated with a non-periodic EP, the non-periodic
3101  * Tx FIFO is written. For a channel associated with a periodic EP, the
3102  * periodic Tx FIFO is written. This function should only be called in Slave
3103  * mode.
3104  *
3105  * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
3106  * then number of bytes written to the Tx FIFO.
3107  */
3108 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
3109 {
3110         uint32_t i;
3111         uint32_t remaining_count;
3112         uint32_t byte_count;
3113         uint32_t dword_count;
3114
3115         uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
3116         uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
3117
3118         remaining_count = hc->xfer_len - hc->xfer_count;
3119         if (remaining_count > hc->max_packet) {
3120                 byte_count = hc->max_packet;
3121         } else {
3122                 byte_count = remaining_count;
3123         }
3124
3125         dword_count = (byte_count + 3) / 4;
3126
3127         if ((((unsigned long)data_buff) & 0x3) == 0) {
3128                 /* xfer_buff is DWORD aligned. */
3129                 for (i = 0; i < dword_count; i++, data_buff++) {
3130                         DWC_WRITE_REG32(data_fifo, *data_buff);
3131                 }
3132         } else {
3133                 /* xfer_buff is not DWORD aligned. */
3134                 for (i = 0; i < dword_count; i++, data_buff++) {
3135                         uint32_t data;
3136                         data =
3137                             (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
3138                              16 | data_buff[3] << 24);
3139                         DWC_WRITE_REG32(data_fifo, data);
3140                 }
3141         }
3142
3143         hc->xfer_count += byte_count;
3144         hc->xfer_buff += byte_count;
3145 }
3146
3147 /**
3148  * Gets the current USB frame number. This is the frame number from the last
3149  * SOF packet.
3150  */
3151 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
3152 {
3153         dsts_data_t dsts;
3154         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
3155
3156         /* read current frame/microframe number from DSTS register */
3157         return dsts.b.soffn;
3158 }
3159
3160 /**
3161  * Calculates and gets the frame Interval value of HFIR register according PHY 
3162  * type and speed.The application can modify a value of HFIR register only after
3163  * the Port Enable bit of the Host Port Control and Status register 
3164  * (HPRT.PrtEnaPort) has been set.
3165 */
3166
3167 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
3168 {
3169         gusbcfg_data_t usbcfg;
3170         hwcfg2_data_t hwcfg2;
3171         hprt0_data_t hprt0;
3172         int clock = 60;         // default value
3173         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
3174         hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
3175         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
3176         if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3177                 clock = 60;
3178         if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
3179                 clock = 48;
3180         if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3181             !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3182                 clock = 30;
3183         if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3184             !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
3185                 clock = 60;
3186         if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
3187             !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
3188                 clock = 48;
3189         if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
3190                 clock = 48;
3191         if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
3192                 clock = 48;
3193         if (hprt0.b.prtspd == 0)
3194                 /* High speed case */
3195                 return 125 * clock;
3196         else
3197                 /* FS/LS case */
3198                 return 1000 * clock;
3199 }
3200
3201 /**
3202  * This function reads a setup packet from the Rx FIFO into the destination
3203  * buffer. This function is called from the Rx Status Queue Level (RxStsQLvl)
3204  * Interrupt routine when a SETUP packet has been received in Slave mode.
3205  *
3206  * @param core_if Programming view of DWC_otg controller.
3207  * @param dest Destination buffer for packet data.
3208  */
3209 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
3210 {
3211         device_grxsts_data_t status;
3212         /* Get the 8 bytes of a setup transaction data */
3213
3214         /* Pop 2 DWORDS off the receive data FIFO into memory */
3215         dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
3216         dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
3217         if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
3218                 status.d32 =
3219                     DWC_READ_REG32(&core_if->core_global_regs->grxstsp);
3220                 DWC_DEBUGPL(DBG_ANY,
3221                             "EP:%d BCnt:%d " "pktsts:%x Frame:%d(0x%0x)\n",
3222                             status.b.epnum, status.b.bcnt, status.b.pktsts,
3223                             status.b.fn, status.b.fn);
3224         }
3225 }
3226
3227 /**
3228  * This function enables EP0 OUT to receive SETUP packets and configures EP0
3229  * IN for transmitting packets. It is normally called when the
3230  * "Enumeration Done" interrupt occurs.
3231  *
3232  * @param core_if Programming view of DWC_otg controller.
3233  * @param ep The EP0 data.
3234  */
3235 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3236 {
3237         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3238         dsts_data_t dsts;
3239         depctl_data_t diepctl;
3240         depctl_data_t doepctl;
3241         dctl_data_t dctl = {.d32 = 0 };
3242
3243         ep->stp_rollover = 0;
3244         /* Read the Device Status and Endpoint 0 Control registers */
3245         dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
3246         diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
3247         doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
3248
3249         /* Set the MPS of the IN EP based on the enumeration speed */
3250         switch (dsts.b.enumspd) {
3251         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
3252         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
3253         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
3254                 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
3255                 break;
3256         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
3257                 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
3258                 break;
3259         }
3260
3261         DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
3262
3263         /* Enable OUT EP for receive */
3264         if (core_if->snpsid <= OTG_CORE_REV_2_94a) {
3265                 doepctl.b.epena = 1;
3266                 DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
3267         }
3268 #ifdef VERBOSE
3269         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
3270                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
3271         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
3272                     DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
3273 #endif
3274         dctl.b.cgnpinnak = 1;
3275
3276         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
3277         DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
3278                     DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
3279
3280 }
3281
3282 /**
3283  * This function activates an EP.  The Device EP control register for
3284  * the EP is configured as defined in the ep structure. Note: This
3285  * function is not used for EP0.
3286  *
3287  * @param core_if Programming view of DWC_otg controller.
3288  * @param ep The EP to activate.
3289  */
3290 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3291 {
3292         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3293         depctl_data_t depctl;
3294         volatile uint32_t *addr;
3295         daint_data_t daintmsk = {.d32 = 0 };
3296         dcfg_data_t dcfg;
3297         uint8_t i;
3298
3299         DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
3300                     (ep->is_in ? "IN" : "OUT"));
3301
3302 #ifdef DWC_UTE_PER_IO
3303         ep->xiso_frame_num = 0xFFFFFFFF;
3304         ep->xiso_active_xfers = 0;
3305         ep->xiso_queued_xfers = 0;
3306 #endif
3307         /* Read DEPCTLn register */
3308         if (ep->is_in == 1) {
3309                 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
3310                 daintmsk.ep.in = 1 << ep->num;
3311         } else {
3312                 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
3313                 daintmsk.ep.out = 1 << ep->num;
3314         }
3315
3316         /* If the EP is already active don't change the EP Control
3317          * register. */
3318         depctl.d32 = DWC_READ_REG32(addr);
3319         if (!depctl.b.usbactep) {
3320                 depctl.b.mps = ep->maxpacket;
3321                 depctl.b.eptype = ep->type;
3322                 depctl.b.txfnum = ep->tx_fifo_num;
3323
3324                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3325                         depctl.b.setd0pid = 1;  // ???
3326                 } else {
3327                         depctl.b.setd0pid = 1;
3328                 }
3329                 depctl.b.usbactep = 1;
3330
3331                 /* Update nextep_seq array and EPMSCNT in DCFG */
3332                 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) {       // NP IN EP
3333                         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3334                                 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
3335                                         break;
3336                         }
3337                         core_if->nextep_seq[i] = ep->num;
3338                         core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
3339                         depctl.b.nextep = core_if->nextep_seq[ep->num];
3340                         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
3341                         dcfg.b.epmscnt++;
3342                         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
3343
3344                         DWC_DEBUGPL(DBG_PCDV,
3345                                     "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3346                                     __func__, core_if->first_in_nextep_seq);
3347                         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3348                                 DWC_DEBUGPL(DBG_PCDV, "%2d\n",
3349                                             core_if->nextep_seq[i]);
3350                         }
3351
3352                 }
3353
3354
3355                 DWC_WRITE_REG32(addr, depctl.d32);
3356                 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
3357         }
3358
3359         /* Enable the Interrupt for this EP */
3360         if (core_if->multiproc_int_enable) {
3361                 if (ep->is_in == 1) {
3362                         diepmsk_data_t diepmsk = {.d32 = 0 };
3363                         diepmsk.b.xfercompl = 1;
3364                         diepmsk.b.timeout = 1;
3365                         diepmsk.b.epdisabled = 1;
3366                         diepmsk.b.ahberr = 1;
3367                         diepmsk.b.intknepmis = 1;
3368                         if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
3369                                 diepmsk.b.intknepmis = 0;
3370                         diepmsk.b.txfifoundrn = 1;      //?????
3371                         if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3372                                 diepmsk.b.nak = 1;
3373                         }
3374
3375 /*
3376                         if (core_if->dma_desc_enable) {
3377                                 diepmsk.b.bna = 1;
3378                         }
3379 */
3380 /*                      
3381                         if (core_if->dma_enable) {
3382                                 doepmsk.b.nak = 1;
3383                         }
3384 */
3385                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
3386                                         diepeachintmsk[ep->num], diepmsk.d32);
3387
3388                 } else {
3389                         doepmsk_data_t doepmsk = {.d32 = 0 };
3390                         doepmsk.b.xfercompl = 1;
3391                         doepmsk.b.ahberr = 1;
3392                         doepmsk.b.epdisabled = 1;
3393                         if (ep->type == DWC_OTG_EP_TYPE_ISOC)
3394                                 doepmsk.b.outtknepdis = 1;
3395
3396 /*                      
3397
3398                         if (core_if->dma_desc_enable) {
3399                                 doepmsk.b.bna = 1;
3400                         }
3401 */
3402 /*                      
3403                         doepmsk.b.babble = 1;
3404                         doepmsk.b.nyet = 1;
3405                         doepmsk.b.nak = 1;
3406 */
3407                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
3408                                         doepeachintmsk[ep->num], doepmsk.d32);
3409                 }
3410                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
3411                                  0, daintmsk.d32);
3412         } else {
3413                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3414                         if (ep->is_in) {
3415                                 diepmsk_data_t diepmsk = {.d32 = 0 };
3416                                 diepmsk.b.nak = 1;
3417                                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
3418                         } else {
3419                                 doepmsk_data_t doepmsk = {.d32 = 0 };
3420                                 doepmsk.b.outtknepdis = 1;
3421                                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
3422                         }
3423                 }
3424                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
3425                                  0, daintmsk.d32);
3426         }
3427
3428         DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
3429                     DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
3430
3431         ep->stall_clear_flag = 0;
3432
3433         return;
3434 }
3435
3436 /**
3437  * This function deactivates an EP. This is done by clearing the USB Active
3438  * EP bit in the Device EP control register. Note: This function is not used
3439  * for EP0. EP0 cannot be deactivated.
3440  *
3441  * @param core_if Programming view of DWC_otg controller.
3442  * @param ep The EP to deactivate.
3443  */
3444 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3445 {
3446         depctl_data_t depctl = {.d32 = 0 };
3447         volatile uint32_t *addr;
3448         daint_data_t daintmsk = {.d32 = 0 };
3449         dcfg_data_t dcfg;
3450         uint8_t i = 0;
3451
3452 #ifdef DWC_UTE_PER_IO
3453         ep->xiso_frame_num = 0xFFFFFFFF;
3454         ep->xiso_active_xfers = 0;
3455         ep->xiso_queued_xfers = 0;
3456 #endif
3457
3458         /* Read DEPCTLn register */
3459         if (ep->is_in == 1) {
3460                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
3461                 daintmsk.ep.in = 1 << ep->num;
3462         } else {
3463                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
3464                 daintmsk.ep.out = 1 << ep->num;
3465         }
3466
3467         depctl.d32 = DWC_READ_REG32(addr);
3468
3469         depctl.b.usbactep = 0;
3470
3471         /* Update nextep_seq array and EPMSCNT in DCFG */
3472         if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN
3473                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3474                         if (core_if->nextep_seq[i] == ep->num)
3475                                 break;
3476                 }
3477                 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];
3478                 if (core_if->first_in_nextep_seq == ep->num)
3479                         core_if->first_in_nextep_seq = i;
3480                 core_if->nextep_seq[ep->num] = 0xff;
3481                 depctl.b.nextep = 0;
3482                 dcfg.d32 =
3483                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
3484                 dcfg.b.epmscnt--;
3485                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
3486                                 dcfg.d32);
3487
3488                 DWC_DEBUGPL(DBG_PCDV,
3489                             "%s first_in_nextep_seq= %2d; nextep_seq[]:\n",
3490                             __func__, core_if->first_in_nextep_seq);
3491                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
3492                         DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
3493                 }
3494         }
3495                 
3496         if (ep->is_in == 1)
3497                 depctl.b.txfnum = 0;
3498
3499         if (core_if->dma_desc_enable)
3500                 depctl.b.epdis = 1;
3501
3502         DWC_WRITE_REG32(addr, depctl.d32);
3503         depctl.d32 = DWC_READ_REG32(addr);
3504         if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC
3505             && depctl.b.epena) {
3506                 depctl_data_t depctl = {.d32 = 0 };
3507                 if (ep->is_in) {
3508                         diepint_data_t diepint = {.d32 = 0 };
3509
3510                         depctl.b.snak = 1;
3511                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3512                                         diepctl, depctl.d32);
3513                         do {
3514                                 dwc_udelay(10);
3515                                 diepint.d32 =
3516                                     DWC_READ_REG32(&core_if->
3517                                                    dev_if->in_ep_regs[ep->num]->
3518                                                    diepint);
3519                         } while (!diepint.b.inepnakeff);
3520                         diepint.b.inepnakeff = 1;
3521                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3522                                         diepint, diepint.d32);
3523                         depctl.d32 = 0;
3524                         depctl.b.epdis = 1;
3525                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3526                                         diepctl, depctl.d32);
3527                         do {
3528                                 dwc_udelay(10);
3529                                 diepint.d32 =
3530                                     DWC_READ_REG32(&core_if->
3531                                                    dev_if->in_ep_regs[ep->num]->
3532                                                    diepint);
3533                         } while (!diepint.b.epdisabled);
3534                         diepint.b.epdisabled = 1;
3535                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
3536                                         diepint, diepint.d32);
3537                 } else {
3538                         dctl_data_t dctl = {.d32 = 0};
3539                         gintmsk_data_t gintsts = {.d32 = 0};
3540                         doepint_data_t doepint = {.d32 = 0};
3541                         dctl.b.sgoutnak = 1;
3542                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
3543                                          dctl, 0, dctl.d32);
3544                         do {
3545                                 dwc_udelay(10);
3546                                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
3547                         } while (!gintsts.b.goutnakeff); 
3548                         gintsts.d32 = 0;
3549                         gintsts.b.goutnakeff = 1;
3550                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
3551
3552                         depctl.d32 = 0;
3553                         depctl.b.epdis = 1;
3554                         depctl.b.snak = 1;
3555                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
3556                         do 
3557                         {
3558                                 dwc_udelay(10);
3559                                 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
3560                                                                                         out_ep_regs[ep->num]->doepint);
3561                         } while (!doepint.b.epdisabled); 
3562
3563                         doepint.b.epdisabled = 1;
3564                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
3565
3566                         dctl.d32 = 0;
3567                         dctl.b.cgoutnak = 1;
3568                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
3569                 }               
3570         }
3571
3572         /* Disable the Interrupt for this EP */
3573         if (core_if->multiproc_int_enable) {
3574                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
3575                                  daintmsk.d32, 0);
3576
3577                 if (ep->is_in == 1) {
3578                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3579                                         diepeachintmsk[ep->num], 0);
3580                 } else {
3581                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
3582                                         doepeachintmsk[ep->num], 0);
3583                 }
3584         } else {
3585                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
3586                                  daintmsk.d32, 0);
3587         }
3588
3589 }
3590
3591 /**
3592  * This function initializes dma descriptor chain.
3593  *
3594  * @param core_if Programming view of DWC_otg controller.
3595  * @param ep The EP to start the transfer on.
3596  */
3597 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3598 {
3599         dwc_otg_dev_dma_desc_t *dma_desc;
3600         uint32_t offset;
3601         uint32_t xfer_est;
3602         int i;
3603         unsigned maxxfer_local, total_len;
3604
3605         if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR &&
3606             (ep->maxpacket % 4)) {
3607                 maxxfer_local = ep->maxpacket;
3608                 total_len = ep->xfer_len;
3609         } else {
3610                 maxxfer_local = ep->maxxfer;
3611                 total_len = ep->total_len;
3612         }
3613
3614         ep->desc_cnt = (total_len / maxxfer_local) +
3615             ((total_len % maxxfer_local) ? 1 : 0);
3616
3617         if (!ep->desc_cnt)
3618                 ep->desc_cnt = 1;
3619
3620         if (ep->desc_cnt > MAX_DMA_DESC_CNT)
3621                 ep->desc_cnt = MAX_DMA_DESC_CNT;
3622
3623         dma_desc = ep->desc_addr;
3624         if (maxxfer_local == ep->maxpacket) {
3625                 if ((total_len % maxxfer_local) &&
3626                     (total_len / maxxfer_local < MAX_DMA_DESC_CNT)) {
3627                         xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
3628                             (total_len % maxxfer_local);
3629                 } else
3630                         xfer_est = ep->desc_cnt * maxxfer_local;
3631         } else
3632                 xfer_est = total_len;
3633         offset = 0;
3634         for (i = 0; i < ep->desc_cnt; ++i) {
3635                 /** DMA Descriptor Setup */
3636                 if (xfer_est > maxxfer_local) {
3637                         dma_desc->status.b.bs = BS_HOST_BUSY;
3638                         dma_desc->status.b.l = 0;
3639                         dma_desc->status.b.ioc = 0;
3640                         dma_desc->status.b.sp = 0;
3641                         dma_desc->status.b.bytes = maxxfer_local;
3642                         dma_desc->buf = ep->dma_addr + offset;
3643                         dma_desc->status.b.sts = 0;
3644                         dma_desc->status.b.bs = BS_HOST_READY;
3645
3646                         xfer_est -= maxxfer_local;
3647                         offset += maxxfer_local;
3648                 } else {
3649                         dma_desc->status.b.bs = BS_HOST_BUSY;
3650                         dma_desc->status.b.l = 1;
3651                         dma_desc->status.b.ioc = 1;
3652                         if (ep->is_in) {
3653                                 dma_desc->status.b.sp =
3654                                     (xfer_est %
3655                                      ep->maxpacket) ? 1 : ((ep->
3656                                                             sent_zlp) ? 1 : 0);
3657                                 dma_desc->status.b.bytes = xfer_est;
3658                         } else {
3659                                 if (maxxfer_local == ep->maxpacket)
3660                                         dma_desc->status.b.bytes = xfer_est;
3661                                 else    
3662                                         dma_desc->status.b.bytes =
3663                                                 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
3664                         }
3665
3666                         dma_desc->buf = ep->dma_addr + offset;
3667                         dma_desc->status.b.sts = 0;
3668                         dma_desc->status.b.bs = BS_HOST_READY;
3669                 }
3670                 dma_desc++;
3671         }
3672 }
3673
3674 /**
3675  * This function is called when to write ISOC data into appropriate dedicated 
3676  * periodic FIFO.
3677  */
3678 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
3679 {
3680         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
3681         dwc_otg_dev_in_ep_regs_t *ep_regs;
3682         dtxfsts_data_t txstatus = {.d32 = 0 };
3683         uint32_t len = 0;
3684         int epnum = dwc_ep->num;
3685         int dwords;
3686
3687         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
3688
3689         ep_regs = core_if->dev_if->in_ep_regs[epnum];
3690
3691         len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3692
3693         if (len > dwc_ep->maxpacket) {
3694                 len = dwc_ep->maxpacket;
3695         }
3696
3697         dwords = (len + 3) / 4;
3698
3699         /* While there is space in the queue and space in the FIFO and
3700          * More data to tranfer, Write packets to the Tx FIFO */
3701         txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3702         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
3703
3704         while (txstatus.b.txfspcavail > dwords &&
3705                dwc_ep->xfer_count < dwc_ep->xfer_len && dwc_ep->xfer_len != 0) {
3706                 /* Write the FIFO */
3707                 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
3708
3709                 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
3710                 if (len > dwc_ep->maxpacket) {
3711                         len = dwc_ep->maxpacket;
3712                 }
3713
3714                 dwords = (len + 3) / 4;
3715                 txstatus.d32 =
3716                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
3717                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
3718                             txstatus.d32);
3719         }
3720
3721         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
3722                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
3723
3724         return 1;
3725 }
3726
3727 /**
3728  * This function does the setup for a data transfer for an EP and
3729  * starts the transfer. For an IN transfer, the packets will be
3730  * loaded into the appropriate Tx FIFO in the ISR. For OUT transfers,
3731  * the packets are unloaded from the Rx FIFO in the ISR.  the ISR.
3732  *
3733  * @param core_if Programming view of DWC_otg controller.
3734  * @param ep The EP to start the transfer on.
3735  */
3736
3737 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
3738 {
3739         depctl_data_t depctl;
3740         deptsiz_data_t deptsiz;
3741         gintmsk_data_t intr_mask = {.d32 = 0 };
3742
3743         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
3744         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
3745                     "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
3746                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
3747                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
3748                     ep->total_len);
3749         /* IN endpoint */
3750         if (ep->is_in == 1) {
3751                 dwc_otg_dev_in_ep_regs_t *in_regs =
3752                     core_if->dev_if->in_ep_regs[ep->num];
3753
3754                 gnptxsts_data_t gtxstatus;
3755
3756                 gtxstatus.d32 =
3757                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
3758
3759                 if (core_if->en_multiple_tx_fifo == 0
3760                     && gtxstatus.b.nptxqspcavail == 0 && !core_if->dma_enable) {
3761 #ifdef DEBUG
3762                         DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
3763 #endif
3764                         return;
3765                 }
3766
3767                 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
3768                 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
3769
3770                 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3771                         ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3772                                 ep->maxxfer : (ep->total_len - ep->xfer_len);
3773                 else 
3774                         ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
3775                                  MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3776
3777
3778                 /* Zero Length Packet? */
3779                 if ((ep->xfer_len - ep->xfer_count) == 0) {
3780                         deptsiz.b.xfersize = 0;
3781                         deptsiz.b.pktcnt = 1;
3782                 } else {
3783                         /* Program the transfer size and packet count
3784                          *      as follows: xfersize = N * maxpacket +
3785                          *      short_packet pktcnt = N + (short_packet
3786                          *      exist ? 1 : 0) 
3787                          */
3788                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3789                         deptsiz.b.pktcnt =
3790                             (ep->xfer_len - ep->xfer_count - 1 +
3791                              ep->maxpacket) / ep->maxpacket;
3792                         if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3793                                 deptsiz.b.pktcnt = MAX_PKT_CNT;
3794                                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
3795                         } 
3796                         if (ep->type == DWC_OTG_EP_TYPE_ISOC) 
3797                                 deptsiz.b.mc = deptsiz.b.pktcnt;
3798                 }
3799
3800                 /* Write the DMA register */
3801                 if (core_if->dma_enable) {
3802                         if (core_if->dma_desc_enable == 0) {
3803                                 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
3804                                         deptsiz.b.mc = 1;
3805                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
3806                                                 deptsiz.d32);
3807                                 DWC_WRITE_REG32(&(in_regs->diepdma),
3808                                                 (uint32_t) ep->dma_addr);
3809                         } else {
3810 #ifdef DWC_UTE_CFI
3811                                 /* The descriptor chain should be already initialized by now */
3812                                 if (ep->buff_mode != BM_STANDARD) {
3813                                         DWC_WRITE_REG32(&in_regs->diepdma,
3814                                                         ep->descs_dma_addr);
3815                                 } else {
3816 #endif
3817                                         init_dma_desc_chain(core_if, ep);
3818                                 /** DIEPDMAn Register write */
3819                                         DWC_WRITE_REG32(&in_regs->diepdma,
3820                                                         ep->dma_desc_addr);
3821 #ifdef DWC_UTE_CFI
3822                                 }
3823 #endif
3824                         }
3825                 } else {
3826                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
3827                         if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
3828                                 /**
3829                                  * Enable the Non-Periodic Tx FIFO empty interrupt,
3830                                  * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
3831                                  * the data will be written into the fifo by the ISR.
3832                                  */
3833                                 if (core_if->en_multiple_tx_fifo == 0) {
3834                                         intr_mask.b.nptxfempty = 1;
3835                                         DWC_MODIFY_REG32
3836                                             (&core_if->core_global_regs->gintmsk,
3837                                              intr_mask.d32, intr_mask.d32);
3838                                 } else {
3839                                         /* Enable the Tx FIFO Empty Interrupt for this EP */
3840                                         if (ep->xfer_len > 0) {
3841                                                 uint32_t fifoemptymsk = 0;
3842                                                 fifoemptymsk = 1 << ep->num;
3843                                                 DWC_MODIFY_REG32
3844                                                     (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
3845                                                      0, fifoemptymsk);
3846
3847                                         }
3848                                 }
3849                         } else {
3850                                 write_isoc_tx_fifo(core_if, ep);
3851                         }
3852                 }
3853                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
3854                         depctl.b.nextep = core_if->nextep_seq[ep->num];
3855
3856                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3857                         dsts_data_t dsts = {.d32 = 0 };
3858                         if (ep->bInterval == 1) {
3859                                 dsts.d32 =
3860                                     DWC_READ_REG32(&core_if->dev_if->
3861                                                    dev_global_regs->dsts);
3862                                 ep->frame_num = dsts.b.soffn + ep->bInterval;
3863                                 if (ep->frame_num > 0x3FFF) {
3864                                         ep->frm_overrun = 1;
3865                                         ep->frame_num &= 0x3FFF;
3866                                 } else
3867                                         ep->frm_overrun = 0;
3868                                 if (ep->frame_num & 0x1) {
3869                                         depctl.b.setd1pid = 1;
3870                                 } else {
3871                                         depctl.b.setd0pid = 1;
3872                                 }
3873                         }
3874                 }
3875                 /* EP enable, IN data in FIFO */
3876                 depctl.b.cnak = 1;
3877                 depctl.b.epena = 1;
3878                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
3879
3880         } else {
3881                 /* OUT endpoint */
3882                 dwc_otg_dev_out_ep_regs_t *out_regs =
3883                     core_if->dev_if->out_ep_regs[ep->num];
3884
3885                 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
3886                 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
3887
3888                 if (!core_if->dma_desc_enable) {        
3889                         if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
3890                                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
3891                                 ep->maxxfer : (ep->total_len - ep->xfer_len);
3892                 else
3893                                         ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len 
3894                                         - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
3895                 }
3896
3897                 /* Program the transfer size and packet count as follows:
3898                  *
3899                  *      pktcnt = N                                                                                
3900                  *      xfersize = N * maxpacket
3901                  */
3902                 if ((ep->xfer_len - ep->xfer_count) == 0) {
3903                         /* Zero Length Packet */
3904                         deptsiz.b.xfersize = ep->maxpacket;
3905                         deptsiz.b.pktcnt = 1;
3906                 } else {
3907                         deptsiz.b.pktcnt =
3908                             (ep->xfer_len - ep->xfer_count +
3909                              (ep->maxpacket - 1)) / ep->maxpacket;
3910                         if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
3911                                 deptsiz.b.pktcnt = MAX_PKT_CNT;
3912                         }
3913                         if (!core_if->dma_desc_enable) {
3914                                 ep->xfer_len =
3915                                         deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
3916                         }
3917                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
3918                 }
3919
3920                 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
3921                             ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
3922
3923                 if (core_if->dma_enable) {
3924                         if (!core_if->dma_desc_enable) {
3925                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
3926                                                 deptsiz.d32);
3927
3928                                 DWC_WRITE_REG32(&(out_regs->doepdma),
3929                                                 (uint32_t) ep->dma_addr);
3930                         } else {
3931 #ifdef DWC_UTE_CFI
3932                                 /* The descriptor chain should be already initialized by now */
3933                                 if (ep->buff_mode != BM_STANDARD) {
3934                                         DWC_WRITE_REG32(&out_regs->doepdma,
3935                                                         ep->descs_dma_addr);
3936                                 } else {
3937 #endif
3938                                         /** This is used for interrupt out transfers*/
3939                                         if (!ep->xfer_len)
3940                                                 ep->xfer_len = ep->total_len;
3941                                         init_dma_desc_chain(core_if, ep);
3942
3943                                         if (core_if->core_params->dev_out_nak) {
3944                                                 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
3945                                                         deptsiz.b.pktcnt = (ep->total_len +
3946                                                                 (ep->maxpacket - 1)) / ep->maxpacket;
3947                                                         deptsiz.b.xfersize = ep->total_len;
3948                                                         /* Remember initial value of doeptsiz */
3949                                                         core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
3950                                                         DWC_WRITE_REG32(&out_regs->doeptsiz,
3951                                                                 deptsiz.d32);                                                                                                   
3952                                                 }
3953                                         }
3954                                 /** DOEPDMAn Register write */
3955                                         DWC_WRITE_REG32(&out_regs->doepdma,
3956                                                         ep->dma_desc_addr);
3957 #ifdef DWC_UTE_CFI
3958                                 }
3959 #endif
3960                         }
3961                 } else {
3962                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
3963                 }
3964
3965                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
3966                         dsts_data_t dsts = {.d32 = 0 };
3967                         if (ep->bInterval == 1) {
3968                                 dsts.d32 =
3969                                     DWC_READ_REG32(&core_if->dev_if->
3970                                                    dev_global_regs->dsts);
3971                                 ep->frame_num = dsts.b.soffn + ep->bInterval;
3972                                 if (ep->frame_num > 0x3FFF) {
3973                                         ep->frm_overrun = 1;
3974                                         ep->frame_num &= 0x3FFF;
3975                                 } else
3976                                         ep->frm_overrun = 0;
3977
3978                                 if (ep->frame_num & 0x1) {
3979                                         depctl.b.setd1pid = 1;
3980                                 } else {
3981                                         depctl.b.setd0pid = 1;
3982                                 }
3983                         }
3984                 }
3985
3986                 /* EP enable */
3987                 depctl.b.cnak = 1;
3988                 depctl.b.epena = 1;
3989
3990                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
3991
3992                 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
3993                             DWC_READ_REG32(&out_regs->doepctl),
3994                             DWC_READ_REG32(&out_regs->doeptsiz));
3995                 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
3996                             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->
3997                                            daintmsk),
3998                             DWC_READ_REG32(&core_if->core_global_regs->
3999                                            gintmsk));
4000
4001                 /* Timer is scheduling only for out bulk transfers for 
4002                  * "Device DDMA OUT NAK Enhancement" feature to inform user 
4003                  * about received data payload in case of timeout 
4004                  */
4005                 if (core_if->core_params->dev_out_nak) {
4006                         if (ep->type == DWC_OTG_EP_TYPE_BULK) {
4007                                 core_if->ep_xfer_info[ep->num].core_if = core_if;
4008                                 core_if->ep_xfer_info[ep->num].ep = ep;
4009                                 core_if->ep_xfer_info[ep->num].state = 1;
4010
4011                                 /* Start a timer for this transfer. */
4012                                 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
4013                         }
4014                 }
4015         }
4016 }
4017
4018 /**
4019  * This function setup a zero length transfer in Buffer DMA and
4020  * Slave modes for usb requests with zero field set
4021  *
4022  * @param core_if Programming view of DWC_otg controller.
4023  * @param ep The EP to start the transfer on.
4024  *
4025  */
4026 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4027 {
4028
4029         depctl_data_t depctl;
4030         deptsiz_data_t deptsiz;
4031         gintmsk_data_t intr_mask = {.d32 = 0 };
4032
4033         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
4034         DWC_PRINTF("zero length transfer is called\n");
4035
4036         /* IN endpoint */
4037         if (ep->is_in == 1) {
4038                 dwc_otg_dev_in_ep_regs_t *in_regs =
4039                     core_if->dev_if->in_ep_regs[ep->num];
4040
4041                 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
4042                 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
4043
4044                 deptsiz.b.xfersize = 0;
4045                 deptsiz.b.pktcnt = 1;
4046
4047                 /* Write the DMA register */
4048                 if (core_if->dma_enable) {
4049                         if (core_if->dma_desc_enable == 0) {
4050                                 deptsiz.b.mc = 1;
4051                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
4052                                                 deptsiz.d32);
4053                                 DWC_WRITE_REG32(&(in_regs->diepdma),
4054                                                 (uint32_t) ep->dma_addr);
4055                         }
4056                 } else {
4057                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4058                         /**
4059                          * Enable the Non-Periodic Tx FIFO empty interrupt,
4060                          * or the Tx FIFO epmty interrupt in dedicated Tx FIFO mode,
4061                          * the data will be written into the fifo by the ISR.
4062                          */
4063                         if (core_if->en_multiple_tx_fifo == 0) {
4064                                 intr_mask.b.nptxfempty = 1;
4065                                 DWC_MODIFY_REG32(&core_if->
4066                                                  core_global_regs->gintmsk,
4067                                                  intr_mask.d32, intr_mask.d32);
4068                         } else {
4069                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
4070                                 if (ep->xfer_len > 0) {
4071                                         uint32_t fifoemptymsk = 0;
4072                                         fifoemptymsk = 1 << ep->num;
4073                                         DWC_MODIFY_REG32(&core_if->
4074                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4075                                                          0, fifoemptymsk);
4076                                 }
4077                         }
4078                 }
4079
4080                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4081                         depctl.b.nextep = core_if->nextep_seq[ep->num];
4082                 /* EP enable, IN data in FIFO */
4083                 depctl.b.cnak = 1;
4084                 depctl.b.epena = 1;
4085                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4086
4087         } else {
4088                 /* OUT endpoint */
4089                 dwc_otg_dev_out_ep_regs_t *out_regs =
4090                     core_if->dev_if->out_ep_regs[ep->num];
4091
4092                 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
4093                 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
4094
4095                 /* Zero Length Packet */
4096                 deptsiz.b.xfersize = ep->maxpacket;
4097                 deptsiz.b.pktcnt = 1;
4098
4099                 if (core_if->dma_enable) {
4100                         if (!core_if->dma_desc_enable) {
4101                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
4102                                                 deptsiz.d32);
4103
4104                                 DWC_WRITE_REG32(&(out_regs->doepdma),
4105                                                 (uint32_t) ep->dma_addr);
4106                         }
4107                 } else {
4108                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4109                 }
4110
4111                 /* EP enable */
4112                 depctl.b.cnak = 1;
4113                 depctl.b.epena = 1;
4114
4115                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4116
4117         }
4118 }
4119
4120 /**
4121  * This function does the setup for a data transfer for EP0 and starts
4122  * the transfer.  For an IN transfer, the packets will be loaded into
4123  * the appropriate Tx FIFO in the ISR. For OUT transfers, the packets are
4124  * unloaded from the Rx FIFO in the ISR.
4125  *
4126  * @param core_if Programming view of DWC_otg controller.
4127  * @param ep The EP0 data.
4128  */
4129 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4130 {
4131         depctl_data_t depctl;
4132         deptsiz0_data_t deptsiz;
4133         gintmsk_data_t intr_mask = {.d32 = 0 };
4134         dwc_otg_dev_dma_desc_t *dma_desc;
4135
4136         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
4137                     "xfer_buff=%p start_xfer_buff=%p \n",
4138                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
4139                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
4140
4141         ep->total_len = ep->xfer_len;
4142
4143         /* IN endpoint */
4144         if (ep->is_in == 1) {
4145                 dwc_otg_dev_in_ep_regs_t *in_regs =
4146                     core_if->dev_if->in_ep_regs[0];
4147
4148                 gnptxsts_data_t gtxstatus;
4149
4150                 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4151                         depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4152                         if (depctl.b.epena)
4153                                 return;
4154                 }
4155
4156                 gtxstatus.d32 =
4157                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4158
4159                 /* If dedicated FIFO every time flush fifo before enable ep*/
4160                 if (core_if->en_multiple_tx_fifo && core_if->snpsid >= OTG_CORE_REV_3_00a)
4161                         dwc_otg_flush_tx_fifo(core_if, ep->tx_fifo_num);
4162
4163                 if (core_if->en_multiple_tx_fifo == 0
4164                     && gtxstatus.b.nptxqspcavail == 0
4165                     && !core_if->dma_enable) {
4166 #ifdef DEBUG
4167                         deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4168                         DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
4169                                     DWC_READ_REG32(&in_regs->diepctl));
4170                         DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
4171                                     deptsiz.d32,
4172                                     deptsiz.b.xfersize, deptsiz.b.pktcnt);
4173                         DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
4174                                    gtxstatus.d32);
4175 #endif
4176                         return;
4177                 }
4178
4179                 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4180                 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4181
4182                 /* Zero Length Packet? */
4183                 if (ep->xfer_len == 0) {
4184                         deptsiz.b.xfersize = 0;
4185                         deptsiz.b.pktcnt = 1;
4186                 } else {
4187                         /* Program the transfer size and packet count
4188                          *      as follows: xfersize = N * maxpacket +
4189                          *      short_packet pktcnt = N + (short_packet
4190                          *      exist ? 1 : 0) 
4191                          */
4192                         if (ep->xfer_len > ep->maxpacket) {
4193                                 ep->xfer_len = ep->maxpacket;
4194                                 deptsiz.b.xfersize = ep->maxpacket;
4195                         } else {
4196                                 deptsiz.b.xfersize = ep->xfer_len;
4197                         }
4198                         deptsiz.b.pktcnt = 1;
4199
4200                 }
4201                 DWC_DEBUGPL(DBG_PCDV,
4202                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
4203                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4204                             deptsiz.d32);
4205
4206                 /* Write the DMA register */
4207                 if (core_if->dma_enable) {
4208                         if (core_if->dma_desc_enable == 0) {
4209                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
4210                                                 deptsiz.d32);
4211
4212                                 DWC_WRITE_REG32(&(in_regs->diepdma),
4213                                                 (uint32_t) ep->dma_addr);
4214                         } else {
4215                                 dma_desc = core_if->dev_if->in_desc_addr;
4216
4217                                 /** DMA Descriptor Setup */
4218                                 dma_desc->status.b.bs = BS_HOST_BUSY;
4219                                 dma_desc->status.b.l = 1;
4220                                 dma_desc->status.b.ioc = 1;
4221                                 dma_desc->status.b.sp =
4222                                     (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4223                                 dma_desc->status.b.bytes = ep->xfer_len;
4224                                 dma_desc->buf = ep->dma_addr;
4225                                 dma_desc->status.b.sts = 0;
4226                                 dma_desc->status.b.bs = BS_HOST_READY;
4227
4228                                 /** DIEPDMA0 Register write */
4229                                 DWC_WRITE_REG32(&in_regs->diepdma,
4230                                                 core_if->
4231                                                 dev_if->dma_in_desc_addr);
4232                         }
4233                 } else {
4234                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4235                 }
4236
4237                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4238                         depctl.b.nextep = core_if->nextep_seq[ep->num];
4239                 /* EP enable, IN data in FIFO */
4240                 depctl.b.cnak = 1;
4241                 depctl.b.epena = 1;
4242                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4243
4244                 /**
4245                  * Enable the Non-Periodic Tx FIFO empty interrupt, the
4246                  * data will be written into the fifo by the ISR.
4247                  */
4248                 if (!core_if->dma_enable) {
4249                         if (core_if->en_multiple_tx_fifo == 0) {
4250                                 intr_mask.b.nptxfempty = 1;
4251                                 DWC_MODIFY_REG32(&core_if->
4252                                                  core_global_regs->gintmsk,
4253                                                  intr_mask.d32, intr_mask.d32);
4254                         } else {
4255                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
4256                                 if (ep->xfer_len > 0) {
4257                                         uint32_t fifoemptymsk = 0;
4258                                         fifoemptymsk |= 1 << ep->num;
4259                                         DWC_MODIFY_REG32(&core_if->
4260                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4261                                                          0, fifoemptymsk);
4262                                 }
4263                         }
4264                 }
4265         } else {
4266                 /* OUT endpoint */
4267                 dwc_otg_dev_out_ep_regs_t *out_regs =
4268                     core_if->dev_if->out_ep_regs[0];
4269
4270                 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4271                 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4272
4273                 /* Program the transfer size and packet count as follows:
4274                  *      xfersize = N * (maxpacket + 4 - (maxpacket % 4))
4275                  *      pktcnt = N                                                                                      */
4276                 /* Zero Length Packet */
4277                 deptsiz.b.xfersize = ep->maxpacket;
4278                 deptsiz.b.pktcnt = 1;
4279                 if (core_if->snpsid >= OTG_CORE_REV_3_00a)
4280                         deptsiz.b.supcnt = 3;
4281
4282                 DWC_DEBUGPL(DBG_PCDV, "len=%d  xfersize=%d pktcnt=%d\n",
4283                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
4284
4285                 if (core_if->dma_enable) {
4286                         if (!core_if->dma_desc_enable) {
4287                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
4288                                                 deptsiz.d32);
4289
4290                                 DWC_WRITE_REG32(&(out_regs->doepdma),
4291                                                 (uint32_t) ep->dma_addr);
4292                         } else {
4293                                 dma_desc = core_if->dev_if->out_desc_addr;
4294
4295                                 /** DMA Descriptor Setup */
4296                                 dma_desc->status.b.bs = BS_HOST_BUSY;
4297                                 if (core_if->snpsid >= OTG_CORE_REV_3_00a) {
4298                                         dma_desc->status.b.mtrf = 0;
4299                                         dma_desc->status.b.sr = 0;
4300                                 }
4301                                 dma_desc->status.b.l = 1;
4302                                 dma_desc->status.b.ioc = 1;
4303                                 dma_desc->status.b.bytes = ep->maxpacket;
4304                                 dma_desc->buf = ep->dma_addr;
4305                                 dma_desc->status.b.sts = 0;
4306                                 dma_desc->status.b.bs = BS_HOST_READY;
4307
4308                                 /** DOEPDMA0 Register write */
4309                                 DWC_WRITE_REG32(&out_regs->doepdma,
4310                                                 core_if->dev_if->
4311                                                 dma_out_desc_addr);
4312                         }
4313                 } else {
4314                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4315                 }
4316
4317                 /* EP enable */
4318                 depctl.b.cnak = 1;
4319                 depctl.b.epena = 1;
4320                 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
4321         }
4322 }
4323
4324 /**
4325  * This function continues control IN transfers started by
4326  * dwc_otg_ep0_start_transfer, when the transfer does not fit in a
4327  * single packet.  NOTE: The DIEPCTL0/DOEPCTL0 registers only have one
4328  * bit for the packet count.
4329  *
4330  * @param core_if Programming view of DWC_otg controller.
4331  * @param ep The EP0 data.
4332  */
4333 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4334 {
4335         depctl_data_t depctl;
4336         deptsiz0_data_t deptsiz;
4337         gintmsk_data_t intr_mask = {.d32 = 0 };
4338         dwc_otg_dev_dma_desc_t *dma_desc;
4339
4340         if (ep->is_in == 1) {
4341                 dwc_otg_dev_in_ep_regs_t *in_regs =
4342                     core_if->dev_if->in_ep_regs[0];
4343                 gnptxsts_data_t tx_status = {.d32 = 0 };
4344
4345                 tx_status.d32 =
4346                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
4347                 /** @todo Should there be check for room in the Tx
4348                  * Status Queue.  If not remove the code above this comment. */
4349
4350                 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
4351                 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
4352
4353                 /* Program the transfer size and packet count
4354                  *      as follows: xfersize = N * maxpacket +
4355                  *      short_packet pktcnt = N + (short_packet
4356                  *      exist ? 1 : 0) 
4357                  */
4358
4359                 if (core_if->dma_desc_enable == 0) {
4360                         deptsiz.b.xfersize =
4361                             (ep->total_len - ep->xfer_count) >
4362                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
4363                                                              ep->xfer_count);
4364                         deptsiz.b.pktcnt = 1;
4365                         if (core_if->dma_enable == 0) {
4366                                 ep->xfer_len += deptsiz.b.xfersize;
4367                         } else {
4368                                 ep->xfer_len = deptsiz.b.xfersize;
4369                         }
4370                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
4371                 } else {
4372                         ep->xfer_len =
4373                             (ep->total_len - ep->xfer_count) >
4374                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
4375                                                              ep->xfer_count);
4376
4377                         dma_desc = core_if->dev_if->in_desc_addr;
4378
4379                         /** DMA Descriptor Setup */
4380                         dma_desc->status.b.bs = BS_HOST_BUSY;
4381                         dma_desc->status.b.l = 1;
4382                         dma_desc->status.b.ioc = 1;
4383                         dma_desc->status.b.sp =
4384                             (ep->xfer_len == ep->maxpacket) ? 0 : 1;
4385                         dma_desc->status.b.bytes = ep->xfer_len;
4386                         dma_desc->buf = ep->dma_addr;
4387                         dma_desc->status.b.sts = 0;
4388                         dma_desc->status.b.bs = BS_HOST_READY;
4389
4390                         /** DIEPDMA0 Register write */
4391                         DWC_WRITE_REG32(&in_regs->diepdma,
4392                                         core_if->dev_if->dma_in_desc_addr);
4393                 }
4394
4395                 DWC_DEBUGPL(DBG_PCDV,
4396                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
4397                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4398                             deptsiz.d32);
4399
4400                 /* Write the DMA register */
4401                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4402                         if (core_if->dma_desc_enable == 0)
4403                                 DWC_WRITE_REG32(&(in_regs->diepdma),
4404                                                 (uint32_t) ep->dma_addr);
4405                 }
4406                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
4407                         depctl.b.nextep = core_if->nextep_seq[ep->num];
4408                 /* EP enable, IN data in FIFO */
4409                 depctl.b.cnak = 1;
4410                 depctl.b.epena = 1;
4411                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
4412
4413                 /**
4414                  * Enable the Non-Periodic Tx FIFO empty interrupt, the
4415                  * data will be written into the fifo by the ISR.
4416                  */
4417                 if (!core_if->dma_enable) {
4418                         if (core_if->en_multiple_tx_fifo == 0) {
4419                                 /* First clear it from GINTSTS */
4420                                 intr_mask.b.nptxfempty = 1;
4421                                 DWC_MODIFY_REG32(&core_if->
4422                                                  core_global_regs->gintmsk,
4423                                                  intr_mask.d32, intr_mask.d32);
4424
4425                         } else {
4426                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
4427                                 if (ep->xfer_len > 0) {
4428                                         uint32_t fifoemptymsk = 0;
4429                                         fifoemptymsk |= 1 << ep->num;
4430                                         DWC_MODIFY_REG32(&core_if->
4431                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
4432                                                          0, fifoemptymsk);
4433                                 }
4434                         }
4435                 }
4436         } else {
4437                 dwc_otg_dev_out_ep_regs_t *out_regs =
4438                     core_if->dev_if->out_ep_regs[0];
4439
4440                 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
4441                 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
4442
4443                 /* Program the transfer size and packet count
4444                  *      as follows: xfersize = N * maxpacket +
4445                  *      short_packet pktcnt = N + (short_packet
4446                  *      exist ? 1 : 0) 
4447                  */
4448                 deptsiz.b.xfersize = ep->maxpacket;
4449                 deptsiz.b.pktcnt = 1;
4450
4451                 if (core_if->dma_desc_enable == 0) {
4452                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
4453                 } else {
4454                         dma_desc = core_if->dev_if->out_desc_addr;
4455
4456                         /** DMA Descriptor Setup */
4457                         dma_desc->status.b.bs = BS_HOST_BUSY;
4458                         dma_desc->status.b.l = 1;
4459                         dma_desc->status.b.ioc = 1;
4460                         dma_desc->status.b.bytes = ep->maxpacket;
4461                         dma_desc->buf = ep->dma_addr;
4462                         dma_desc->status.b.sts = 0;
4463                         dma_desc->status.b.bs = BS_HOST_READY;
4464
4465                         /** DOEPDMA0 Register write */
4466                         DWC_WRITE_REG32(&out_regs->doepdma,
4467                                         core_if->dev_if->dma_out_desc_addr);
4468                 }
4469
4470                 DWC_DEBUGPL(DBG_PCDV,
4471                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
4472                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
4473                             deptsiz.d32);
4474
4475                 /* Write the DMA register */
4476                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
4477                         if (core_if->dma_desc_enable == 0)
4478                                 DWC_WRITE_REG32(&(out_regs->doepdma),
4479                                                 (uint32_t) ep->dma_addr);
4480
4481                 }
4482
4483                 /* EP enable, IN data in FIFO */
4484                 depctl.b.cnak = 1;
4485                 depctl.b.epena = 1;
4486                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
4487
4488         }
4489 }
4490
4491 #ifdef DEBUG
4492 void dump_msg(const u8 * buf, unsigned int length)
4493 {
4494         unsigned int start, num, i;
4495         char line[52], *p;
4496
4497         if (length >= 512)
4498                 return;
4499         start = 0;
4500         while (length > 0) {
4501                 num = length < 16u ? length : 16u;
4502                 p = line;
4503                 for (i = 0; i < num; ++i) {
4504                         if (i == 8)
4505                                 *p++ = ' ';
4506                         DWC_SPRINTF(p, " %02x", buf[i]);
4507                         p += 3;
4508                 }
4509                 *p = 0;
4510                 DWC_PRINTF("%6x: %s\n", start, line);
4511                 buf += num;
4512                 start += num;
4513                 length -= num;
4514         }
4515 }
4516 #else
4517 static inline void dump_msg(const u8 * buf, unsigned int length)
4518 {
4519 }
4520 #endif
4521
4522 /**
4523  * This function writes a packet into the Tx FIFO associated with the
4524  * EP. For non-periodic EPs the non-periodic Tx FIFO is written.  For
4525  * periodic EPs the periodic Tx FIFO associated with the EP is written
4526  * with all packets for the next micro-frame.
4527  *
4528  * @param core_if Programming view of DWC_otg controller.
4529  * @param ep The EP to write packet for.
4530  * @param dma Indicates if DMA is being used.
4531  */
4532 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
4533                              int dma)
4534 {
4535         /**
4536          * The buffer is padded to DWORD on a per packet basis in
4537          * slave/dma mode if the MPS is not DWORD aligned. The last
4538          * packet, if short, is also padded to a multiple of DWORD.
4539          *
4540          * ep->xfer_buff always starts DWORD aligned in memory and is a
4541          * multiple of DWORD in length
4542          *
4543          * ep->xfer_len can be any number of bytes
4544          *
4545          * ep->xfer_count is a multiple of ep->maxpacket until the last
4546          *      packet
4547          *
4548          * FIFO access is DWORD */
4549
4550         uint32_t i;
4551         uint32_t byte_count;
4552         uint32_t dword_count;
4553         uint32_t *fifo;
4554         uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
4555
4556         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
4557                     ep);
4558         if (ep->xfer_count >= ep->xfer_len) {
4559                 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
4560                 return;
4561         }
4562
4563         /* Find the byte length of the packet either short packet or MPS */
4564         if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
4565                 byte_count = ep->xfer_len - ep->xfer_count;
4566         } else {
4567                 byte_count = ep->maxpacket;
4568         }
4569
4570         /* Find the DWORD length, padded by extra bytes as neccessary if MPS
4571          * is not a multiple of DWORD */
4572         dword_count = (byte_count + 3) / 4;
4573
4574 #ifdef VERBOSE
4575         dump_msg(ep->xfer_buff, byte_count);
4576 #endif
4577
4578         /**@todo NGS Where are the Periodic Tx FIFO addresses
4579          * intialized?  What should this be? */
4580
4581         fifo = core_if->data_fifo[ep->num];
4582
4583         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
4584                     fifo, data_buff, *data_buff, byte_count);
4585
4586         if (!dma) {
4587                 for (i = 0; i < dword_count; i++, data_buff++) {
4588                         DWC_WRITE_REG32(fifo, *data_buff);
4589                 }
4590         }
4591
4592         ep->xfer_count += byte_count;
4593         ep->xfer_buff += byte_count;
4594         ep->dma_addr += byte_count;
4595 }
4596
4597 /**
4598  * Set the EP STALL.
4599  *
4600  * @param core_if Programming view of DWC_otg controller.
4601  * @param ep The EP to set the stall on.
4602  */
4603 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4604 {
4605         depctl_data_t depctl;
4606         volatile uint32_t *depctl_addr;
4607
4608         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4609                     (ep->is_in ? "IN" : "OUT"));
4610
4611         if (ep->is_in == 1) {
4612                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4613                 depctl.d32 = DWC_READ_REG32(depctl_addr);
4614
4615                 /* set the disable and stall bits */
4616                 if (depctl.b.epena) {
4617                         depctl.b.epdis = 1;
4618                 }
4619                 depctl.b.stall = 1;
4620                 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4621         } else {
4622                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4623                 depctl.d32 = DWC_READ_REG32(depctl_addr);
4624
4625                 /* set the stall bit */
4626                 depctl.b.stall = 1;
4627                 DWC_WRITE_REG32(depctl_addr, depctl.d32);
4628         }
4629
4630         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4631
4632         return;
4633 }
4634
4635 /**
4636  * Clear the EP STALL.
4637  *
4638  * @param core_if Programming view of DWC_otg controller.
4639  * @param ep The EP to clear stall from.
4640  */
4641 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
4642 {
4643         depctl_data_t depctl;
4644         volatile uint32_t *depctl_addr;
4645
4646         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
4647                     (ep->is_in ? "IN" : "OUT"));
4648
4649         if (ep->is_in == 1) {
4650                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
4651         } else {
4652                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
4653         }
4654
4655         depctl.d32 = DWC_READ_REG32(depctl_addr);
4656
4657         /* clear the stall bits */
4658         depctl.b.stall = 0;
4659
4660         /*
4661          * USB Spec 9.4.5: For endpoints using data toggle, regardless
4662          * of whether an endpoint has the Halt feature set, a
4663          * ClearFeature(ENDPOINT_HALT) request always results in the
4664          * data toggle being reinitialized to DATA0.
4665          */
4666         if (ep->type == DWC_OTG_EP_TYPE_INTR ||
4667             ep->type == DWC_OTG_EP_TYPE_BULK) {
4668                 depctl.b.setd0pid = 1;  /* DATA0 */
4669         }
4670
4671         DWC_WRITE_REG32(depctl_addr, depctl.d32);
4672         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
4673         return;
4674 }
4675
4676 /**
4677  * This function reads a packet from the Rx FIFO into the destination
4678  * buffer. To read SETUP data use dwc_otg_read_setup_packet.
4679  *
4680  * @param core_if Programming view of DWC_otg controller.
4681  * @param dest    Destination buffer for the packet.
4682  * @param bytes  Number of bytes to copy to the destination.
4683  */
4684 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
4685                          uint8_t * dest, uint16_t bytes)
4686 {
4687         int i;
4688         int word_count = (bytes + 3) / 4;
4689
4690         volatile uint32_t *fifo = core_if->data_fifo[0];
4691         uint32_t *data_buff = (uint32_t *) dest;
4692
4693         /**
4694          * @todo Account for the case where _dest is not dword aligned. This
4695          * requires reading data from the FIFO into a uint32_t temp buffer,
4696          * then moving it into the data buffer.
4697          */
4698
4699         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
4700                     core_if, dest, bytes);
4701
4702         for (i = 0; i < word_count; i++, data_buff++) {
4703                 *data_buff = DWC_READ_REG32(fifo);
4704         }
4705
4706         return;
4707 }
4708
4709 /**
4710  * This functions reads the device registers and prints them
4711  *
4712  * @param core_if Programming view of DWC_otg controller.
4713  */
4714 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
4715 {
4716         int i;
4717         volatile uint32_t *addr;
4718         uint32_t hwcfg1;
4719
4720         hwcfg1 = ~core_if->core_global_regs->ghwcfg1;
4721
4722         DWC_PRINTF("Device Global Registers\n");
4723         addr = &core_if->dev_if->dev_global_regs->dcfg;
4724         DWC_PRINTF("DCFG                 @0x%08lX : 0x%08X\n",
4725                    (unsigned long)addr, DWC_READ_REG32(addr));
4726         addr = &core_if->dev_if->dev_global_regs->dctl;
4727         DWC_PRINTF("DCTL                 @0x%08lX : 0x%08X\n",
4728                    (unsigned long)addr, DWC_READ_REG32(addr));
4729         addr = &core_if->dev_if->dev_global_regs->dsts;
4730         DWC_PRINTF("DSTS                 @0x%08lX : 0x%08X\n",
4731                    (unsigned long)addr, DWC_READ_REG32(addr));
4732         addr = &core_if->dev_if->dev_global_regs->diepmsk;
4733         DWC_PRINTF("DIEPMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4734                    DWC_READ_REG32(addr));
4735         addr = &core_if->dev_if->dev_global_regs->doepmsk;
4736         DWC_PRINTF("DOEPMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4737                    DWC_READ_REG32(addr));
4738         addr = &core_if->dev_if->dev_global_regs->daint;
4739         DWC_PRINTF("DAINT        @0x%08lX : 0x%08X\n", (unsigned long)addr,
4740                    DWC_READ_REG32(addr));
4741         addr = &core_if->dev_if->dev_global_regs->daintmsk;
4742         DWC_PRINTF("DAINTMSK     @0x%08lX : 0x%08X\n", (unsigned long)addr,
4743                    DWC_READ_REG32(addr));
4744         addr = &core_if->dev_if->dev_global_regs->dtknqr1;
4745         DWC_PRINTF("DTKNQR1      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4746                    DWC_READ_REG32(addr));
4747         if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
4748                 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
4749                 DWC_PRINTF("DTKNQR2      @0x%08lX : 0x%08X\n",
4750                            (unsigned long)addr, DWC_READ_REG32(addr));
4751         }
4752
4753         addr = &core_if->dev_if->dev_global_regs->dvbusdis;
4754         DWC_PRINTF("DVBUSID      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4755                    DWC_READ_REG32(addr));
4756
4757         addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
4758         DWC_PRINTF("DVBUSPULSE  @0x%08lX : 0x%08X\n",
4759                    (unsigned long)addr, DWC_READ_REG32(addr));
4760
4761         addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
4762         DWC_PRINTF("DTKNQR3_DTHRCTL      @0x%08lX : 0x%08X\n",
4763                    (unsigned long)addr, DWC_READ_REG32(addr));
4764
4765         if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
4766                 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4767                 DWC_PRINTF("DTKNQR4      @0x%08lX : 0x%08X\n",
4768                            (unsigned long)addr, DWC_READ_REG32(addr));
4769         }
4770
4771         addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
4772         DWC_PRINTF("FIFOEMPMSK   @0x%08lX : 0x%08X\n", (unsigned long)addr,
4773                    DWC_READ_REG32(addr));
4774
4775         if (core_if->hwcfg2.b.multi_proc_int) {
4776
4777                 addr = &core_if->dev_if->dev_global_regs->deachint;
4778                 DWC_PRINTF("DEACHINT     @0x%08lX : 0x%08X\n",
4779                            (unsigned long)addr, DWC_READ_REG32(addr));
4780                 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
4781                 DWC_PRINTF("DEACHINTMSK  @0x%08lX : 0x%08X\n",
4782                            (unsigned long)addr, DWC_READ_REG32(addr));
4783
4784                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
4785                         addr =
4786                             &core_if->dev_if->
4787                             dev_global_regs->diepeachintmsk[i];
4788                         DWC_PRINTF("DIEPEACHINTMSK[%d]   @0x%08lX : 0x%08X\n",
4789                                    i, (unsigned long)addr,
4790                                    DWC_READ_REG32(addr));
4791                 }
4792
4793                 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
4794                         addr =
4795                             &core_if->dev_if->
4796                             dev_global_regs->doepeachintmsk[i];
4797                         DWC_PRINTF("DOEPEACHINTMSK[%d]   @0x%08lX : 0x%08X\n",
4798                                    i, (unsigned long)addr,
4799                                    DWC_READ_REG32(addr));
4800                 }
4801         }
4802
4803         for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
4804                 if(hwcfg1 & (2<<(i<<1))){
4805                         DWC_PRINTF("Device IN EP %d Registers\n", i);
4806                         addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
4807                         DWC_PRINTF("DIEPCTL      @0x%08lX : 0x%08X\n",
4808                                    (unsigned long)addr, DWC_READ_REG32(addr));
4809                         addr = &core_if->dev_if->in_ep_regs[i]->diepint;
4810                         DWC_PRINTF("DIEPINT      @0x%08lX : 0x%08X\n",
4811                                    (unsigned long)addr, DWC_READ_REG32(addr));
4812                         addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
4813                         DWC_PRINTF("DIETSIZ      @0x%08lX : 0x%08X\n",
4814                                    (unsigned long)addr, DWC_READ_REG32(addr));
4815                         addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
4816                         DWC_PRINTF("DIEPDMA      @0x%08lX : 0x%08X\n",
4817                                    (unsigned long)addr, DWC_READ_REG32(addr));
4818                         addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
4819                         DWC_PRINTF("DTXFSTS      @0x%08lX : 0x%08X\n",
4820                                    (unsigned long)addr, DWC_READ_REG32(addr));
4821                         addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
4822                         DWC_PRINTF("DIEPDMAB     @0x%08lX : 0x%08X\n",
4823                                    (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ );
4824                 }
4825         }
4826
4827         for (i = 0; i <= core_if->core_params->dev_endpoints; i++) {
4828                 if(hwcfg1 & (1<<(i<<1))){
4829                         DWC_PRINTF("Device OUT EP %d Registers\n", i);
4830                         addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
4831                         DWC_PRINTF("DOEPCTL      @0x%08lX : 0x%08X\n",
4832                                    (unsigned long)addr, DWC_READ_REG32(addr));
4833                         addr = &core_if->dev_if->out_ep_regs[i]->doepint;
4834                         DWC_PRINTF("DOEPINT      @0x%08lX : 0x%08X\n",
4835                                    (unsigned long)addr, DWC_READ_REG32(addr));
4836                         addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
4837                         DWC_PRINTF("DOETSIZ      @0x%08lX : 0x%08X\n",
4838                                    (unsigned long)addr, DWC_READ_REG32(addr));
4839                         addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
4840                         DWC_PRINTF("DOEPDMA      @0x%08lX : 0x%08X\n",
4841                                    (unsigned long)addr, DWC_READ_REG32(addr));
4842                         if (core_if->dma_enable) {      /* Don't access this register in SLAVE mode */
4843                                 addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
4844                                 DWC_PRINTF("DOEPDMAB     @0x%08lX : 0x%08X\n",
4845                                            (unsigned long)addr, DWC_READ_REG32(addr));
4846                         }
4847                 }
4848
4849         }
4850 }
4851
4852 /**
4853  * This functions reads the SPRAM and prints its content
4854  *
4855  * @param core_if Programming view of DWC_otg controller.
4856  */
4857 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
4858 {
4859         volatile uint8_t *addr, *start_addr, *end_addr;
4860
4861         DWC_PRINTF("SPRAM Data:\n");
4862         start_addr = (void *)core_if->core_global_regs;
4863         DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
4864         start_addr += 0x00028000;
4865         end_addr = (void *)core_if->core_global_regs;
4866         end_addr += 0x000280e0;
4867
4868         for (addr = start_addr; addr < end_addr; addr += 16) {
4869                 DWC_PRINTF
4870                     ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
4871                      (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
4872                      addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
4873                      addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
4874                     );
4875         }
4876
4877         return;
4878 }
4879
4880 /**
4881  * This function reads the host registers and prints them
4882  *
4883  * @param core_if Programming view of DWC_otg controller.
4884  */
4885 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
4886 {
4887         int i;
4888         volatile uint32_t *addr;
4889
4890         DWC_PRINTF("Host Global Registers\n");
4891         addr = &core_if->host_if->host_global_regs->hcfg;
4892         DWC_PRINTF("HCFG                 @0x%08lX : 0x%08X\n",
4893                    (unsigned long)addr, DWC_READ_REG32(addr));
4894         addr = &core_if->host_if->host_global_regs->hfir;
4895         DWC_PRINTF("HFIR                 @0x%08lX : 0x%08X\n",
4896                    (unsigned long)addr, DWC_READ_REG32(addr));
4897         addr = &core_if->host_if->host_global_regs->hfnum;
4898         DWC_PRINTF("HFNUM        @0x%08lX : 0x%08X\n", (unsigned long)addr,
4899                    DWC_READ_REG32(addr));
4900         addr = &core_if->host_if->host_global_regs->hptxsts;
4901         DWC_PRINTF("HPTXSTS      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4902                    DWC_READ_REG32(addr));
4903         addr = &core_if->host_if->host_global_regs->haint;
4904         DWC_PRINTF("HAINT        @0x%08lX : 0x%08X\n", (unsigned long)addr,
4905                    DWC_READ_REG32(addr));
4906         addr = &core_if->host_if->host_global_regs->haintmsk;
4907         DWC_PRINTF("HAINTMSK     @0x%08lX : 0x%08X\n", (unsigned long)addr,
4908                    DWC_READ_REG32(addr));
4909         if (core_if->dma_desc_enable) {
4910                 addr = &core_if->host_if->host_global_regs->hflbaddr;
4911                 DWC_PRINTF("HFLBADDR     @0x%08lX : 0x%08X\n",
4912                            (unsigned long)addr, DWC_READ_REG32(addr));
4913         }
4914
4915         addr = core_if->host_if->hprt0;
4916         DWC_PRINTF("HPRT0        @0x%08lX : 0x%08X\n", (unsigned long)addr,
4917                    DWC_READ_REG32(addr));
4918
4919         for (i = 0; i < core_if->core_params->host_channels; i++) {
4920                 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
4921                 addr = &core_if->host_if->hc_regs[i]->hcchar;
4922                 DWC_PRINTF("HCCHAR       @0x%08lX : 0x%08X\n",
4923                            (unsigned long)addr, DWC_READ_REG32(addr));
4924                 addr = &core_if->host_if->hc_regs[i]->hcsplt;
4925                 DWC_PRINTF("HCSPLT       @0x%08lX : 0x%08X\n",
4926                            (unsigned long)addr, DWC_READ_REG32(addr));
4927                 addr = &core_if->host_if->hc_regs[i]->hcint;
4928                 DWC_PRINTF("HCINT        @0x%08lX : 0x%08X\n",
4929                            (unsigned long)addr, DWC_READ_REG32(addr));
4930                 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
4931                 DWC_PRINTF("HCINTMSK     @0x%08lX : 0x%08X\n",
4932                            (unsigned long)addr, DWC_READ_REG32(addr));
4933                 addr = &core_if->host_if->hc_regs[i]->hctsiz;
4934                 DWC_PRINTF("HCTSIZ       @0x%08lX : 0x%08X\n",
4935                            (unsigned long)addr, DWC_READ_REG32(addr));
4936                 addr = &core_if->host_if->hc_regs[i]->hcdma;
4937                 DWC_PRINTF("HCDMA        @0x%08lX : 0x%08X\n",
4938                            (unsigned long)addr, DWC_READ_REG32(addr));
4939                 if (core_if->dma_desc_enable) {
4940                         addr = &core_if->host_if->hc_regs[i]->hcdmab;
4941                         DWC_PRINTF("HCDMAB       @0x%08lX : 0x%08X\n",
4942                                    (unsigned long)addr, DWC_READ_REG32(addr));
4943                 }
4944
4945         }
4946         return;
4947 }
4948
4949 /**
4950  * This function reads the core global registers and prints them
4951  *
4952  * @param core_if Programming view of DWC_otg controller.
4953  */
4954 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
4955 {
4956         int i, ep_num;
4957         volatile uint32_t *addr;
4958         char *txfsiz;
4959
4960         DWC_PRINTF("Core Global Registers\n");
4961         addr = &core_if->core_global_regs->gotgctl;
4962         DWC_PRINTF("GOTGCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4963                    DWC_READ_REG32(addr));
4964         addr = &core_if->core_global_regs->gotgint;
4965         DWC_PRINTF("GOTGINT      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4966                    DWC_READ_REG32(addr));
4967         addr = &core_if->core_global_regs->gahbcfg;
4968         DWC_PRINTF("GAHBCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4969                    DWC_READ_REG32(addr));
4970         addr = &core_if->core_global_regs->gusbcfg;
4971         DWC_PRINTF("GUSBCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4972                    DWC_READ_REG32(addr));
4973         addr = &core_if->core_global_regs->grstctl;
4974         DWC_PRINTF("GRSTCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4975                    DWC_READ_REG32(addr));
4976         addr = &core_if->core_global_regs->gintsts;
4977         DWC_PRINTF("GINTSTS      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4978                    DWC_READ_REG32(addr));
4979         addr = &core_if->core_global_regs->gintmsk;
4980         DWC_PRINTF("GINTMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4981                    DWC_READ_REG32(addr));
4982         addr = &core_if->core_global_regs->grxstsr;
4983         DWC_PRINTF("GRXSTSR      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4984                    DWC_READ_REG32(addr));
4985         addr = &core_if->core_global_regs->grxfsiz;
4986         DWC_PRINTF("GRXFSIZ      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4987                    DWC_READ_REG32(addr));
4988         addr = &core_if->core_global_regs->gnptxfsiz;
4989         DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
4990                    DWC_READ_REG32(addr));
4991         addr = &core_if->core_global_regs->gnptxsts;
4992         DWC_PRINTF("GNPTXSTS     @0x%08lX : 0x%08X\n", (unsigned long)addr,
4993                    DWC_READ_REG32(addr));
4994         addr = &core_if->core_global_regs->gi2cctl;
4995         DWC_PRINTF("GI2CCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
4996                    DWC_READ_REG32(addr));
4997         addr = &core_if->core_global_regs->gpvndctl;
4998         DWC_PRINTF("GPVNDCTL     @0x%08lX : 0x%08X\n", (unsigned long)addr,
4999                    DWC_READ_REG32(addr));
5000         addr = &core_if->core_global_regs->ggpio;
5001         DWC_PRINTF("GGPIO        @0x%08lX : 0x%08X\n", (unsigned long)addr,
5002                    DWC_READ_REG32(addr));
5003         addr = &core_if->core_global_regs->guid;
5004         DWC_PRINTF("GUID                 @0x%08lX : 0x%08X\n",
5005                    (unsigned long)addr, DWC_READ_REG32(addr));
5006         addr = &core_if->core_global_regs->gsnpsid;
5007         DWC_PRINTF("GSNPSID      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5008                    DWC_READ_REG32(addr));
5009         addr = &core_if->core_global_regs->ghwcfg1;
5010         DWC_PRINTF("GHWCFG1      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5011                    DWC_READ_REG32(addr));
5012         addr = &core_if->core_global_regs->ghwcfg2;
5013         DWC_PRINTF("GHWCFG2      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5014                    DWC_READ_REG32(addr));
5015         addr = &core_if->core_global_regs->ghwcfg3;
5016         DWC_PRINTF("GHWCFG3      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5017                    DWC_READ_REG32(addr));
5018         addr = &core_if->core_global_regs->ghwcfg4;
5019         DWC_PRINTF("GHWCFG4      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5020                    DWC_READ_REG32(addr));
5021         addr = &core_if->core_global_regs->glpmcfg;
5022         DWC_PRINTF("GLPMCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5023                    DWC_READ_REG32(addr));
5024         addr = &core_if->core_global_regs->gpwrdn;
5025         DWC_PRINTF("GPWRDN       @0x%08lX : 0x%08X\n", (unsigned long)addr,
5026                    DWC_READ_REG32(addr));
5027         addr = &core_if->core_global_regs->gdfifocfg;
5028         DWC_PRINTF("GDFIFOCFG    @0x%08lX : 0x%08X\n", (unsigned long)addr,
5029                    DWC_READ_REG32(addr));
5030         addr = &core_if->core_global_regs->adpctl;
5031         DWC_PRINTF("ADPCTL       @0x%08lX : 0x%08X\n", (unsigned long)addr,
5032                    dwc_otg_adp_read_reg(core_if));
5033         addr = &core_if->core_global_regs->hptxfsiz;
5034         DWC_PRINTF("HPTXFSIZ     @0x%08lX : 0x%08X\n", (unsigned long)addr,
5035                    DWC_READ_REG32(addr));
5036
5037         if (core_if->en_multiple_tx_fifo == 0) {
5038                 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
5039                 txfsiz = "DPTXFSIZ";
5040         } else {
5041                 ep_num = core_if->hwcfg4.b.num_in_eps;
5042                 txfsiz = "DIENPTXF";
5043         }
5044         for (i = 0; i < ep_num; i++) {
5045                 addr = &core_if->core_global_regs->dtxfsiz[i];
5046                 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
5047                            (unsigned long)addr, DWC_READ_REG32(addr));
5048         }
5049         addr = core_if->pcgcctl;
5050         DWC_PRINTF("PCGCCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
5051                    DWC_READ_REG32(addr));
5052 }
5053
5054 /**
5055  * Flush a Tx FIFO.
5056  *
5057  * @param core_if Programming view of DWC_otg controller.
5058  * @param num Tx FIFO to flush.
5059  */
5060 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
5061 {
5062         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5063         volatile grstctl_t greset = {.d32 = 0 };
5064         int count = 0;
5065
5066         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
5067
5068         greset.b.txfflsh = 1;
5069         greset.b.txfnum = num;
5070         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5071
5072         do {
5073                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5074                 if (++count > 10000) {
5075                         DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
5076                                  __func__, greset.d32,
5077                                  DWC_READ_REG32(&global_regs->gnptxsts));
5078                         break;
5079                 }
5080                 dwc_udelay(1);
5081         } while (greset.b.txfflsh == 1);
5082
5083         /* Wait for 3 PHY Clocks */
5084         dwc_udelay(1);
5085 }
5086
5087 /**
5088  * Flush Rx FIFO.
5089  *
5090  * @param core_if Programming view of DWC_otg controller.
5091  */
5092 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
5093 {
5094         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5095         volatile grstctl_t greset = {.d32 = 0 };
5096         int count = 0;
5097
5098         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
5099         /*
5100          *
5101          */
5102         greset.b.rxfflsh = 1;
5103         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5104
5105         do {
5106                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5107                 if (++count > 10000) {
5108                         DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
5109                                  greset.d32);
5110                         break;
5111                 }
5112                 dwc_udelay(1);
5113         } while (greset.b.rxfflsh == 1);
5114
5115         /* Wait for 3 PHY Clocks */
5116         dwc_udelay(1);
5117 }
5118
5119 /**
5120  * Do core a soft reset of the core.  Be careful with this because it
5121  * resets all the internal state machines of the core.
5122  */
5123 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
5124 {
5125         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
5126         volatile grstctl_t greset = {.d32 = 0 };
5127         int count = 0;
5128
5129         DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
5130         /* Wait for AHB master IDLE state. */
5131         do {
5132                 dwc_udelay(10);
5133                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5134                 if (++count > 100000) {
5135                         DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
5136                                  greset.d32);
5137                         return;
5138                 }
5139         }
5140         while (greset.b.ahbidle == 0);
5141
5142         /* Core Soft Reset */
5143         count = 0;
5144         greset.b.csftrst = 1;
5145         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
5146         do {
5147                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
5148                 if (++count > 10000) {
5149                         DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
5150                                  __func__, greset.d32);
5151                         break;
5152                 }
5153                 dwc_udelay(1);
5154         }
5155         while (greset.b.csftrst == 1);
5156
5157         /* Wait for 3 PHY Clocks */
5158         dwc_mdelay(100);
5159
5160 }
5161
5162 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
5163 {
5164         return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
5165 }
5166
5167 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
5168 {
5169         return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
5170 }
5171
5172 /**
5173  * Register HCD callbacks. The callbacks are used to start and stop
5174  * the HCD for interrupt processing.
5175  *
5176  * @param core_if Programming view of DWC_otg controller.
5177  * @param cb the HCD callback structure.
5178  * @param p pointer to be passed to callback function (usb_hcd*).
5179  */
5180 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
5181                                         dwc_otg_cil_callbacks_t * cb, void *p)
5182 {
5183         core_if->hcd_cb = cb;
5184         //cb->p = p;
5185         core_if->hcd_cb_p = p;
5186 }
5187
5188 /**
5189  * Register PCD callbacks. The callbacks are used to start and stop
5190  * the PCD for interrupt processing.
5191  *
5192  * @param core_if Programming view of DWC_otg controller.
5193  * @param cb the PCD callback structure.
5194  * @param p pointer to be passed to callback function (pcd*).
5195  */
5196 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
5197                                         dwc_otg_cil_callbacks_t * cb, void *p)
5198 {
5199         core_if->pcd_cb = cb;
5200         cb->p = p;
5201 }
5202
5203 #ifdef DWC_EN_ISOC
5204
5205 /**
5206  * This function writes isoc data per 1 (micro)frame into tx fifo
5207  *
5208  * @param core_if Programming view of DWC_otg controller.
5209  * @param ep The EP to start the transfer on.
5210  *
5211  */
5212 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
5213 {
5214         dwc_otg_dev_in_ep_regs_t *ep_regs;
5215         dtxfsts_data_t txstatus = {.d32 = 0 };
5216         uint32_t len = 0;
5217         uint32_t dwords;
5218
5219         ep->xfer_len = ep->data_per_frame;
5220         ep->xfer_count = 0;
5221
5222         ep_regs = core_if->dev_if->in_ep_regs[ep->num];
5223
5224         len = ep->xfer_len - ep->xfer_count;
5225
5226         if (len > ep->maxpacket) {
5227                 len = ep->maxpacket;
5228         }
5229
5230         dwords = (len + 3) / 4;
5231
5232         /* While there is space in the queue and space in the FIFO and
5233          * More data to tranfer, Write packets to the Tx FIFO */
5234         txstatus.d32 =
5235             DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
5236         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
5237
5238         while (txstatus.b.txfspcavail > dwords &&
5239                ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
5240                 /* Write the FIFO */
5241                 dwc_otg_ep_write_packet(core_if, ep, 0);
5242
5243                 len = ep->xfer_len - ep->xfer_count;
5244                 if (len > ep->maxpacket) {
5245                         len = ep->maxpacket;
5246                 }
5247
5248                 dwords = (len + 3) / 4;
5249                 txstatus.d32 =
5250                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->
5251                                    dtxfsts);
5252                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
5253                             txstatus.d32);
5254         }
5255 }
5256
5257 /**
5258  * This function initializes a descriptor chain for Isochronous transfer
5259  *
5260  * @param core_if Programming view of DWC_otg controller.
5261  * @param ep The EP to start the transfer on.
5262  *
5263  */
5264 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
5265                                        dwc_ep_t * ep)
5266 {
5267         deptsiz_data_t deptsiz = {.d32 = 0 };
5268         depctl_data_t depctl = {.d32 = 0 };
5269         dsts_data_t dsts = {.d32 = 0 };
5270         volatile uint32_t *addr;
5271
5272         if (ep->is_in) {
5273                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
5274         } else {
5275                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
5276         }
5277
5278         ep->xfer_len = ep->data_per_frame;
5279         ep->xfer_count = 0;
5280         ep->xfer_buff = ep->cur_pkt_addr;
5281         ep->dma_addr = ep->cur_pkt_dma_addr;
5282
5283         if (ep->is_in) {
5284                 /* Program the transfer size and packet count
5285                  *      as follows: xfersize = N * maxpacket +
5286                  *      short_packet pktcnt = N + (short_packet
5287                  *      exist ? 1 : 0) 
5288                  */
5289                 deptsiz.b.xfersize = ep->xfer_len;
5290                 deptsiz.b.pktcnt =
5291                     (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
5292                 deptsiz.b.mc = deptsiz.b.pktcnt;
5293                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
5294                                 deptsiz.d32);
5295
5296                 /* Write the DMA register */
5297                 if (core_if->dma_enable) {
5298                         DWC_WRITE_REG32(&
5299                                         (core_if->dev_if->in_ep_regs[ep->num]->
5300                                          diepdma), (uint32_t) ep->dma_addr);
5301                 }
5302         } else {
5303                 deptsiz.b.pktcnt =
5304                     (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
5305                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
5306
5307                 DWC_WRITE_REG32(&core_if->dev_if->
5308                                 out_ep_regs[ep->num]->doeptsiz, deptsiz.d32);
5309
5310                 if (core_if->dma_enable) {
5311                         DWC_WRITE_REG32(&
5312                                         (core_if->dev_if->
5313                                          out_ep_regs[ep->num]->doepdma),
5314                                         (uint32_t) ep->dma_addr);
5315                 }
5316         }
5317
5318         /** Enable endpoint, clear nak  */
5319
5320         depctl.d32 = 0;
5321         if (ep->bInterval == 1) {
5322                 dsts.d32 =
5323                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
5324                 ep->next_frame = dsts.b.soffn + ep->bInterval;
5325
5326                 if (ep->next_frame & 0x1) {
5327                         depctl.b.setd1pid = 1;
5328                 } else {
5329                         depctl.b.setd0pid = 1;
5330                 }
5331         } else {
5332                 ep->next_frame += ep->bInterval;
5333
5334                 if (ep->next_frame & 0x1) {
5335                         depctl.b.setd1pid = 1;
5336                 } else {
5337                         depctl.b.setd0pid = 1;
5338                 }
5339         }
5340         depctl.b.epena = 1;
5341         depctl.b.cnak = 1;
5342
5343         DWC_MODIFY_REG32(addr, 0, depctl.d32);
5344         depctl.d32 = DWC_READ_REG32(addr);
5345
5346         if (ep->is_in && core_if->dma_enable == 0) {
5347                 write_isoc_frame_data(core_if, ep);
5348         }
5349
5350 }
5351 #endif /* DWC_EN_ISOC */
5352
5353 static void dwc_otg_set_uninitialized(int32_t * p, int size)
5354 {
5355         int i;
5356         for (i = 0; i < size; i++) {
5357                 p[i] = -1;
5358         }
5359 }
5360
5361 static int dwc_otg_param_initialized(int32_t val)
5362 {
5363         return val != -1;
5364 }
5365
5366 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
5367 {
5368         int i;
5369         gintsts_data_t gintsts;
5370         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
5371
5372         core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
5373         if (!core_if->core_params) {
5374                 return -DWC_E_NO_MEMORY;
5375         }
5376         dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
5377                                   sizeof(*core_if->core_params) /
5378                                   sizeof(int32_t));
5379         DWC_PRINTF("Setting default values for core params\n");
5380         dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
5381         dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
5382         dwc_otg_set_param_dma_desc_enable(core_if,
5383                                           dwc_param_dma_desc_enable_default);
5384         dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
5385         dwc_otg_set_param_dma_burst_size(core_if,
5386                                          dwc_param_dma_burst_size_default);
5387         dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
5388                                                        dwc_param_host_support_fs_ls_low_power_default);
5389         dwc_otg_set_param_enable_dynamic_fifo(core_if,
5390                                               dwc_param_enable_dynamic_fifo_default);
5391         dwc_otg_set_param_data_fifo_size(core_if,
5392                                          dwc_param_data_fifo_size_default);
5393         dwc_otg_set_param_dev_rx_fifo_size(core_if,
5394                                            dwc_param_dev_rx_fifo_size_default);
5395         dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
5396                                                   dwc_param_dev_nperio_tx_fifo_size_default);
5397         dwc_otg_set_param_host_rx_fifo_size(core_if,
5398                                             dwc_param_host_rx_fifo_size_default);
5399         dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
5400                                                    dwc_param_host_nperio_tx_fifo_size_default);
5401         dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
5402                                                   dwc_param_host_perio_tx_fifo_size_default);
5403         dwc_otg_set_param_max_transfer_size(core_if,
5404                                             dwc_param_max_transfer_size_default);
5405         dwc_otg_set_param_max_packet_count(core_if,
5406                                            dwc_param_max_packet_count_default);
5407         dwc_otg_set_param_host_channels(core_if,
5408                                         dwc_param_host_channels_default);
5409         dwc_otg_set_param_dev_endpoints(core_if,
5410                                         dwc_param_dev_endpoints_default);
5411         dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
5412         dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
5413         dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
5414                                                     dwc_param_host_ls_low_power_phy_clk_default);
5415         dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
5416         dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
5417                                             dwc_param_phy_ulpi_ext_vbus_default);
5418         dwc_otg_set_param_phy_utmi_width(core_if,
5419                                          dwc_param_phy_utmi_width_default);
5420         dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
5421         dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
5422         dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
5423         dwc_otg_set_param_en_multiple_tx_fifo(core_if,
5424                                               dwc_param_en_multiple_tx_fifo_default);
5425         
5426         if (gintsts.b.curmode) {
5427                 /* Force device mode to get power-on values of device FIFOs */
5428                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
5429                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5430                 gusbcfg.b.force_dev_mode = 1;
5431                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5432                 dwc_mdelay(100);
5433                 for (i = 0; i < 15; i++) {
5434                 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5435                                                          dwc_param_dev_perio_tx_fifo_size_default, i);
5436                 }
5437                 for (i = 0; i < 15; i++) {
5438                         dwc_otg_set_param_dev_tx_fifo_size(core_if,
5439                                                            dwc_param_dev_tx_fifo_size_default, i);
5440                 }
5441                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
5442                 gusbcfg.b.force_dev_mode = 0;
5443                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
5444                 dwc_mdelay(100);
5445         } else {
5446                 for (i = 0; i < 15; i++) {
5447                         dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
5448                                 dwc_param_dev_perio_tx_fifo_size_default, i);
5449                 }
5450                 for (i = 0; i < 15; i++) {
5451                         dwc_otg_set_param_dev_tx_fifo_size(core_if,
5452                                 dwc_param_dev_tx_fifo_size_default, i);
5453                 }
5454         }
5455
5456         dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
5457         dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
5458         dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
5459         dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
5460                 
5461         dwc_otg_set_param_besl_enable(core_if, dwc_param_besl_enable_default);
5462         dwc_otg_set_param_baseline_besl(core_if, dwc_param_baseline_besl_default);
5463         dwc_otg_set_param_deep_besl(core_if, dwc_param_deep_besl_default);
5464         
5465         dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
5466         dwc_otg_set_param_tx_thr_length(core_if,
5467                                         dwc_param_tx_thr_length_default);
5468         dwc_otg_set_param_rx_thr_length(core_if,
5469                                         dwc_param_rx_thr_length_default);
5470         dwc_otg_set_param_ahb_thr_ratio(core_if,
5471                                         dwc_param_ahb_thr_ratio_default);
5472         dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
5473         dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
5474         dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
5475         dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
5476         dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
5477         dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
5478         dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
5479         return 0;
5480 }
5481
5482 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
5483 {
5484         return core_if->dma_enable;
5485 }
5486
5487 /* Checks if the parameter is outside of its valid range of values */
5488 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
5489                 (((_param_) < (_low_)) || \
5490                 ((_param_) > (_high_)))
5491
5492 /* Parameter access functions */
5493 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
5494 {
5495         int valid;
5496         int retval = 0;
5497         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5498                 DWC_WARN("Wrong value for otg_cap parameter\n");
5499                 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
5500                 retval = -DWC_E_INVALID;
5501                 goto out;
5502         }
5503
5504         valid = 1;
5505         switch (val) {
5506         case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
5507                 if (core_if->hwcfg2.b.op_mode !=
5508                     DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5509                         valid = 0;
5510                 break;
5511         case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
5512                 if ((core_if->hwcfg2.b.op_mode !=
5513                      DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5514                     && (core_if->hwcfg2.b.op_mode !=
5515                         DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5516                     && (core_if->hwcfg2.b.op_mode !=
5517                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5518                     && (core_if->hwcfg2.b.op_mode !=
5519                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
5520                         valid = 0;
5521                 }
5522                 break;
5523         case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
5524                 /* always valid */
5525                 break;
5526         }
5527         if (!valid) {
5528                 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
5529                         DWC_ERROR
5530                             ("%d invalid for otg_cap paremter. Check HW configuration.\n",
5531                              val);
5532                 }
5533                 val =
5534                     (((core_if->hwcfg2.b.op_mode ==
5535                        DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
5536                       || (core_if->hwcfg2.b.op_mode ==
5537                           DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
5538                       || (core_if->hwcfg2.b.op_mode ==
5539                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
5540                       || (core_if->hwcfg2.b.op_mode ==
5541                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
5542                      DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
5543                      DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
5544                 retval = -DWC_E_INVALID;
5545         }
5546
5547         core_if->core_params->otg_cap = val;
5548 out:
5549         return retval;
5550 }
5551
5552 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
5553 {
5554         return core_if->core_params->otg_cap;
5555 }
5556
5557 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
5558 {
5559         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5560                 DWC_WARN("Wrong value for opt parameter\n");
5561                 return -DWC_E_INVALID;
5562         }
5563         core_if->core_params->opt = val;
5564         return 0;
5565 }
5566
5567 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
5568 {
5569         return core_if->core_params->opt;
5570 }
5571
5572 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
5573 {
5574         int retval = 0;
5575         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5576                 DWC_WARN("Wrong value for dma enable\n");
5577                 return -DWC_E_INVALID;
5578         }
5579
5580         if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
5581                 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
5582                         DWC_ERROR
5583                             ("%d invalid for dma_enable paremter. Check HW configuration.\n",
5584                              val);
5585                 }
5586                 val = 0;
5587                 retval = -DWC_E_INVALID;
5588         }
5589
5590         core_if->core_params->dma_enable = val;
5591         if (val == 0) {
5592                 dwc_otg_set_param_dma_desc_enable(core_if, 0);
5593         }
5594         return retval;
5595 }
5596
5597 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
5598 {
5599         return core_if->core_params->dma_enable;
5600 }
5601
5602 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
5603 {
5604         int retval = 0;
5605         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5606                 DWC_WARN("Wrong value for dma_enable\n");
5607                 DWC_WARN("dma_desc_enable must be 0 or 1\n");
5608                 return -DWC_E_INVALID;
5609         }
5610
5611         if ((val == 1)
5612             && ((dwc_otg_get_param_dma_enable(core_if) == 0)
5613                 || (core_if->hwcfg4.b.desc_dma == 0))) {
5614                 if (dwc_otg_param_initialized
5615                     (core_if->core_params->dma_desc_enable)) {
5616                         DWC_ERROR
5617                             ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
5618                              val);
5619                 }
5620                 val = 0;
5621                 retval = -DWC_E_INVALID;
5622         }
5623         core_if->core_params->dma_desc_enable = val;
5624         return retval;
5625 }
5626
5627 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
5628 {
5629         return core_if->core_params->dma_desc_enable;
5630 }
5631
5632 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
5633                                                    int32_t val)
5634 {
5635         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5636                 DWC_WARN("Wrong value for host_support_fs_low_power\n");
5637                 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
5638                 return -DWC_E_INVALID;
5639         }
5640         core_if->core_params->host_support_fs_ls_low_power = val;
5641         return 0;
5642 }
5643
5644 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
5645                                                        core_if)
5646 {
5647         return core_if->core_params->host_support_fs_ls_low_power;
5648 }
5649
5650 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
5651                                           int32_t val)
5652 {
5653         int retval = 0;
5654         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
5655                 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
5656                 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
5657                 return -DWC_E_INVALID;
5658         }
5659
5660         if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
5661                 if (dwc_otg_param_initialized
5662                     (core_if->core_params->enable_dynamic_fifo)) {
5663                         DWC_ERROR
5664                             ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
5665                              val);
5666                 }
5667                 val = 0;
5668                 retval = -DWC_E_INVALID;
5669         }
5670         core_if->core_params->enable_dynamic_fifo = val;
5671         return retval;
5672 }
5673
5674 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
5675 {
5676         return core_if->core_params->enable_dynamic_fifo;
5677 }
5678
5679 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5680 {
5681         int retval = 0;
5682         if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
5683                 DWC_WARN("Wrong value for data_fifo_size\n");
5684                 DWC_WARN("data_fifo_size must be 32-32768\n");
5685                 return -DWC_E_INVALID;
5686         }
5687
5688         if (val > core_if->hwcfg3.b.dfifo_depth) {
5689                 if (dwc_otg_param_initialized
5690                     (core_if->core_params->data_fifo_size)) {
5691                         DWC_ERROR
5692                             ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
5693                              val);
5694                 }
5695                 val = core_if->hwcfg3.b.dfifo_depth;
5696                 retval = -DWC_E_INVALID;
5697         }
5698
5699         core_if->core_params->data_fifo_size = val;
5700         return retval;
5701 }
5702
5703 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
5704 {
5705         return core_if->core_params->data_fifo_size;
5706 }
5707
5708 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
5709 {
5710         int retval = 0;
5711         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5712                 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
5713                 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
5714                 return -DWC_E_INVALID;
5715         }
5716
5717         if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5718                 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
5719                 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
5720                 }
5721                 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5722                 retval = -DWC_E_INVALID;
5723         }
5724
5725         core_if->core_params->dev_rx_fifo_size = val;
5726         return retval;
5727 }
5728
5729 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
5730 {
5731         return core_if->core_params->dev_rx_fifo_size;
5732 }
5733
5734 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5735                                               int32_t val)
5736 {
5737         int retval = 0;
5738
5739         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5740                 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
5741                 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
5742                 return -DWC_E_INVALID;
5743         }
5744
5745         if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5746                 if (dwc_otg_param_initialized
5747                     (core_if->core_params->dev_nperio_tx_fifo_size)) {
5748                         DWC_ERROR
5749                             ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
5750                              val);
5751                 }
5752                 val =
5753                     (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5754                      16);
5755                 retval = -DWC_E_INVALID;
5756         }
5757
5758         core_if->core_params->dev_nperio_tx_fifo_size = val;
5759         return retval;
5760 }
5761
5762 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5763 {
5764         return core_if->core_params->dev_nperio_tx_fifo_size;
5765 }
5766
5767 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
5768                                         int32_t val)
5769 {
5770         int retval = 0;
5771
5772         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5773                 DWC_WARN("Wrong value for host_rx_fifo_size\n");
5774                 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
5775                 return -DWC_E_INVALID;
5776         }
5777
5778         if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
5779                 if (dwc_otg_param_initialized
5780                     (core_if->core_params->host_rx_fifo_size)) {
5781                         DWC_ERROR
5782                             ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
5783                              val);
5784                 }
5785                 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
5786                 retval = -DWC_E_INVALID;
5787         }
5788
5789         core_if->core_params->host_rx_fifo_size = val;
5790         return retval;
5791
5792 }
5793
5794 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
5795 {
5796         return core_if->core_params->host_rx_fifo_size;
5797 }
5798
5799 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5800                                                int32_t val)
5801 {
5802         int retval = 0;
5803
5804         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5805                 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
5806                 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
5807                 return -DWC_E_INVALID;
5808         }
5809
5810         if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
5811                 if (dwc_otg_param_initialized
5812                     (core_if->core_params->host_nperio_tx_fifo_size)) {
5813                         DWC_ERROR
5814                             ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
5815                              val);
5816                 }
5817                 val =
5818                     (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
5819                      16);
5820                 retval = -DWC_E_INVALID;
5821         }
5822
5823         core_if->core_params->host_nperio_tx_fifo_size = val;
5824         return retval;
5825 }
5826
5827 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5828 {
5829         return core_if->core_params->host_nperio_tx_fifo_size;
5830 }
5831
5832 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
5833                                               int32_t val)
5834 {
5835         int retval = 0;
5836         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
5837                 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
5838                 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
5839                 return -DWC_E_INVALID;
5840         }
5841
5842         if (val > ((core_if->hptxfsiz.d32) >> 16)) {
5843                 if (dwc_otg_param_initialized
5844                     (core_if->core_params->host_perio_tx_fifo_size)) {
5845                         DWC_ERROR
5846                             ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
5847                              val);
5848                 }
5849                 val = (core_if->hptxfsiz.d32) >> 16;
5850                 retval = -DWC_E_INVALID;
5851         }
5852
5853         core_if->core_params->host_perio_tx_fifo_size = val;
5854         return retval;
5855 }
5856
5857 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
5858 {
5859         return core_if->core_params->host_perio_tx_fifo_size;
5860 }
5861
5862 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
5863                                         int32_t val)
5864 {
5865         int retval = 0;
5866
5867         if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
5868                 DWC_WARN("Wrong value for max_transfer_size\n");
5869                 DWC_WARN("max_transfer_size must be 2047-524288\n");
5870                 return -DWC_E_INVALID;
5871         }
5872
5873         if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
5874                 if (dwc_otg_param_initialized
5875                     (core_if->core_params->max_transfer_size)) {
5876                         DWC_ERROR
5877                             ("%d invalid for max_transfer_size. Check HW configuration.\n",
5878                              val);
5879                 }
5880                 val =
5881                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
5882                      1);
5883                 retval = -DWC_E_INVALID;
5884         }
5885
5886         core_if->core_params->max_transfer_size = val;
5887         return retval;
5888 }
5889
5890 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
5891 {
5892         return core_if->core_params->max_transfer_size;
5893 }
5894
5895 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
5896 {
5897         int retval = 0;
5898
5899         if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
5900                 DWC_WARN("Wrong value for max_packet_count\n");
5901                 DWC_WARN("max_packet_count must be 15-511\n");
5902                 return -DWC_E_INVALID;
5903         }
5904
5905         if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
5906                 if (dwc_otg_param_initialized
5907                     (core_if->core_params->max_packet_count)) {
5908                         DWC_ERROR
5909                             ("%d invalid for max_packet_count. Check HW configuration.\n",
5910                              val);
5911                 }
5912                 val =
5913                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
5914                 retval = -DWC_E_INVALID;
5915         }
5916
5917         core_if->core_params->max_packet_count = val;
5918         return retval;
5919 }
5920
5921 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
5922 {
5923         return core_if->core_params->max_packet_count;
5924 }
5925
5926 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
5927 {
5928         int retval = 0;
5929
5930         if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
5931                 DWC_WARN("Wrong value for host_channels\n");
5932                 DWC_WARN("host_channels must be 1-16\n");
5933                 return -DWC_E_INVALID;
5934         }
5935
5936         if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
5937                 if (dwc_otg_param_initialized
5938                     (core_if->core_params->host_channels)) {
5939                         DWC_ERROR
5940                             ("%d invalid for host_channels. Check HW configurations.\n",
5941                              val);
5942                 }
5943                 val = (core_if->hwcfg2.b.num_host_chan + 1);
5944                 retval = -DWC_E_INVALID;
5945         }
5946
5947         core_if->core_params->host_channels = val;
5948         return retval;
5949 }
5950
5951 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
5952 {
5953         return core_if->core_params->host_channels;
5954 }
5955
5956 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
5957 {
5958         int retval = 0;
5959
5960         if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
5961                 DWC_WARN("Wrong value for dev_endpoints\n");
5962                 DWC_WARN("dev_endpoints must be 1-15\n");
5963                 return -DWC_E_INVALID;
5964         }
5965
5966         if (val > (core_if->hwcfg2.b.num_dev_ep)) {
5967                 if (dwc_otg_param_initialized
5968                     (core_if->core_params->dev_endpoints)) {
5969                         DWC_ERROR
5970                             ("%d invalid for dev_endpoints. Check HW configurations.\n",
5971                              val);
5972                 }
5973                 val = core_if->hwcfg2.b.num_dev_ep;
5974                 retval = -DWC_E_INVALID;
5975         }
5976
5977         core_if->core_params->dev_endpoints = val;
5978         return retval;
5979 }
5980
5981 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
5982 {
5983         return core_if->core_params->dev_endpoints;
5984 }
5985
5986 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
5987 {
5988         int retval = 0;
5989         int valid = 0;
5990
5991         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
5992                 DWC_WARN("Wrong value for phy_type\n");
5993                 DWC_WARN("phy_type must be 0,1 or 2\n");
5994                 return -DWC_E_INVALID;
5995         }
5996 #ifndef NO_FS_PHY_HW_CHECKS
5997         if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
5998             ((core_if->hwcfg2.b.hs_phy_type == 1) ||
5999              (core_if->hwcfg2.b.hs_phy_type == 3))) {
6000                 valid = 1;
6001         } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
6002                    ((core_if->hwcfg2.b.hs_phy_type == 2) ||
6003                     (core_if->hwcfg2.b.hs_phy_type == 3))) {
6004                 valid = 1;
6005         } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
6006                    (core_if->hwcfg2.b.fs_phy_type == 1)) {
6007                 valid = 1;
6008         }
6009         if (!valid) {
6010                 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
6011                         DWC_ERROR
6012                             ("%d invalid for phy_type. Check HW configurations.\n",
6013                              val);
6014                 }
6015                 if (core_if->hwcfg2.b.hs_phy_type) {
6016                         if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
6017                             (core_if->hwcfg2.b.hs_phy_type == 1)) {
6018                                 val = DWC_PHY_TYPE_PARAM_UTMI;
6019                         } else {
6020                                 val = DWC_PHY_TYPE_PARAM_ULPI;
6021                         }
6022                 }
6023                 retval = -DWC_E_INVALID;
6024         }
6025 #endif
6026         core_if->core_params->phy_type = val;
6027         return retval;
6028 }
6029
6030 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
6031 {
6032         return core_if->core_params->phy_type;
6033 }
6034
6035 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
6036 {
6037         int retval = 0;
6038         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6039                 DWC_WARN("Wrong value for speed parameter\n");
6040                 DWC_WARN("max_speed parameter must be 0 or 1\n");
6041                 return -DWC_E_INVALID;
6042         }
6043         if ((val == 0)
6044             && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
6045                 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
6046                         DWC_ERROR
6047                             ("%d invalid for speed paremter. Check HW configuration.\n",
6048                              val);
6049                 }
6050                 val =
6051                     (dwc_otg_get_param_phy_type(core_if) ==
6052                      DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
6053                 retval = -DWC_E_INVALID;
6054         }
6055         core_if->core_params->speed = val;
6056         return retval;
6057 }
6058
6059 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
6060 {
6061         return core_if->core_params->speed;
6062 }
6063
6064 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
6065                                                 int32_t val)
6066 {
6067         int retval = 0;
6068
6069         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6070                 DWC_WARN
6071                     ("Wrong value for host_ls_low_power_phy_clk parameter\n");
6072                 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
6073                 return -DWC_E_INVALID;
6074         }
6075
6076         if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
6077             && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
6078                 if (dwc_otg_param_initialized
6079                     (core_if->core_params->host_ls_low_power_phy_clk)) {
6080                         DWC_ERROR
6081                             ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
6082                              val);
6083                 }
6084                 val =
6085                     (dwc_otg_get_param_phy_type(core_if) ==
6086                      DWC_PHY_TYPE_PARAM_FS) ?
6087                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
6088                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
6089                 retval = -DWC_E_INVALID;
6090         }
6091
6092         core_if->core_params->host_ls_low_power_phy_clk = val;
6093         return retval;
6094 }
6095
6096 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
6097 {
6098         return core_if->core_params->host_ls_low_power_phy_clk;
6099 }
6100
6101 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
6102 {
6103         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6104                 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
6105                 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
6106                 return -DWC_E_INVALID;
6107         }
6108
6109         core_if->core_params->phy_ulpi_ddr = val;
6110         return 0;
6111 }
6112
6113 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
6114 {
6115         return core_if->core_params->phy_ulpi_ddr;
6116 }
6117
6118 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
6119                                         int32_t val)
6120 {
6121         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6122                 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
6123                 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
6124                 return -DWC_E_INVALID;
6125         }
6126
6127         core_if->core_params->phy_ulpi_ext_vbus = val;
6128         return 0;
6129 }
6130
6131 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
6132 {
6133         return core_if->core_params->phy_ulpi_ext_vbus;
6134 }
6135
6136 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
6137 {
6138         if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
6139                 DWC_WARN("Wrong valaue for phy_utmi_width\n");
6140                 DWC_WARN("phy_utmi_width must be 8 or 16\n");
6141                 return -DWC_E_INVALID;
6142         }
6143
6144         core_if->core_params->phy_utmi_width = val;
6145         return 0;
6146 }
6147
6148 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
6149 {
6150         return core_if->core_params->phy_utmi_width;
6151 }
6152
6153 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
6154 {
6155         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6156                 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
6157                 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
6158                 return -DWC_E_INVALID;
6159         }
6160
6161         core_if->core_params->ulpi_fs_ls = val;
6162         return 0;
6163 }
6164
6165 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
6166 {
6167         return core_if->core_params->ulpi_fs_ls;
6168 }
6169
6170 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
6171 {
6172         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6173                 DWC_WARN("Wrong valaue for ts_dline\n");
6174                 DWC_WARN("ts_dline must be 0 or 1\n");
6175                 return -DWC_E_INVALID;
6176         }
6177
6178         core_if->core_params->ts_dline = val;
6179         return 0;
6180 }
6181
6182 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
6183 {
6184         return core_if->core_params->ts_dline;
6185 }
6186
6187 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
6188 {
6189         int retval = 0;
6190         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6191                 DWC_WARN("Wrong valaue for i2c_enable\n");
6192                 DWC_WARN("i2c_enable must be 0 or 1\n");
6193                 return -DWC_E_INVALID;
6194         }
6195 #ifndef NO_FS_PHY_HW_CHECK
6196         if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
6197                 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
6198                         DWC_ERROR
6199                             ("%d invalid for i2c_enable. Check HW configuration.\n",
6200                              val);
6201                 }
6202                 val = 0;
6203                 retval = -DWC_E_INVALID;
6204         }
6205 #endif
6206
6207         core_if->core_params->i2c_enable = val;
6208         return retval;
6209 }
6210
6211 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
6212 {
6213         return core_if->core_params->i2c_enable;
6214 }
6215
6216 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6217                                              int32_t val, int fifo_num)
6218 {
6219         int retval = 0;
6220         gintsts_data_t gintsts;
6221         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6222
6223         if (core_if->hwcfg4.b.ded_fifo_en == 0){
6224                 if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
6225                         DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
6226                         DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
6227                         return -DWC_E_INVALID;
6228                 }
6229
6230                 if (val > (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16)) {
6231                         printk("%d   ",DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6232                         printk("val = %d fifo_num = %d\n",val,fifo_num);
6233                         DWC_WARN("Value is larger then power-on FIFO size\n");
6234                         if (dwc_otg_param_initialized
6235                            (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
6236                                 DWC_ERROR
6237                                 ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
6238                                 val, fifo_num);
6239                         }
6240                         val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]) >> 16);
6241                         retval = -DWC_E_INVALID;
6242                 }
6243
6244                 core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
6245         }
6246         return retval;
6247 }
6248
6249 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
6250                                                  int fifo_num)
6251 {
6252         return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
6253 }
6254
6255 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
6256                                           int32_t val)
6257 {
6258         int retval = 0;
6259         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6260                 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
6261                 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
6262                 return -DWC_E_INVALID;
6263         }
6264
6265         if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
6266                 if (dwc_otg_param_initialized
6267                     (core_if->core_params->en_multiple_tx_fifo)) {
6268                         DWC_ERROR
6269                             ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
6270                              val);
6271                 }
6272                 val = 0;
6273                 retval = -DWC_E_INVALID;
6274         }
6275
6276         core_if->core_params->en_multiple_tx_fifo = val;
6277         return retval;
6278 }
6279
6280 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
6281 {
6282         return core_if->core_params->en_multiple_tx_fifo;
6283 }
6284
6285 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
6286                                        int fifo_num)
6287 {
6288         int retval = 0;
6289         fifosize_data_t txfifosize;
6290         txfifosize.d32 = DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]); 
6291
6292         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
6293                 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
6294                 DWC_WARN("dev_tx_fifo_size must be 16-32768\n");
6295                 return -DWC_E_INVALID;
6296         }
6297
6298         core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
6299         return retval;
6300 }
6301
6302 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
6303                                            int fifo_num)
6304 {
6305         return core_if->core_params->dev_tx_fifo_size[fifo_num];
6306 }
6307
6308 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6309 {
6310         int retval = 0;
6311
6312         if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
6313                 DWC_WARN("Wrong value for thr_ctl\n");
6314                 DWC_WARN("thr_ctl must be 0-7\n");
6315                 return -DWC_E_INVALID;
6316         }
6317
6318         if ((val != 0) &&
6319             (!dwc_otg_get_param_dma_enable(core_if) ||
6320              !core_if->hwcfg4.b.ded_fifo_en)) {
6321                 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
6322                         DWC_ERROR
6323                             ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
6324                              val);
6325                 }
6326                 val = 0;
6327                 retval = -DWC_E_INVALID;
6328         }
6329
6330         core_if->core_params->thr_ctl = val;
6331         return retval;
6332 }
6333
6334 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
6335 {
6336         return core_if->core_params->thr_ctl;
6337 }
6338
6339 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
6340 {
6341         int retval = 0;
6342
6343         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6344                 DWC_WARN("Wrong value for lpm_enable\n");
6345                 DWC_WARN("lpm_enable must be 0 or 1\n");
6346                 return -DWC_E_INVALID;
6347         }
6348
6349         if (val && !core_if->hwcfg3.b.otg_lpm_en) {
6350                 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
6351                         DWC_ERROR
6352                             ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
6353                              val);
6354                 }
6355                 val = 0;
6356                 retval = -DWC_E_INVALID;
6357         }
6358
6359         core_if->core_params->lpm_enable = val;
6360         return retval;
6361 }
6362
6363 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
6364 {
6365         return core_if->core_params->lpm_enable;
6366 }
6367
6368 int dwc_otg_set_param_besl_enable(dwc_otg_core_if_t * core_if, int32_t val)
6369 {
6370         int retval = 0;
6371
6372         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6373                 DWC_WARN("Wrong value for besl_enable\n");
6374                 DWC_WARN("besl_enable must be 0 or 1\n");
6375                 return -DWC_E_INVALID;
6376         }
6377
6378         core_if->core_params->besl_enable = val;
6379         
6380         if(val)
6381         {
6382                 retval += dwc_otg_set_param_lpm_enable(core_if,val);
6383         }
6384         
6385         return retval;
6386 }
6387
6388 int32_t dwc_otg_get_param_besl_enable(dwc_otg_core_if_t * core_if)
6389 {
6390         return core_if->core_params->besl_enable;
6391 }
6392
6393 int dwc_otg_set_param_baseline_besl(dwc_otg_core_if_t * core_if, int32_t val)
6394 {
6395         int retval = 0;
6396                 
6397         if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6398                 DWC_WARN("Wrong value for baseline_besl\n");
6399                 DWC_WARN("baseline_besl must be 0-15\n");
6400                 return -DWC_E_INVALID;
6401         }
6402
6403         core_if->core_params->baseline_besl = val;
6404         return retval;
6405 }
6406
6407 int32_t dwc_otg_get_param_baseline_besl(dwc_otg_core_if_t * core_if)
6408 {
6409         return core_if->core_params->baseline_besl;
6410 }
6411
6412 int dwc_otg_set_param_deep_besl(dwc_otg_core_if_t * core_if, int32_t val)
6413 {
6414         int retval = 0;
6415
6416         if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
6417                 DWC_WARN("Wrong value for deep_besl\n");
6418                 DWC_WARN("deep_besl must be 0-15\n");
6419                 return -DWC_E_INVALID;
6420         }
6421
6422         core_if->core_params->deep_besl = val;
6423         return retval;
6424 }
6425
6426 int32_t dwc_otg_get_param_deep_besl(dwc_otg_core_if_t * core_if)
6427 {
6428         return core_if->core_params->deep_besl;
6429 }
6430
6431 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6432 {
6433         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6434                 DWC_WARN("Wrong valaue for tx_thr_length\n");
6435                 DWC_WARN("tx_thr_length must be 8 - 128\n");
6436                 return -DWC_E_INVALID;
6437         }
6438
6439         core_if->core_params->tx_thr_length = val;
6440         return 0;
6441 }
6442
6443 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
6444 {
6445         return core_if->core_params->tx_thr_length;
6446 }
6447
6448 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
6449 {
6450         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
6451                 DWC_WARN("Wrong valaue for rx_thr_length\n");
6452                 DWC_WARN("rx_thr_length must be 8 - 128\n");
6453                 return -DWC_E_INVALID;
6454         }
6455
6456         core_if->core_params->rx_thr_length = val;
6457         return 0;
6458 }
6459
6460 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
6461 {
6462         return core_if->core_params->rx_thr_length;
6463 }
6464
6465 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
6466 {
6467         if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
6468             DWC_OTG_PARAM_TEST(val, 4, 4) &&
6469             DWC_OTG_PARAM_TEST(val, 8, 8) &&
6470             DWC_OTG_PARAM_TEST(val, 16, 16) &&
6471             DWC_OTG_PARAM_TEST(val, 32, 32) &&
6472             DWC_OTG_PARAM_TEST(val, 64, 64) &&
6473             DWC_OTG_PARAM_TEST(val, 128, 128) &&
6474             DWC_OTG_PARAM_TEST(val, 256, 256)) {
6475                 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
6476                 return -DWC_E_INVALID;
6477         }
6478         core_if->core_params->dma_burst_size = val;
6479         return 0;
6480 }
6481
6482 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
6483 {
6484         return core_if->core_params->dma_burst_size;
6485 }
6486
6487 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
6488 {
6489         int retval = 0;
6490         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6491                 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
6492                 return -DWC_E_INVALID;
6493         }
6494         if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
6495                 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
6496                         DWC_ERROR
6497                             ("%d invalid for parameter pti_enable. Check HW configuration.\n",
6498                              val);
6499                 }
6500                 retval = -DWC_E_INVALID;
6501                 val = 0;
6502         }
6503         core_if->core_params->pti_enable = val;
6504         return retval;
6505 }
6506
6507 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
6508 {
6509         return core_if->core_params->pti_enable;
6510 }
6511
6512 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
6513 {
6514         int retval = 0;
6515         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6516                 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
6517                 return -DWC_E_INVALID;
6518         }
6519         if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
6520                 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
6521                         DWC_ERROR
6522                             ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
6523                              val);
6524                 }
6525                 retval = -DWC_E_INVALID;
6526                 val = 0;
6527         }
6528         core_if->core_params->mpi_enable = val;
6529         return retval;
6530 }
6531
6532 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
6533 {
6534         return core_if->core_params->mpi_enable;
6535 }
6536
6537 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
6538 {
6539         int retval = 0;
6540         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6541                 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
6542                 return -DWC_E_INVALID;
6543         }
6544         if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
6545                 if (dwc_otg_param_initialized
6546                     (core_if->core_params->adp_supp_enable)) {
6547                         DWC_ERROR
6548                             ("%d invalid for parameter adp_enable. Check HW configuration.\n",
6549                              val);
6550                 }
6551                 retval = -DWC_E_INVALID;
6552                 val = 0;
6553         }
6554         core_if->core_params->adp_supp_enable = val;
6555         /* Set OTG version 2.0 in case of enabling ADP */
6556         if (val)
6557                 dwc_otg_set_param_otg_ver(core_if, 1);
6558
6559         return retval;
6560 }
6561
6562 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
6563 {
6564         return core_if->core_params->adp_supp_enable;
6565 }
6566
6567 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
6568 {
6569         int retval = 0;
6570         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6571                 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
6572                 DWC_WARN("ic_usb_cap must be 0 or 1\n");
6573                 return -DWC_E_INVALID;
6574         }
6575
6576         if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
6577                 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
6578                         DWC_ERROR
6579                             ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
6580                              val);
6581                 }
6582                 retval = -DWC_E_INVALID;
6583                 val = 0;
6584         }
6585         core_if->core_params->ic_usb_cap = val;
6586         return retval;
6587 }
6588
6589 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
6590 {
6591         return core_if->core_params->ic_usb_cap;
6592 }
6593
6594 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
6595 {
6596         int retval = 0;
6597         int valid = 1;
6598
6599         if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6600                 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
6601                 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
6602                 return -DWC_E_INVALID;
6603         }
6604
6605         if (val
6606             && (core_if->snpsid < OTG_CORE_REV_2_81a
6607                 || !dwc_otg_get_param_thr_ctl(core_if))) {
6608                 valid = 0;
6609         } else if (val
6610                    && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
6611                        4)) {
6612                 valid = 0;
6613         }
6614         if (valid == 0) {
6615                 if (dwc_otg_param_initialized
6616                     (core_if->core_params->ahb_thr_ratio)) {
6617                         DWC_ERROR
6618                             ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
6619                              val);
6620                 }
6621                 retval = -DWC_E_INVALID;
6622                 val = 0;
6623         }
6624
6625         core_if->core_params->ahb_thr_ratio = val;
6626         return retval;
6627 }
6628
6629 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
6630 {
6631         return core_if->core_params->ahb_thr_ratio;
6632 }
6633
6634 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
6635 {
6636         int retval = 0;
6637         int valid = 1;
6638         hwcfg4_data_t hwcfg4 = {.d32 = 0 };
6639         hwcfg4.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
6640
6641         if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
6642                 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
6643                 DWC_WARN("power_down must be 0 - 2\n");
6644                 return -DWC_E_INVALID;
6645         }
6646
6647         if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
6648                 valid = 0;
6649         }
6650         if ((val == 3)
6651             && ((core_if->snpsid < OTG_CORE_REV_3_00a)
6652                 || (hwcfg4.b.xhiber == 0))) {
6653                 valid = 0;
6654         }
6655         if (valid == 0) {
6656                 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
6657                         DWC_ERROR
6658                             ("%d invalid for parameter power_down. Check HW configuration.\n",
6659                              val);
6660                 }
6661                 retval = -DWC_E_INVALID;
6662                 val = 0;
6663         }
6664         core_if->core_params->power_down = val;
6665         return retval;
6666 }
6667
6668 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
6669 {
6670         return core_if->core_params->power_down;
6671 }
6672
6673 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
6674 {
6675         int retval = 0;
6676         int valid = 1;
6677
6678         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6679                 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
6680                 DWC_WARN("reload_ctl must be 0 or 1\n");
6681                 return -DWC_E_INVALID;
6682         }
6683
6684         if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
6685                 valid = 0;
6686         }
6687         if (valid == 0) {
6688                 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
6689                         DWC_ERROR("%d invalid for parameter reload_ctl."
6690                                   "Check HW configuration.\n", val);
6691                 }
6692                 retval = -DWC_E_INVALID;
6693                 val = 0;
6694         }
6695         core_if->core_params->reload_ctl = val;
6696         return retval;
6697 }
6698
6699 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
6700 {
6701         return core_if->core_params->reload_ctl;
6702 }
6703
6704 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
6705 {
6706         int retval = 0;
6707         int valid = 1;
6708
6709         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6710                 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
6711                 DWC_WARN("dev_out_nak must be 0 or 1\n");
6712                 return -DWC_E_INVALID;
6713         }
6714
6715         if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
6716                            !(core_if->core_params->dma_desc_enable))) {
6717                 valid = 0;
6718         }
6719         if (valid == 0) {
6720                 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
6721                         DWC_ERROR("%d invalid for parameter dev_out_nak."
6722                                   "Check HW configuration.\n", val);
6723                 }
6724                 retval = -DWC_E_INVALID;
6725                 val = 0;
6726         }
6727         core_if->core_params->dev_out_nak = val;
6728         return retval;
6729 }
6730
6731 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
6732 {
6733         return core_if->core_params->dev_out_nak;
6734 }
6735
6736 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
6737 {
6738         int retval = 0;
6739         int valid = 1;
6740
6741         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6742                 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
6743                 DWC_WARN("cont_on_bna must be 0 or 1\n");
6744                 return -DWC_E_INVALID;
6745         }
6746
6747         if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
6748                            !(core_if->core_params->dma_desc_enable))) {
6749                 valid = 0;
6750         }
6751         if (valid == 0) {
6752                 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
6753                         DWC_ERROR("%d invalid for parameter cont_on_bna."
6754                                 "Check HW configuration.\n", val);
6755                 }
6756                 retval = -DWC_E_INVALID;
6757                 val = 0;
6758         }
6759         core_if->core_params->cont_on_bna = val;
6760         return retval;
6761 }
6762
6763 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
6764 {
6765         return core_if->core_params->cont_on_bna;
6766 }
6767
6768 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
6769 {
6770         int retval = 0;
6771         int valid = 1;
6772
6773         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6774                 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
6775                 DWC_WARN("ahb_single must be 0 or 1\n");
6776                 return -DWC_E_INVALID;
6777         }
6778
6779         if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
6780                 valid = 0;
6781         }
6782         if (valid == 0) {
6783                 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
6784                         DWC_ERROR("%d invalid for parameter ahb_single."
6785                                   "Check HW configuration.\n", val);
6786                 }
6787                 retval = -DWC_E_INVALID;
6788                 val = 0;
6789         }
6790         core_if->core_params->ahb_single = val;
6791         return retval;
6792 }
6793
6794 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
6795 {
6796         return core_if->core_params->ahb_single;
6797 }
6798
6799 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
6800 {
6801         int retval = 0;
6802
6803         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
6804                 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
6805                 DWC_WARN
6806                     ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
6807                 return -DWC_E_INVALID;
6808         }
6809
6810         core_if->core_params->otg_ver = val;
6811         return retval;
6812 }
6813
6814 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
6815 {
6816         return core_if->core_params->otg_ver;
6817 }
6818
6819 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
6820 {
6821         gotgctl_data_t otgctl;
6822         otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6823         return otgctl.b.hstnegscs;
6824 }
6825
6826 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
6827 {
6828         gotgctl_data_t otgctl;
6829         otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6830         return otgctl.b.sesreqscs;
6831 }
6832
6833 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
6834 {
6835         if(core_if->otg_ver == 0) {
6836                 gotgctl_data_t otgctl;
6837                 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
6838                 otgctl.b.hnpreq = val;
6839                 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
6840         } else {
6841                 core_if->otg_sts = val;
6842         }
6843 }
6844
6845 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
6846 {
6847         return core_if->snpsid;
6848 }
6849
6850 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
6851 {
6852         gintsts_data_t gintsts;
6853         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
6854         return gintsts.b.curmode;
6855 }
6856
6857 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
6858 {
6859         gusbcfg_data_t usbcfg;
6860         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6861         return usbcfg.b.hnpcap;
6862 }
6863
6864 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6865 {
6866         gusbcfg_data_t usbcfg;
6867         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6868         usbcfg.b.hnpcap = val;
6869         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6870 }
6871
6872 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
6873 {
6874         gusbcfg_data_t usbcfg;
6875         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6876         return usbcfg.b.srpcap;
6877 }
6878
6879 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
6880 {
6881         gusbcfg_data_t usbcfg;
6882         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
6883         usbcfg.b.srpcap = val;
6884         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
6885 }
6886
6887 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
6888 {
6889         dcfg_data_t dcfg;
6890         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6891         return dcfg.b.devspd;
6892 }
6893
6894 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
6895 {
6896         dcfg_data_t dcfg;
6897         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
6898         dcfg.b.devspd = val;
6899         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
6900 }
6901
6902 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
6903 {
6904         hprt0_data_t hprt0;
6905         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6906         return hprt0.b.prtconnsts;
6907 }
6908
6909 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
6910 {
6911         dsts_data_t dsts;
6912         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
6913         return dsts.b.enumspd;
6914 }
6915
6916 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
6917 {
6918         hprt0_data_t hprt0;
6919         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6920         return hprt0.b.prtpwr;
6921
6922 }
6923
6924 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
6925 {
6926         return core_if->hibernation_suspend;
6927 }
6928
6929 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
6930 {
6931         hprt0_data_t hprt0;
6932         hprt0.d32 = dwc_otg_read_hprt0(core_if);
6933         hprt0.b.prtpwr = val;
6934         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6935 }
6936
6937 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
6938 {
6939         hprt0_data_t hprt0;
6940         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
6941         return hprt0.b.prtsusp;
6942
6943 }
6944
6945 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
6946 {
6947         hprt0_data_t hprt0;
6948         hprt0.d32 = dwc_otg_read_hprt0(core_if);
6949         hprt0.b.prtsusp = val;
6950         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
6951 }
6952
6953 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
6954 {
6955         hfir_data_t hfir;
6956         hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6957         return hfir.b.frint;
6958
6959 }
6960
6961 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
6962 {
6963         hfir_data_t hfir;
6964         uint32_t fram_int;
6965         fram_int = calc_frame_interval(core_if);
6966         hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
6967         if (!core_if->core_params->reload_ctl) {
6968                 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
6969                          "not set to 1.\nShould load driver with reload_ctl=1"
6970                          " module parameter\n");
6971                 return;
6972         }
6973         switch (fram_int) {
6974         case 3750:
6975                 if ((val < 3350) || (val > 4150)) {
6976                         DWC_WARN("HFIR interval for HS core and 30 MHz"
6977                                  "clock freq should be from 3350 to 4150\n");
6978                         return;
6979                 }
6980                 break;
6981         case 30000:
6982                 if ((val < 26820) || (val > 33180)) {
6983                         DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
6984                                  "clock freq should be from 26820 to 33180\n");
6985                         return;
6986                 }
6987                 break;
6988         case 6000:
6989                 if ((val < 5360) || (val > 6640)) {
6990                         DWC_WARN("HFIR interval for HS core and 48 MHz"
6991                                  "clock freq should be from 5360 to 6640\n");
6992                         return;
6993                 }
6994                 break;
6995         case 48000:
6996                 if ((val < 42912) || (val > 53088)) {
6997                         DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
6998                                  "clock freq should be from 42912 to 53088\n");
6999                         return;
7000                 }
7001                 break;
7002         case 7500:
7003                 if ((val < 6700) || (val > 8300)) {
7004                         DWC_WARN("HFIR interval for HS core and 60 MHz"
7005                                  "clock freq should be from 6700 to 8300\n");
7006                         return;
7007                 }
7008                 break;
7009         case 60000:
7010                 if ((val < 53640) || (val > 65536)) {
7011                         DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
7012                                  "clock freq should be from 53640 to 65536\n");
7013                         return;
7014                 }
7015                 break;
7016         default:
7017                 DWC_WARN("Unknown frame interval\n");
7018                 return;
7019                 break;
7020
7021         }
7022         hfir.b.frint = val;
7023         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
7024 }
7025
7026 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
7027 {
7028         hcfg_data_t hcfg;
7029         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7030         return hcfg.b.modechtimen;
7031
7032 }
7033
7034 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
7035 {
7036         hcfg_data_t hcfg;
7037         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
7038         hcfg.b.modechtimen = val;
7039         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
7040 }
7041
7042 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
7043 {
7044         hprt0_data_t hprt0;
7045         hprt0.d32 = dwc_otg_read_hprt0(core_if);
7046         hprt0.b.prtres = val;
7047         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
7048 }
7049
7050 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
7051 {
7052         dctl_data_t dctl;
7053         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7054         return dctl.b.rmtwkupsig;
7055 }
7056
7057 uint32_t dwc_otg_get_beslreject(dwc_otg_core_if_t * core_if)
7058 {
7059         dctl_data_t dctl;
7060         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7061         return dctl.b.besl_reject;
7062 }
7063
7064 void dwc_otg_set_beslreject(dwc_otg_core_if_t * core_if, uint32_t val)
7065 {
7066     dctl_data_t dctl;
7067         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
7068         dctl.b.besl_reject = val;
7069         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
7070 }
7071 uint32_t dwc_otg_get_hirdthresh(dwc_otg_core_if_t * core_if)
7072 {
7073         glpmcfg_data_t lpmcfg;
7074         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7075         return lpmcfg.b.hird_thres;
7076 }
7077
7078 void dwc_otg_set_hirdthresh(dwc_otg_core_if_t * core_if, uint32_t val)
7079 {
7080         glpmcfg_data_t lpmcfg;
7081         
7082         if (DWC_OTG_PARAM_TEST(val, 0, 15)) {
7083                 DWC_WARN("Wrong valaue for hird_thres\n");
7084                 DWC_WARN("hird_thres must be 0-f\n");
7085                 return ;
7086         }
7087         
7088         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7089         lpmcfg.b.hird_thres |= val;
7090         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7091 }
7092
7093 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
7094 {
7095         glpmcfg_data_t lpmcfg;
7096         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7097
7098         DWC_ASSERT(!
7099                    ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
7100                    "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
7101                    core_if->lx_state, lpmcfg.b.prt_sleep_sts);
7102
7103         return lpmcfg.b.prt_sleep_sts;
7104 }
7105
7106 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
7107 {
7108         glpmcfg_data_t lpmcfg;
7109         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7110         return lpmcfg.b.rem_wkup_en;
7111 }
7112
7113 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
7114 {
7115         glpmcfg_data_t lpmcfg;
7116         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7117         return lpmcfg.b.appl_resp;
7118 }
7119
7120 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
7121 {
7122         glpmcfg_data_t lpmcfg;
7123         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7124         lpmcfg.b.appl_resp = val;
7125         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7126 }
7127
7128 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
7129 {
7130         glpmcfg_data_t lpmcfg;
7131         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7132         return lpmcfg.b.hsic_connect;
7133 }
7134
7135 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
7136 {
7137         glpmcfg_data_t lpmcfg;
7138         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7139         lpmcfg.b.hsic_connect = val;
7140         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7141 }
7142
7143 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
7144 {
7145         glpmcfg_data_t lpmcfg;
7146         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7147         return lpmcfg.b.inv_sel_hsic;
7148
7149 }
7150
7151 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
7152 {
7153         glpmcfg_data_t lpmcfg;
7154         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
7155         lpmcfg.b.inv_sel_hsic = val;
7156         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
7157 }
7158
7159 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
7160 {
7161         return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
7162 }
7163
7164 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
7165 {
7166         DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
7167 }
7168
7169 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
7170 {
7171         return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
7172 }
7173
7174 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
7175 {
7176         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
7177 }
7178
7179 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
7180 {
7181         return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
7182 }
7183
7184 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7185 {
7186         DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
7187 }
7188
7189 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
7190 {
7191         return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
7192 }
7193
7194 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
7195 {
7196         DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
7197 }
7198
7199 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
7200 {
7201         return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
7202 }
7203
7204 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
7205 {
7206         DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
7207 }
7208
7209 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
7210 {
7211         return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
7212 }
7213
7214 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
7215 {
7216         DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
7217 }
7218
7219 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
7220 {
7221         return DWC_READ_REG32(core_if->host_if->hprt0);
7222
7223 }
7224
7225 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
7226 {
7227         DWC_WRITE_REG32(core_if->host_if->hprt0, val);
7228 }
7229
7230 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
7231 {
7232         return DWC_READ_REG32(&core_if->core_global_regs->guid);
7233 }
7234
7235 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
7236 {
7237         DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
7238 }
7239
7240 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
7241 {
7242         return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
7243 }
7244
7245 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
7246 {
7247         return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
7248 }
7249
7250 /**
7251  * Start the SRP timer to detect when the SRP does not complete within
7252  * 6 seconds.
7253  *
7254  * @param core_if the pointer to core_if strucure.
7255  */
7256 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
7257 {
7258         core_if->srp_timer_started = 1;
7259         DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
7260 }
7261
7262 void dwc_otg_initiate_srp(void * p)
7263 {
7264         dwc_otg_core_if_t * core_if = p;
7265         uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
7266         gotgctl_data_t mem;
7267         gotgctl_data_t val;
7268
7269         val.d32 = DWC_READ_REG32(addr);
7270         if (val.b.sesreq) {
7271                 DWC_ERROR("Session Request Already active!\n");
7272                 return;
7273         }
7274
7275         DWC_INFO("Session Request Initated\n"); //NOTICE
7276         mem.d32 = DWC_READ_REG32(addr);
7277         mem.b.sesreq = 1;
7278         DWC_WRITE_REG32(addr, mem.d32);
7279
7280         /* Start the SRP timer */
7281         dwc_otg_pcd_start_srp_timer(core_if);
7282         return;
7283 }
7284
7285 int dwc_otg_check_haps_status(dwc_otg_core_if_t * core_if)
7286 {
7287    int retval = 0;
7288
7289    if(DWC_READ_REG32(&core_if->core_global_regs->gsnpsid) == 0xffffffff)
7290    {
7291                 return -1;
7292    } else {
7293                 return retval;
7294    } 
7295
7296 }