Main Page | Data Structures | File List | Data Fields | Globals | Related Pages

dwc_otg_cil.c

Go to the documentation of this file.
00001 /* ==========================================================================
00002  * $File: //dwh/usb_iip/dev/software/otg/linux/drivers/dwc_otg_cil.c $
00003  * $Revision: #189 $
00004  * $Date: 2011/10/24 $
00005  * $Change: 1871160 $
00006  *
00007  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
00008  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
00009  * otherwise expressly agreed to in writing between Synopsys and you.
00010  *
00011  * The Software IS NOT an item of Licensed Software or Licensed Product under
00012  * any End User Software License Agreement or Agreement for Licensed Product
00013  * with Synopsys or any supplement thereto. You are permitted to use and
00014  * redistribute this Software in source and binary forms, with or without
00015  * modification, provided that redistributions of source code must retain this
00016  * notice. You may not view, use, disclose, copy or distribute this file or
00017  * any information contained herein except pursuant to this license grant from
00018  * Synopsys. If you do not agree with this notice, including the disclaimer
00019  * below, then you are not authorized to use the Software.
00020  *
00021  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
00022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00024  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
00025  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00026  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00027  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00028  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00029  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00030  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00031  * DAMAGE.
00032  * ========================================================================== */
00033 
00060 #include "dwc_os.h"
00061 #include "dwc_otg_regs.h"
00062 #include "dwc_otg_cil.h"
00063 
00064 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if);
00065 
00078 dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * reg_base_addr)
00079 {
00080         dwc_otg_core_if_t *core_if = 0;
00081         dwc_otg_dev_if_t *dev_if = 0;
00082         dwc_otg_host_if_t *host_if = 0;
00083         uint8_t *reg_base = (uint8_t *) reg_base_addr;
00084         int i = 0;
00085 
00086         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, reg_base_addr);
00087 
00088         core_if = DWC_ALLOC(sizeof(dwc_otg_core_if_t));
00089 
00090         if (core_if == NULL) {
00091                 DWC_DEBUGPL(DBG_CIL,
00092                             "Allocation of dwc_otg_core_if_t failed\n");
00093                 return 0;
00094         }
00095         core_if->core_global_regs = (dwc_otg_core_global_regs_t *) reg_base;
00096 
00097         /*
00098          * Allocate the Device Mode structures.
00099          */
00100         dev_if = DWC_ALLOC(sizeof(dwc_otg_dev_if_t));
00101 
00102         if (dev_if == NULL) {
00103                 DWC_DEBUGPL(DBG_CIL, "Allocation of dwc_otg_dev_if_t failed\n");
00104                 DWC_FREE(core_if);
00105                 return 0;
00106         }
00107 
00108         dev_if->dev_global_regs =
00109             (dwc_otg_device_global_regs_t *) (reg_base +
00110                                               DWC_DEV_GLOBAL_REG_OFFSET);
00111 
00112         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00113                 dev_if->in_ep_regs[i] = (dwc_otg_dev_in_ep_regs_t *)
00114                     (reg_base + DWC_DEV_IN_EP_REG_OFFSET +
00115                      (i * DWC_EP_REG_OFFSET));
00116 
00117                 dev_if->out_ep_regs[i] = (dwc_otg_dev_out_ep_regs_t *)
00118                     (reg_base + DWC_DEV_OUT_EP_REG_OFFSET +
00119                      (i * DWC_EP_REG_OFFSET));
00120                 DWC_DEBUGPL(DBG_CILV, "in_ep_regs[%d]->diepctl=%p\n",
00121                             i, &dev_if->in_ep_regs[i]->diepctl);
00122                 DWC_DEBUGPL(DBG_CILV, "out_ep_regs[%d]->doepctl=%p\n",
00123                             i, &dev_if->out_ep_regs[i]->doepctl);
00124         }
00125 
00126         dev_if->speed = 0;      // unknown
00127 
00128         core_if->dev_if = dev_if;
00129 
00130         /*
00131          * Allocate the Host Mode structures.
00132          */
00133         host_if = DWC_ALLOC(sizeof(dwc_otg_host_if_t));
00134 
00135         if (host_if == NULL) {
00136                 DWC_DEBUGPL(DBG_CIL,
00137                             "Allocation of dwc_otg_host_if_t failed\n");
00138                 DWC_FREE(dev_if);
00139                 DWC_FREE(core_if);
00140                 return 0;
00141         }
00142 
00143         host_if->host_global_regs = (dwc_otg_host_global_regs_t *)
00144             (reg_base + DWC_OTG_HOST_GLOBAL_REG_OFFSET);
00145 
00146         host_if->hprt0 =
00147             (uint32_t *) (reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
00148 
00149         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00150                 host_if->hc_regs[i] = (dwc_otg_hc_regs_t *)
00151                     (reg_base + DWC_OTG_HOST_CHAN_REGS_OFFSET +
00152                      (i * DWC_OTG_CHAN_REGS_OFFSET));
00153                 DWC_DEBUGPL(DBG_CILV, "hc_reg[%d]->hcchar=%p\n",
00154                             i, &host_if->hc_regs[i]->hcchar);
00155         }
00156 
00157         host_if->num_host_channels = MAX_EPS_CHANNELS;
00158         core_if->host_if = host_if;
00159 
00160         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00161                 core_if->data_fifo[i] =
00162                     (uint32_t *) (reg_base + DWC_OTG_DATA_FIFO_OFFSET +
00163                                   (i * DWC_OTG_DATA_FIFO_SIZE));
00164                 DWC_DEBUGPL(DBG_CILV, "data_fifo[%d]=0x%08lx\n",
00165                             i, (unsigned long)core_if->data_fifo[i]);
00166         }
00167 
00168         core_if->pcgcctl = (uint32_t *) (reg_base + DWC_OTG_PCGCCTL_OFFSET);
00169 
00170         /* Initiate lx_state to L3 disconnected state */
00171         core_if->lx_state = DWC_OTG_L3;
00172         /*
00173          * Store the contents of the hardware configuration registers here for
00174          * easy access later.
00175          */
00176         core_if->hwcfg1.d32 =
00177             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg1);
00178         core_if->hwcfg2.d32 =
00179             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
00180         core_if->hwcfg3.d32 =
00181             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg3);
00182         core_if->hwcfg4.d32 =
00183             DWC_READ_REG32(&core_if->core_global_regs->ghwcfg4);
00184 
00185         /* Force host mode to get HPTXFSIZ exact power on value */
00186         {
00187                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
00188                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00189                 gusbcfg.b.force_host_mode = 1;
00190                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
00191                 dwc_mdelay(100); 
00192                 core_if->hptxfsiz.d32 =
00193                 DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
00194                 gusbcfg.d32 =  DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00195                 gusbcfg.b.force_host_mode = 0;
00196                 DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
00197                 dwc_mdelay(100); 
00198         }
00199 
00200         DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
00201         DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
00202         DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
00203         DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
00204 
00205         core_if->hcfg.d32 =
00206             DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
00207         core_if->dcfg.d32 =
00208             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
00209 
00210         DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
00211         DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
00212 
00213         DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
00214         DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
00215         DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
00216         DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
00217                     core_if->hwcfg2.b.num_host_chan);
00218         DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
00219                     core_if->hwcfg2.b.nonperio_tx_q_depth);
00220         DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
00221                     core_if->hwcfg2.b.host_perio_tx_q_depth);
00222         DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
00223                     core_if->hwcfg2.b.dev_token_q_depth);
00224 
00225         DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
00226                     core_if->hwcfg3.b.dfifo_depth);
00227         DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
00228                     core_if->hwcfg3.b.xfer_size_cntr_width);
00229 
00230         /*
00231          * Set the SRP sucess bit for FS-I2c
00232          */
00233         core_if->srp_success = 0;
00234         core_if->srp_timer_started = 0;
00235 
00236         /*
00237          * Create new workqueue and init works
00238          */
00239         core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
00240         if (core_if->wq_otg == 0) {
00241                 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
00242                 DWC_FREE(host_if);
00243                 DWC_FREE(dev_if);
00244                 DWC_FREE(core_if);
00245                 return 0;
00246         }
00247 
00248         core_if->snpsid = DWC_READ_REG32(&core_if->core_global_regs->gsnpsid);
00249 
00250         DWC_PRINTF("Core Release: %x.%x%x%x\n",
00251                    (core_if->snpsid >> 12 & 0xF),
00252                    (core_if->snpsid >> 8 & 0xF),
00253                    (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
00254 
00255         core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
00256                                              w_wakeup_detected, core_if);
00257         if (core_if->wkp_timer == 0) {
00258                 DWC_WARN("DWC_TIMER_ALLOC failed\n");
00259                 DWC_FREE(host_if);
00260                 DWC_FREE(dev_if);
00261                 DWC_WORKQ_FREE(core_if->wq_otg);
00262                 DWC_FREE(core_if);
00263                 return 0;
00264         }
00265 
00266         if (dwc_otg_setup_params(core_if)) {
00267                 DWC_WARN("Error while setting core params\n");
00268         }
00269 
00270         core_if->hibernation_suspend = 0;
00271 
00273         dwc_otg_adp_init(core_if);
00274         
00275         return core_if;
00276 }
00277 
00285 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
00286 {
00287         /* Disable all interrupts */
00288         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 1, 0);
00289         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, 0);
00290 
00291         if (core_if->wq_otg) {
00292                 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
00293                 DWC_WORKQ_FREE(core_if->wq_otg);
00294         }
00295         if (core_if->dev_if) {
00296                 DWC_FREE(core_if->dev_if);
00297         }
00298         if (core_if->host_if) {
00299                 DWC_FREE(core_if->host_if);
00300         }
00301 
00303         dwc_otg_adp_remove(core_if);
00304         if (core_if->core_params) {
00305                 DWC_FREE(core_if->core_params);
00306         }
00307         if (core_if->wkp_timer) {
00308                 DWC_TIMER_FREE(core_if->wkp_timer);
00309         }
00310         if (core_if->srp_timer) {
00311                 DWC_TIMER_FREE(core_if->srp_timer);
00312         }
00313         DWC_FREE(core_if);
00314 }
00315 
00322 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
00323 {
00324         gahbcfg_data_t ahbcfg = {.d32 = 0 };
00325         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
00326         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
00327 }
00328 
00335 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
00336 {
00337         gahbcfg_data_t ahbcfg = {.d32 = 0 };
00338         ahbcfg.b.glblintrmsk = 1;       /* Disable interrupts */
00339         DWC_MODIFY_REG32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
00340 }
00341 
00349 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
00350 {
00351         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00352         gintmsk_data_t intr_mask = {.d32 = 0 };
00353 
00354         /* Clear any pending OTG Interrupts */
00355         DWC_WRITE_REG32(&global_regs->gotgint, 0xFFFFFFFF);
00356 
00357         /* Clear any pending interrupts */
00358         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
00359 
00360         /*
00361          * Enable the interrupts in the GINTMSK.
00362          */
00363         intr_mask.b.modemismatch = 1;
00364         intr_mask.b.otgintr = 1;
00365 
00366         if (!core_if->dma_enable) {
00367                 intr_mask.b.rxstsqlvl = 1;
00368         }
00369 
00370         intr_mask.b.conidstschng = 1;
00371         intr_mask.b.wkupintr = 1;
00372         intr_mask.b.disconnect = 0;
00373         intr_mask.b.usbsuspend = 1;
00374         intr_mask.b.sessreqintr = 1;
00375 #ifdef CONFIG_USB_DWC_OTG_LPM
00376         if (core_if->core_params->lpm_enable) {
00377                 intr_mask.b.lpmtranrcvd = 1;
00378         }
00379 #endif
00380         DWC_WRITE_REG32(&global_regs->gintmsk, intr_mask.d32);
00381 }
00382 
00383 /*
00384  * The restore operation is modified to support Synopsys Emulated Powerdown and
00385  * Hibernation. This function is for exiting from Device mode hibernation by
00386  * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
00387  * @param core_if Programming view of DWC_otg controller.
00388  * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
00389  * @param reset - indicates whether resume is initiated by Reset.
00390  */
00391 int dwc_otg_device_hibernation_restore(dwc_otg_core_if_t * core_if,
00392                                        int rem_wakeup, int reset)
00393 {
00394         gpwrdn_data_t gpwrdn = {.d32 = 0 };
00395         pcgcctl_data_t pcgcctl = {.d32 = 0 };
00396         dctl_data_t dctl = {.d32 = 0 };
00397 
00398         int timeout = 2000;
00399 
00400         if (!core_if->hibernation_suspend) {
00401                 DWC_PRINTF("Already exited from Hibernation\n");
00402                 return 1;
00403         }
00404 
00405         DWC_DEBUGPL(DBG_PCD, "%s called\n", __FUNCTION__);
00406         /* Switch-on voltage to the core */
00407         gpwrdn.b.pwrdnswtch = 1;
00408         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00409         dwc_udelay(10);
00410 
00411         /* Reset core */
00412         gpwrdn.d32 = 0;
00413         gpwrdn.b.pwrdnrstn = 1;
00414         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00415         dwc_udelay(10);
00416 
00417         /* Assert Restore signal */
00418         gpwrdn.d32 = 0;
00419         gpwrdn.b.restore = 1;
00420         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00421         dwc_udelay(10);
00422 
00423         /* Disable power clamps */
00424         gpwrdn.d32 = 0;
00425         gpwrdn.b.pwrdnclmp = 1;
00426         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00427 
00428         if (rem_wakeup) {
00429                 dwc_udelay(70);
00430         }
00431 
00432         /* Deassert Reset core */
00433         gpwrdn.d32 = 0;
00434         gpwrdn.b.pwrdnrstn = 1;
00435         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00436         dwc_udelay(10);
00437 
00438         /* Disable PMU interrupt */
00439         gpwrdn.d32 = 0;
00440         gpwrdn.b.pmuintsel = 1;
00441         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00442 
00443         /* Mask interrupts from gpwrdn */
00444         gpwrdn.d32 = 0;
00445         gpwrdn.b.connect_det_msk = 1;
00446         gpwrdn.b.srp_det_msk = 1;
00447         gpwrdn.b.disconn_det_msk = 1;
00448         gpwrdn.b.rst_det_msk = 1;
00449         gpwrdn.b.lnstchng_msk = 1;
00450         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00451 
00452         /* Indicates that we are going out from hibernation */
00453         core_if->hibernation_suspend = 0;
00454 
00455         /*
00456          * Set Restore Essential Regs bit in PCGCCTL register, restore_mode = 1
00457          * indicates restore from remote_wakeup
00458          */
00459         restore_essential_regs(core_if, rem_wakeup, 0);
00460 
00461         /*
00462          * Wait a little for seeing new value of variable hibernation_suspend if
00463          * Restore done interrupt received before polling
00464          */
00465         dwc_udelay(10);
00466 
00467         if (core_if->hibernation_suspend == 0) {
00468                 /*
00469                  * Wait For Restore_done Interrupt. This mechanism of polling the 
00470                  * interrupt is introduced to avoid any possible race conditions
00471                  */
00472                 do {
00473                         gintsts_data_t gintsts;
00474                         gintsts.d32 =
00475                             DWC_READ_REG32(&core_if->core_global_regs->gintsts);
00476                         if (gintsts.b.restoredone) {
00477                                 gintsts.d32 = 0;
00478                                 gintsts.b.restoredone = 1;
00479                                 DWC_WRITE_REG32(&core_if->core_global_regs->
00480                                                 gintsts, gintsts.d32);
00481                                 DWC_PRINTF("Restore Done Interrupt seen\n");
00482                                 break;
00483                         }
00484                         dwc_udelay(10);
00485                 } while (--timeout);
00486                 if (!timeout) {
00487                         DWC_PRINTF("Restore Done interrupt wasn't generated here\n");
00488                 }
00489         }
00490         /* Clear all pending interupts */
00491         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00492 
00493         /* De-assert Restore */
00494         gpwrdn.d32 = 0;
00495         gpwrdn.b.restore = 1;
00496         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00497         dwc_udelay(10);
00498 
00499         if (!rem_wakeup) {
00500                 pcgcctl.d32 = 0;
00501                 pcgcctl.b.rstpdwnmodule = 1;
00502                 DWC_MODIFY_REG32(core_if->pcgcctl, pcgcctl.d32, 0);
00503         }
00504 
00505         /* Restore GUSBCFG and DCFG */
00506         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
00507                         core_if->gr_backup->gusbcfg_local);
00508         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg,
00509                         core_if->dr_backup->dcfg);
00510 
00511         /* De-assert Wakeup Logic */
00512         gpwrdn.d32 = 0;
00513         gpwrdn.b.pmuactv = 1;
00514         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00515         dwc_udelay(10);
00516 
00517         if (!rem_wakeup) {
00518                 /* Set Device programming done bit */
00519                 dctl.b.pwronprgdone = 1;
00520                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
00521         } else {
00522                 /* Start Remote Wakeup Signaling */
00523                 dctl.d32 = core_if->dr_backup->dctl;
00524                 dctl.b.rmtwkupsig = 1;
00525                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32);
00526         }
00527 
00528         dwc_mdelay(2);
00529         /* Clear all pending interupts */
00530         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00531 
00532         /* Restore global registers */
00533         dwc_otg_restore_global_regs(core_if);
00534         /* Restore device global registers */
00535         dwc_otg_restore_dev_regs(core_if, rem_wakeup);
00536 
00537         if (rem_wakeup) {
00538                 dwc_mdelay(7);
00539                 dctl.d32 = 0;
00540                 dctl.b.rmtwkupsig = 1;
00541                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, dctl.d32, 0);
00542         }
00543 
00544         core_if->hibernation_suspend = 0;
00545         /* The core will be in ON STATE */
00546         core_if->lx_state = DWC_OTG_L0;
00547         DWC_PRINTF("Hibernation recovery completes here\n");
00548 
00549         return 1;
00550 }
00551 
00552 /*
00553  * The restore operation is modified to support Synopsys Emulated Powerdown and
00554  * Hibernation. This function is for exiting from Host mode hibernation by
00555  * Host Initiated Resume/Reset and Device Initiated Remote-Wakeup.
00556  * @param core_if Programming view of DWC_otg controller.
00557  * @param rem_wakeup - indicates whether resume is initiated by Device or Host.
00558  * @param reset - indicates whether resume is initiated by Reset.
00559  */
00560 int dwc_otg_host_hibernation_restore(dwc_otg_core_if_t * core_if,
00561                                      int rem_wakeup, int reset)
00562 {
00563         gpwrdn_data_t gpwrdn = {.d32 = 0 };
00564         hprt0_data_t hprt0 = {.d32 = 0 };
00565 
00566         int timeout = 2000;
00567 
00568         DWC_DEBUGPL(DBG_HCD, "%s called\n", __FUNCTION__);
00569         /* Switch-on voltage to the core */
00570         gpwrdn.b.pwrdnswtch = 1;
00571         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00572         dwc_udelay(10);
00573 
00574         /* Reset core */
00575         gpwrdn.d32 = 0;
00576         gpwrdn.b.pwrdnrstn = 1;
00577         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00578         dwc_udelay(10);
00579 
00580         /* Assert Restore signal */
00581         gpwrdn.d32 = 0;
00582         gpwrdn.b.restore = 1;
00583         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00584         dwc_udelay(10);
00585 
00586         /* Disable power clamps */
00587         gpwrdn.d32 = 0;
00588         gpwrdn.b.pwrdnclmp = 1;
00589         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00590 
00591         if (!rem_wakeup) {
00592                 dwc_udelay(50);
00593         }
00594 
00595         /* Deassert Reset core */
00596         gpwrdn.d32 = 0;
00597         gpwrdn.b.pwrdnrstn = 1;
00598         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, 0, gpwrdn.d32);
00599         dwc_udelay(10);
00600 
00601         /* Disable PMU interrupt */
00602         gpwrdn.d32 = 0;
00603         gpwrdn.b.pmuintsel = 1;
00604         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00605 
00606         gpwrdn.d32 = 0;
00607         gpwrdn.b.connect_det_msk = 1;
00608         gpwrdn.b.srp_det_msk = 1;
00609         gpwrdn.b.disconn_det_msk = 1;
00610         gpwrdn.b.rst_det_msk = 1;
00611         gpwrdn.b.lnstchng_msk = 1;
00612         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00613 
00614         /* Indicates that we are going out from hibernation */
00615         core_if->hibernation_suspend = 0;
00616 
00617         /* Set Restore Essential Regs bit in PCGCCTL register */
00618         restore_essential_regs(core_if, rem_wakeup, 1);
00619 
00620         /* Wait a little for seeing new value of variable hibernation_suspend if
00621          * Restore done interrupt received before polling */
00622         dwc_udelay(10);
00623 
00624         if (core_if->hibernation_suspend == 0) {
00625                 /* Wait For Restore_done Interrupt. This mechanism of polling the
00626                  * interrupt is introduced to avoid any possible race conditions
00627                  */
00628                 do {
00629                         gintsts_data_t gintsts;
00630                         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
00631                         if (gintsts.b.restoredone) {
00632                                 gintsts.d32 = 0;
00633                                 gintsts.b.restoredone = 1;
00634                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
00635                                 DWC_DEBUGPL(DBG_HCD,"Restore Done Interrupt seen\n");   
00636                                 break;
00637                         }
00638                         dwc_udelay(10);
00639                 } while (--timeout);
00640                 if (!timeout) {
00641                         DWC_WARN("Restore Done interrupt wasn't generated\n");
00642                 }
00643         }
00644 
00645         /* Set the flag's value to 0 again after receiving restore done interrupt */
00646         core_if->hibernation_suspend = 0;
00647 
00648         /* This step is not described in functional spec but if not wait for this
00649          * delay, mismatch interrupts occurred because just after restore core is
00650          * in Device mode(gintsts.curmode == 0) */
00651         dwc_mdelay(100);
00652 
00653         /* Clear all pending interrupts */
00654         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00655 
00656         /* De-assert Restore */
00657         gpwrdn.d32 = 0;
00658         gpwrdn.b.restore = 1;
00659         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00660         dwc_udelay(10);
00661 
00662         /* Restore GUSBCFG and HCFG */
00663         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg,
00664                         core_if->gr_backup->gusbcfg_local);
00665         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
00666                         core_if->hr_backup->hcfg_local);
00667 
00668         /* De-assert Wakeup Logic */
00669         gpwrdn.d32 = 0;
00670         gpwrdn.b.pmuactv = 1;
00671         DWC_MODIFY_REG32(&core_if->core_global_regs->gpwrdn, gpwrdn.d32, 0);
00672         dwc_udelay(10);
00673 
00674         /* Start the Resume operation by programming HPRT0 */
00675         hprt0.d32 = core_if->hr_backup->hprt0_local;
00676         hprt0.b.prtpwr = 1;
00677         hprt0.b.prtena = 0;
00678         hprt0.b.prtsusp = 0;
00679         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00680 
00681         DWC_PRINTF("Resume Starts Now\n");
00682         if (!reset) {           // Indicates it is Resume Operation
00683                 hprt0.d32 = core_if->hr_backup->hprt0_local;
00684                 hprt0.b.prtres = 1;
00685                 hprt0.b.prtpwr = 1;
00686                 hprt0.b.prtena = 0;
00687                 hprt0.b.prtsusp = 0;
00688                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00689 
00690                 if (!rem_wakeup)
00691                         hprt0.b.prtres = 0;
00692                 /* Wait for Resume time and then program HPRT again */
00693                 dwc_mdelay(100);
00694                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00695 
00696         } else {                // Indicates it is Reset Operation
00697                 hprt0.d32 = core_if->hr_backup->hprt0_local;
00698                 hprt0.b.prtrst = 1;
00699                 hprt0.b.prtpwr = 1;
00700                 hprt0.b.prtena = 0;
00701                 hprt0.b.prtsusp = 0;
00702                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00703                 /* Wait for Reset time and then program HPRT again */
00704                 dwc_mdelay(60);
00705                 hprt0.b.prtrst = 0;
00706                 DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00707         }
00708         /* Clear all interrupt status */
00709         hprt0.d32 = dwc_otg_read_hprt0(core_if);
00710         hprt0.b.prtconndet = 1;
00711         hprt0.b.prtenchng = 1;
00712         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
00713 
00714         /* Clear all pending interupts */
00715         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00716 
00717         /* Restore global registers */
00718         dwc_otg_restore_global_regs(core_if);
00719         /* Restore host global registers */
00720         dwc_otg_restore_host_regs(core_if, reset);
00721 
00722         /* The core will be in ON STATE */
00723         core_if->lx_state = DWC_OTG_L0;
00724         DWC_PRINTF("Hibernation recovery is complete here\n");
00725         return 0;
00726 }
00727 
00729 int dwc_otg_save_global_regs(dwc_otg_core_if_t * core_if)
00730 {
00731         struct dwc_otg_global_regs_backup *gr;
00732         int i;
00733 
00734         gr = core_if->gr_backup;
00735         if (!gr) {
00736                 gr = DWC_ALLOC(sizeof(*gr));
00737                 if (!gr) {
00738                         return -DWC_E_NO_MEMORY;
00739                 }
00740                 core_if->gr_backup = gr;
00741         }
00742 
00743         gr->gotgctl_local = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
00744         gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
00745         gr->gahbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gahbcfg);
00746         gr->gusbcfg_local = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
00747         gr->grxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
00748         gr->gnptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
00749         gr->hptxfsiz_local = DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
00750 #ifdef CONFIG_USB_DWC_OTG_LPM
00751         gr->glpmcfg_local = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
00752 #endif
00753         gr->gi2cctl_local = DWC_READ_REG32(&core_if->core_global_regs->gi2cctl);
00754         gr->pcgcctl_local = DWC_READ_REG32(core_if->pcgcctl);
00755         gr->gdfifocfg_local =
00756             DWC_READ_REG32(&core_if->core_global_regs->gdfifocfg);
00757         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00758                 gr->dtxfsiz_local[i] =
00759                     DWC_READ_REG32(&(core_if->core_global_regs->dtxfsiz[i]));
00760         }
00761 
00762         DWC_DEBUGPL(DBG_ANY, "===========Backing Global registers==========\n");
00763         DWC_DEBUGPL(DBG_ANY, "Backed up gotgctl   = %08x\n", gr->gotgctl_local);
00764         DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk   = %08x\n", gr->gintmsk_local);
00765         DWC_DEBUGPL(DBG_ANY, "Backed up gahbcfg   = %08x\n", gr->gahbcfg_local);
00766         DWC_DEBUGPL(DBG_ANY, "Backed up gusbcfg   = %08x\n", gr->gusbcfg_local);
00767         DWC_DEBUGPL(DBG_ANY, "Backed up grxfsiz   = %08x\n", gr->grxfsiz_local);
00768         DWC_DEBUGPL(DBG_ANY, "Backed up gnptxfsiz = %08x\n",
00769                     gr->gnptxfsiz_local);
00770         DWC_DEBUGPL(DBG_ANY, "Backed up hptxfsiz  = %08x\n",
00771                     gr->hptxfsiz_local);
00772 #ifdef CONFIG_USB_DWC_OTG_LPM
00773         DWC_DEBUGPL(DBG_ANY, "Backed up glpmcfg   = %08x\n", gr->glpmcfg_local);
00774 #endif
00775         DWC_DEBUGPL(DBG_ANY, "Backed up gi2cctl   = %08x\n", gr->gi2cctl_local);
00776         DWC_DEBUGPL(DBG_ANY, "Backed up pcgcctl   = %08x\n", gr->pcgcctl_local);
00777         DWC_DEBUGPL(DBG_ANY,"Backed up gdfifocfg   = %08x\n",gr->gdfifocfg_local);
00778 
00779         return 0;
00780 }
00781 
00783 int dwc_otg_save_gintmsk_reg(dwc_otg_core_if_t * core_if)
00784 {
00785         struct dwc_otg_global_regs_backup *gr;
00786 
00787         gr = core_if->gr_backup;
00788         if (!gr) {
00789                 gr = DWC_ALLOC(sizeof(*gr));
00790                 if (!gr) {
00791                         return -DWC_E_NO_MEMORY;
00792                 }
00793                 core_if->gr_backup = gr;
00794         }
00795 
00796         gr->gintmsk_local = DWC_READ_REG32(&core_if->core_global_regs->gintmsk);
00797 
00798         DWC_DEBUGPL(DBG_ANY,"=============Backing GINTMSK registers============\n");
00799         DWC_DEBUGPL(DBG_ANY, "Backed up gintmsk   = %08x\n", gr->gintmsk_local);
00800 
00801         return 0;
00802 }
00803 
00804 int dwc_otg_save_dev_regs(dwc_otg_core_if_t * core_if)
00805 {
00806         struct dwc_otg_dev_regs_backup *dr;
00807         int i;
00808 
00809         dr = core_if->dr_backup;
00810         if (!dr) {
00811                 dr = DWC_ALLOC(sizeof(*dr));
00812                 if (!dr) {
00813                         return -DWC_E_NO_MEMORY;
00814                 }
00815                 core_if->dr_backup = dr;
00816         }
00817 
00818         dr->dcfg = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
00819         dr->dctl = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
00820         dr->daintmsk =
00821             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->daintmsk);
00822         dr->diepmsk =
00823             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->diepmsk);
00824         dr->doepmsk =
00825             DWC_READ_REG32(&core_if->dev_if->dev_global_regs->doepmsk);
00826 
00827         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00828                 dr->diepctl[i] =
00829                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl);
00830                 dr->dieptsiz[i] =
00831                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz);
00832                 dr->diepdma[i] =
00833                     DWC_READ_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma);
00834         }
00835 
00836         DWC_DEBUGPL(DBG_ANY,
00837                     "=============Backing Host registers==============\n");
00838         DWC_DEBUGPL(DBG_ANY, "Backed up dcfg            = %08x\n", dr->dcfg);
00839         DWC_DEBUGPL(DBG_ANY, "Backed up dctl        = %08x\n", dr->dctl);
00840         DWC_DEBUGPL(DBG_ANY, "Backed up daintmsk            = %08x\n",
00841                     dr->daintmsk);
00842         DWC_DEBUGPL(DBG_ANY, "Backed up diepmsk        = %08x\n", dr->diepmsk);
00843         DWC_DEBUGPL(DBG_ANY, "Backed up doepmsk        = %08x\n", dr->doepmsk);
00844         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00845                 DWC_DEBUGPL(DBG_ANY, "Backed up diepctl[%d]        = %08x\n", i,
00846                             dr->diepctl[i]);
00847                 DWC_DEBUGPL(DBG_ANY, "Backed up dieptsiz[%d]        = %08x\n",
00848                             i, dr->dieptsiz[i]);
00849                 DWC_DEBUGPL(DBG_ANY, "Backed up diepdma[%d]        = %08x\n", i,
00850                             dr->diepdma[i]);
00851         }
00852 
00853         return 0;
00854 }
00855 
00856 int dwc_otg_save_host_regs(dwc_otg_core_if_t * core_if)
00857 {
00858         struct dwc_otg_host_regs_backup *hr;
00859         int i;
00860 
00861         hr = core_if->hr_backup;
00862         if (!hr) {
00863                 hr = DWC_ALLOC(sizeof(*hr));
00864                 if (!hr) {
00865                         return -DWC_E_NO_MEMORY;
00866                 }
00867                 core_if->hr_backup = hr;
00868         }
00869 
00870         hr->hcfg_local =
00871             DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
00872         hr->haintmsk_local =
00873             DWC_READ_REG32(&core_if->host_if->host_global_regs->haintmsk);
00874         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00875                 hr->hcintmsk_local[i] =
00876                     DWC_READ_REG32(&core_if->host_if->hc_regs[i]->hcintmsk);
00877         }
00878         hr->hprt0_local = DWC_READ_REG32(core_if->host_if->hprt0);
00879         hr->hfir_local =
00880             DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
00881 
00882         DWC_DEBUGPL(DBG_ANY,
00883                     "=============Backing Host registers===============\n");
00884         DWC_DEBUGPL(DBG_ANY, "Backed up hcfg            = %08x\n",
00885                     hr->hcfg_local);
00886         DWC_DEBUGPL(DBG_ANY, "Backed up haintmsk = %08x\n", hr->haintmsk_local);
00887         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00888                 DWC_DEBUGPL(DBG_ANY, "Backed up hcintmsk[%02d]=%08x\n", i,
00889                             hr->hcintmsk_local[i]);
00890         }
00891         DWC_DEBUGPL(DBG_ANY, "Backed up hprt0           = %08x\n",
00892                     hr->hprt0_local);
00893         DWC_DEBUGPL(DBG_ANY, "Backed up hfir           = %08x\n",
00894                     hr->hfir_local);
00895 
00896         return 0;
00897 }
00898 
00899 int dwc_otg_restore_global_regs(dwc_otg_core_if_t *core_if)
00900 {
00901         struct dwc_otg_global_regs_backup *gr;
00902         int i;
00903 
00904         gr = core_if->gr_backup;
00905         if (!gr) {
00906                 return -DWC_E_INVALID;
00907         }
00908    
00909         DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, gr->gotgctl_local);
00910         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gr->gintmsk_local);
00911         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gr->gusbcfg_local);
00912         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gr->gahbcfg_local);
00913         DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, gr->grxfsiz_local);
00914         DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz,
00915                         gr->gnptxfsiz_local);
00916         DWC_WRITE_REG32(&core_if->core_global_regs->hptxfsiz,
00917                         gr->hptxfsiz_local);
00918         DWC_WRITE_REG32(&core_if->core_global_regs->gdfifocfg,
00919                         gr->gdfifocfg_local);
00920         for (i = 0; i < MAX_EPS_CHANNELS; i++) {
00921                 DWC_WRITE_REG32(&core_if->core_global_regs->dtxfsiz[i],
00922                                 gr->dtxfsiz_local[i]);
00923         }
00924 
00925         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
00926         DWC_WRITE_REG32(core_if->host_if->hprt0, 0x0000100A);
00927         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg,
00928                         (gr->gahbcfg_local));
00929         return 0;
00930 }
00931 
00932 int dwc_otg_restore_dev_regs(dwc_otg_core_if_t * core_if, int rem_wakeup)
00933 {
00934         struct dwc_otg_dev_regs_backup *dr;
00935         int i;
00936 
00937         dr = core_if->dr_backup;
00938 
00939         if (!dr) {
00940                 return -DWC_E_INVALID;
00941         }
00942 
00943         if (!rem_wakeup)
00944         {
00945                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dctl, dr->dctl);
00946         }
00947         
00948         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->daintmsk, dr->daintmsk);
00949         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->diepmsk, dr->diepmsk);
00950         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->doepmsk, dr->doepmsk);
00951 
00952         for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
00953                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepctl, dr->diepctl[i]);
00954                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->dieptsiz, dr->dieptsiz[i]);
00955                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[i]->diepdma, dr->diepdma[i]);
00956         }
00957         
00958         return 0;
00959 }
00960 
00961 int dwc_otg_restore_host_regs(dwc_otg_core_if_t * core_if, int reset)
00962 {
00963         struct dwc_otg_host_regs_backup *hr;
00964         int i;
00965         hr = core_if->hr_backup;
00966 
00967         if (!hr) {
00968                 return -DWC_E_INVALID;
00969         }
00970 
00971         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hr->hcfg_local);
00972         //if (!reset)
00973         //{
00974         //      DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hr->hfir_local);
00975         //}
00976 
00977         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->haintmsk,
00978                         hr->haintmsk_local);
00979         for (i = 0; i < dwc_otg_get_param_host_channels(core_if); ++i) {
00980                 DWC_WRITE_REG32(&core_if->host_if->hc_regs[i]->hcintmsk,
00981                                 hr->hcintmsk_local[i]);
00982         }
00983 
00984         return 0;
00985 }
00986 
00987 int restore_lpm_i2c_regs(dwc_otg_core_if_t * core_if)
00988 {
00989         struct dwc_otg_global_regs_backup *gr;
00990 
00991         gr = core_if->gr_backup;
00992 
00993         /* Restore values for LPM and I2C */
00994 #ifdef CONFIG_USB_DWC_OTG_LPM
00995         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, gr->glpmcfg_local);
00996 #endif
00997         DWC_WRITE_REG32(&core_if->core_global_regs->gi2cctl, gr->gi2cctl_local);
00998 
00999         return 0;
01000 }
01001 
01002 int restore_essential_regs(dwc_otg_core_if_t * core_if, int rmode, int is_host)
01003 {
01004         struct dwc_otg_global_regs_backup *gr;
01005         pcgcctl_data_t pcgcctl = {.d32 = 0 };
01006         gahbcfg_data_t gahbcfg = {.d32 = 0 };
01007         gusbcfg_data_t gusbcfg = {.d32 = 0 };
01008         gintmsk_data_t gintmsk = {.d32 = 0 };
01009 
01010         /* Restore LPM and I2C registers */
01011         restore_lpm_i2c_regs(core_if);
01012 
01013         /* Set PCGCCTL to 0 */
01014         DWC_WRITE_REG32(core_if->pcgcctl, 0x00000000);
01015 
01016         gr = core_if->gr_backup;
01017         /* Load restore values for [31:14] bits */
01018         DWC_WRITE_REG32(core_if->pcgcctl,
01019                         ((gr->pcgcctl_local & 0xffffc000) | 0x00020000));
01020 
01021         /* Umnask global Interrupt in GAHBCFG and restore it */
01022         gahbcfg.d32 = gr->gahbcfg_local;
01023         gahbcfg.b.glblintrmsk = 1;
01024         DWC_WRITE_REG32(&core_if->core_global_regs->gahbcfg, gahbcfg.d32);
01025 
01026         /* Clear all pending interupts */
01027         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, 0xFFFFFFFF);
01028 
01029         /* Unmask restore done interrupt */
01030         gintmsk.b.restoredone = 1;
01031         DWC_WRITE_REG32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
01032 
01033         /* Restore GUSBCFG and HCFG/DCFG */
01034         gusbcfg.d32 = core_if->gr_backup->gusbcfg_local;
01035         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, gusbcfg.d32);
01036 
01037         if (is_host) {
01038                 hcfg_data_t hcfg = {.d32 = 0 };
01039                 hcfg.d32 = core_if->hr_backup->hcfg_local;
01040                 DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg,
01041                                 hcfg.d32);
01042 
01043                 /* Load restore values for [31:14] bits */
01044                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01045                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01046 
01047                 if (rmode)
01048                         pcgcctl.b.restoremode = 1;
01049                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01050                 dwc_udelay(10);
01051 
01052                 /* Load restore values for [31:14] bits and set EssRegRestored bit */
01053                 pcgcctl.d32 = gr->pcgcctl_local | 0xffffc000;
01054                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01055                 pcgcctl.b.ess_reg_restored = 1;
01056                 if (rmode)
01057                         pcgcctl.b.restoremode = 1;
01058                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01059         } else {
01060                 dcfg_data_t dcfg = {.d32 = 0 };
01061                 dcfg.d32 = core_if->dr_backup->dcfg;
01062                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
01063 
01064                 /* Load restore values for [31:14] bits */
01065                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01066                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01067                 if (!rmode) {
01068                         pcgcctl.d32 |= 0x208;
01069                 }
01070                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01071                 dwc_udelay(10);
01072 
01073                 /* Load restore values for [31:14] bits */
01074                 pcgcctl.d32 = gr->pcgcctl_local & 0xffffc000;
01075                 pcgcctl.d32 = gr->pcgcctl_local | 0x00020000;
01076                 pcgcctl.b.ess_reg_restored = 1;
01077                 if (!rmode)
01078                         pcgcctl.d32 |= 0x208;
01079                 DWC_WRITE_REG32(core_if->pcgcctl, pcgcctl.d32);
01080         }
01081 
01082         return 0;
01083 }
01084 
01089 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
01090 {
01091         uint32_t val;
01092         hcfg_data_t hcfg;
01093 
01094         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
01095              (core_if->hwcfg2.b.fs_phy_type == 1) &&
01096              (core_if->core_params->ulpi_fs_ls)) ||
01097             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01098                 /* Full speed PHY */
01099                 val = DWC_HCFG_48_MHZ;
01100         } else {
01101                 /* High speed PHY running at full speed or high speed */
01102                 val = DWC_HCFG_30_60_MHZ;
01103         }
01104 
01105         DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
01106         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
01107         hcfg.b.fslspclksel = val;
01108         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
01109 }
01110 
01115 static void init_devspd(dwc_otg_core_if_t * core_if)
01116 {
01117         uint32_t val;
01118         dcfg_data_t dcfg;
01119 
01120         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
01121              (core_if->hwcfg2.b.fs_phy_type == 1) &&
01122              (core_if->core_params->ulpi_fs_ls)) ||
01123             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01124                 /* Full speed PHY */
01125                 val = 0x3;
01126         } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
01127                 /* High speed PHY running at full speed */
01128                 val = 0x1;
01129         } else {
01130                 /* High speed PHY running at high speed */
01131                 val = 0x0;
01132         }
01133 
01134         DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
01135 
01136         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
01137         dcfg.b.devspd = val;
01138         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
01139 }
01140 
01147 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
01148 {
01149         uint32_t num_in_eps = 0;
01150         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
01151         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
01152         uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
01153         int i;
01154 
01155         for (i = 0; i < num_eps; ++i) {
01156                 if (!(hwcfg1 & 0x1))
01157                         num_in_eps++;
01158 
01159                 hwcfg1 >>= 2;
01160         }
01161 
01162         if (core_if->hwcfg4.b.ded_fifo_en) {
01163                 num_in_eps =
01164                     (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
01165         }
01166 
01167         return num_in_eps;
01168 }
01169 
01176 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
01177 {
01178         uint32_t num_out_eps = 0;
01179         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
01180         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
01181         int i;
01182 
01183         for (i = 0; i < num_eps; ++i) {
01184                 if (!(hwcfg1 & 0x1))
01185                         num_out_eps++;
01186 
01187                 hwcfg1 >>= 2;
01188         }
01189         return num_out_eps;
01190 }
01191 
01199 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
01200 {
01201         int i = 0;
01202         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01203         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01204         gahbcfg_data_t ahbcfg = {.d32 = 0 };
01205         gusbcfg_data_t usbcfg = {.d32 = 0 };
01206         gi2cctl_data_t i2cctl = {.d32 = 0 };
01207 
01208         DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
01209 
01210         /* Common Initialization */
01211         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01212 
01213         /* Program the ULPI External VBUS bit if needed */
01214         usbcfg.b.ulpi_ext_vbus_drv =
01215             (core_if->core_params->phy_ulpi_ext_vbus ==
01216              DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
01217 
01218         /* Set external TS Dline pulsing */
01219         usbcfg.b.term_sel_dl_pulse =
01220             (core_if->core_params->ts_dline == 1) ? 1 : 0;
01221         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01222 
01223         /* Reset the Controller */
01224         dwc_otg_core_reset(core_if);
01225 
01226         core_if->adp_enable = core_if->core_params->adp_supp_enable;
01227         core_if->power_down = core_if->core_params->power_down;
01228         core_if->otg_sts = 0;
01229 
01230         /* Initialize parameters from Hardware configuration registers. */
01231         dev_if->num_in_eps = calc_num_in_eps(core_if);
01232         dev_if->num_out_eps = calc_num_out_eps(core_if);
01233 
01234         DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
01235                     core_if->hwcfg4.b.num_dev_perio_in_ep);
01236 
01237         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
01238                 dev_if->perio_tx_fifo_size[i] =
01239                     DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
01240                 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
01241                             i, dev_if->perio_tx_fifo_size[i]);
01242         }
01243 
01244         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
01245                 dev_if->tx_fifo_size[i] =
01246                     DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
01247                 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
01248                             i, dev_if->tx_fifo_size[i]);
01249         }
01250 
01251         core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
01252         core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
01253         core_if->nperio_tx_fifo_size =
01254             DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
01255 
01256         DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
01257         DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
01258         DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
01259                     core_if->nperio_tx_fifo_size);
01260 
01261         /* This programming sequence needs to happen in FS mode before any other
01262          * programming occurs */
01263         if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
01264             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
01265                 /* If FS mode with FS PHY */
01266 
01267                 /* core_init() is now called on every switch so only call the
01268                  * following for the first time through. */
01269                 if (!core_if->phy_init_done) {
01270                         core_if->phy_init_done = 1;
01271                         DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
01272                         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01273                         usbcfg.b.physel = 1;
01274                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01275 
01276                         /* Reset after a PHY select */
01277                         dwc_otg_core_reset(core_if);
01278                 }
01279 
01280                 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
01281                  * do this on HNP Dev/Host mode switches (done in dev_init and
01282                  * host_init). */
01283                 if (dwc_otg_is_host_mode(core_if)) {
01284                         init_fslspclksel(core_if);
01285                 } else {
01286                         init_devspd(core_if);
01287                 }
01288 
01289                 if (core_if->core_params->i2c_enable) {
01290                         DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
01291                         /* Program GUSBCFG.OtgUtmifsSel to I2C */
01292                         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01293                         usbcfg.b.otgutmifssel = 1;
01294                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01295 
01296                         /* Program GI2CCTL.I2CEn */
01297                         i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
01298                         i2cctl.b.i2cdevaddr = 1;
01299                         i2cctl.b.i2cen = 0;
01300                         DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
01301                         i2cctl.b.i2cen = 1;
01302                         DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
01303                 }
01304 
01305         } /* endif speed == DWC_SPEED_PARAM_FULL */
01306         else {
01307                 /* High speed PHY. */
01308                 if (!core_if->phy_init_done) {
01309                         core_if->phy_init_done = 1;
01310                         /* HS PHY parameters.  These parameters are preserved
01311                          * during soft reset so only program the first time.  Do
01312                          * a soft reset immediately after setting phyif.  */
01313 
01314                         if (core_if->core_params->phy_type == 2) {
01315                                 /* ULPI interface */
01316                                 usbcfg.b.ulpi_utmi_sel = 1;
01317                                 usbcfg.b.phyif = 0;
01318                                 usbcfg.b.ddrsel =
01319                                     core_if->core_params->phy_ulpi_ddr;
01320                         } else if (core_if->core_params->phy_type == 1) {
01321                                 /* UTMI+ interface */
01322                                 usbcfg.b.ulpi_utmi_sel = 0;
01323                                 if (core_if->core_params->phy_utmi_width == 16) {
01324                                         usbcfg.b.phyif = 1;
01325 
01326                                 } else {
01327                                         usbcfg.b.phyif = 0;
01328                                 }
01329                         } else {
01330                                 DWC_ERROR("FS PHY TYPE\n");
01331                         }
01332                         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01333                         /* Reset after setting the PHY parameters */
01334                         dwc_otg_core_reset(core_if);
01335                 }
01336         }
01337 
01338         if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
01339             (core_if->hwcfg2.b.fs_phy_type == 1) &&
01340             (core_if->core_params->ulpi_fs_ls)) {
01341                 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
01342                 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01343                 usbcfg.b.ulpi_fsls = 1;
01344                 usbcfg.b.ulpi_clk_sus_m = 1;
01345                 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01346         } else {
01347                 usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01348                 usbcfg.b.ulpi_fsls = 0;
01349                 usbcfg.b.ulpi_clk_sus_m = 0;
01350                 DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01351         }
01352 
01353         /* Program the GAHBCFG Register. */
01354         switch (core_if->hwcfg2.b.architecture) {
01355 
01356         case DWC_SLAVE_ONLY_ARCH:
01357                 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
01358                 ahbcfg.b.nptxfemplvl_txfemplvl =
01359                     DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
01360                 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
01361                 core_if->dma_enable = 0;
01362                 core_if->dma_desc_enable = 0;
01363                 break;
01364 
01365         case DWC_EXT_DMA_ARCH:
01366                 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
01367                 {
01368                         uint8_t brst_sz = core_if->core_params->dma_burst_size;
01369                         ahbcfg.b.hburstlen = 0;
01370                         while (brst_sz > 1) {
01371                                 ahbcfg.b.hburstlen++;
01372                                 brst_sz >>= 1;
01373                         }
01374                 }
01375                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
01376                 core_if->dma_desc_enable =
01377                     (core_if->core_params->dma_desc_enable != 0);
01378                 break;
01379 
01380         case DWC_INT_DMA_ARCH:
01381                 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
01382                 /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for 
01383                   Host mode ISOC in issue fix - vahrama */
01384                 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR4;
01385                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
01386                 core_if->dma_desc_enable =
01387                     (core_if->core_params->dma_desc_enable != 0);
01388                 break;
01389 
01390         }
01391         if (core_if->dma_enable) {
01392                 if (core_if->dma_desc_enable) {
01393                         DWC_PRINTF("Using Descriptor DMA mode\n");
01394                 } else {
01395                         DWC_PRINTF("Using Buffer DMA mode\n");
01396 
01397                 }
01398         } else {
01399                 DWC_PRINTF("Using Slave mode\n");
01400                 core_if->dma_desc_enable = 0;
01401         }
01402 
01403         if (core_if->core_params->ahb_single) {
01404                 ahbcfg.b.ahbsingle = 1;
01405         }
01406         
01407         ahbcfg.b.dmaenable = core_if->dma_enable;
01408         DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
01409 
01410         core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
01411 
01412         core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
01413         core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
01414         DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
01415                    ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
01416         DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
01417                    ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
01418 
01419         /*
01420          * Program the GUSBCFG register.
01421          */
01422         usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
01423 
01424         switch (core_if->hwcfg2.b.op_mode) {
01425         case DWC_MODE_HNP_SRP_CAPABLE:
01426                 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
01427                                    DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
01428                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01429                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01430                 break;
01431 
01432         case DWC_MODE_SRP_ONLY_CAPABLE:
01433                 usbcfg.b.hnpcap = 0;
01434                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01435                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01436                 break;
01437 
01438         case DWC_MODE_NO_HNP_SRP_CAPABLE:
01439                 usbcfg.b.hnpcap = 0;
01440                 usbcfg.b.srpcap = 0;
01441                 break;
01442 
01443         case DWC_MODE_SRP_CAPABLE_DEVICE:
01444                 usbcfg.b.hnpcap = 0;
01445                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01446                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01447                 break;
01448 
01449         case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
01450                 usbcfg.b.hnpcap = 0;
01451                 usbcfg.b.srpcap = 0;
01452                 break;
01453 
01454         case DWC_MODE_SRP_CAPABLE_HOST:
01455                 usbcfg.b.hnpcap = 0;
01456                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
01457                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
01458                 break;
01459 
01460         case DWC_MODE_NO_SRP_CAPABLE_HOST:
01461                 usbcfg.b.hnpcap = 0;
01462                 usbcfg.b.srpcap = 0;
01463                 break;
01464         }
01465 
01466         DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
01467 
01468 #ifdef CONFIG_USB_DWC_OTG_LPM
01469         if (core_if->core_params->lpm_enable) {
01470                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
01471 
01472                 /* To enable LPM support set lpm_cap_en bit */
01473                 lpmcfg.b.lpm_cap_en = 1;
01474 
01475                 /* Make AppL1Res ACK */
01476                 lpmcfg.b.appl_resp = 1;
01477 
01478                 /* Retry 3 times */
01479                 lpmcfg.b.retry_count = 3;
01480 
01481                 DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
01482                                  0, lpmcfg.d32);
01483 
01484         }
01485 #endif
01486         if (core_if->core_params->ic_usb_cap) {
01487                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
01488                 gusbcfg.b.ic_usb_cap = 1;
01489                 DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
01490                                  0, gusbcfg.d32);
01491         }
01492         {
01493                 gotgctl_data_t gotgctl = {.d32 = 0 };
01494                 gotgctl.b.otgver = core_if->core_params->otg_ver;
01495                 DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
01496                                  gotgctl.d32);
01497                 /* Set OTG version supported */
01498                 core_if->otg_ver = core_if->core_params->otg_ver;
01499                 DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
01500                            core_if->core_params->otg_ver, core_if->otg_ver);
01501         }
01502         
01503 
01504         /* Enable common interrupts */
01505         dwc_otg_enable_common_interrupts(core_if);
01506 
01507         /* Do device or host intialization based on mode during PCD
01508          * and HCD initialization  */
01509         if (dwc_otg_is_host_mode(core_if)) {
01510                 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
01511                 core_if->op_state = A_HOST;
01512         } else {
01513                 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
01514                 core_if->op_state = B_PERIPHERAL;
01515 #ifdef DWC_DEVICE_ONLY
01516                 dwc_otg_core_dev_init(core_if);
01517 #endif
01518         }
01519 }
01520 
01526 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
01527 {
01528         gintmsk_data_t intr_mask = {.d32 = 0 };
01529         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01530 
01531         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
01532 
01533         /* Disable all interrupts. */
01534         DWC_WRITE_REG32(&global_regs->gintmsk, 0);
01535 
01536         /* Clear any pending interrupts */
01537         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
01538 
01539         /* Enable the common interrupts */
01540         dwc_otg_enable_common_interrupts(core_if);
01541 
01542         /* Enable interrupts */
01543         intr_mask.b.usbreset = 1;
01544         intr_mask.b.enumdone = 1;
01545         /* Disable Disconnect interrupt in Device mode */
01546         intr_mask.b.disconnect = 0;
01547 
01548         if (!core_if->multiproc_int_enable) {
01549                 intr_mask.b.inepintr = 1;
01550                 intr_mask.b.outepintr = 1;
01551         }
01552 
01553         intr_mask.b.erlysuspend = 1;
01554 
01555         if (core_if->en_multiple_tx_fifo == 0) {
01556                 intr_mask.b.epmismatch = 1;
01557         }
01558 
01559         //intr_mask.b.incomplisoout = 1;
01560         intr_mask.b.incomplisoin = 1;
01561         
01562 /* Enable the ignore frame number for ISOC xfers - MAS */
01563 /* Disable to support high bandwith ISOC transfers - manukz */
01564 #if 0
01565 #ifdef DWC_UTE_PER_IO
01566         if (core_if->dma_enable) {
01567                 if (core_if->dma_desc_enable) {
01568                         dctl_data_t dctl1 = {.d32 = 0 };
01569                         dctl1.b.ifrmnum = 1;
01570                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->
01571                                          dctl, 0, dctl1.d32);
01572                         DWC_DEBUG("----Enabled Ignore frame number (0x%08x)",
01573                                   DWC_READ_REG32(&core_if->dev_if->
01574                                                  dev_global_regs->dctl));
01575                 }
01576         }
01577 #endif
01578 #endif
01579 #ifdef DWC_EN_ISOC
01580         if (core_if->dma_enable) {
01581                 if (core_if->dma_desc_enable == 0) {
01582                         if (core_if->pti_enh_enable) {
01583                                 dctl_data_t dctl = {.d32 = 0 };
01584                                 dctl.b.ifrmnum = 1;
01585                                 DWC_MODIFY_REG32(&core_if->
01586                                                  dev_if->dev_global_regs->dctl,
01587                                                  0, dctl.d32);
01588                         } else {
01589                                 intr_mask.b.incomplisoin = 1;
01590                                 intr_mask.b.incomplisoout = 1;
01591                         }
01592                 }
01593         } else {
01594                 intr_mask.b.incomplisoin = 1;
01595                 intr_mask.b.incomplisoout = 1;
01596         }
01597 #endif /* DWC_EN_ISOC */
01598 
01600 #ifdef USE_PERIODIC_EP
01601         intr_mask.b.isooutdrop = 1;
01602         intr_mask.b.eopframe = 1;
01603         intr_mask.b.incomplisoin = 1;
01604         intr_mask.b.incomplisoout = 1;
01605 #endif
01606 
01607         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
01608 
01609         DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
01610                     DWC_READ_REG32(&global_regs->gintmsk));
01611 }
01612 
01620 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
01621 {
01622         int i;
01623         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01624         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
01625         dwc_otg_core_params_t *params = core_if->core_params;
01626         dcfg_data_t dcfg = {.d32 = 0 };
01627         depctl_data_t diepctl = {.d32 = 0 };
01628         grstctl_t resetctl = {.d32 = 0 };
01629         uint32_t rx_fifo_size;
01630         fifosize_data_t nptxfifosize;
01631         fifosize_data_t txfifosize;
01632         dthrctl_data_t dthrctl;
01633         fifosize_data_t ptxfifosize;
01634         uint16_t rxfsiz, nptxfsiz;
01635         gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
01636         hwcfg3_data_t hwcfg3 = {.d32 = 0 };
01637 
01638         /* Restart the Phy Clock */
01639         DWC_WRITE_REG32(core_if->pcgcctl, 0);
01640 
01641         /* Device configuration register */
01642         init_devspd(core_if);
01643         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
01644         dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
01645         dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
01646         /* Enable Device OUT NAK in case of DDMA mode*/
01647         if (core_if->core_params->dev_out_nak) {
01648                 dcfg.b.endevoutnak = 1;         
01649         }
01650 
01651         if (core_if->core_params->cont_on_bna) {
01652                 dctl_data_t dctl = {.d32 = 0 };
01653                 dctl.b.encontonbna = 1;
01654                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
01655         }
01656         
01657 
01658         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
01659 
01660         /* Configure data FIFO sizes */
01661         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
01662                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
01663                             core_if->total_fifo_size);
01664                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
01665                             params->dev_rx_fifo_size);
01666                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
01667                             params->dev_nperio_tx_fifo_size);
01668 
01669                 /* Rx FIFO */
01670                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
01671                             DWC_READ_REG32(&global_regs->grxfsiz));
01672 
01673 #ifdef DWC_UTE_CFI
01674                 core_if->pwron_rxfsiz = DWC_READ_REG32(&global_regs->grxfsiz);
01675                 core_if->init_rxfsiz = params->dev_rx_fifo_size;
01676 #endif
01677                 rx_fifo_size = params->dev_rx_fifo_size;
01678                 DWC_WRITE_REG32(&global_regs->grxfsiz, rx_fifo_size);
01679 
01680                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
01681                             DWC_READ_REG32(&global_regs->grxfsiz));
01682 
01684                 core_if->p_tx_msk = 0;
01685 
01687                 core_if->tx_msk = 0;
01688 
01689                 if (core_if->en_multiple_tx_fifo == 0) {
01690                         /* Non-periodic Tx FIFO */
01691                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
01692                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
01693 
01694                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
01695                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
01696 
01697                         DWC_WRITE_REG32(&global_regs->gnptxfsiz,
01698                                         nptxfifosize.d32);
01699 
01700                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
01701                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
01702 
01704                         /*
01705                          * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
01706                          * Indexes of the FIFO size module parameters in the
01707                          * dev_perio_tx_fifo_size array and the FIFO size registers in
01708                          * the dptxfsiz array run from 0 to 14.
01709                          */
01711                         ptxfifosize.b.startaddr =
01712                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
01713                         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
01714                                 ptxfifosize.b.depth =
01715                                     params->dev_perio_tx_fifo_size[i];
01716                                 DWC_DEBUGPL(DBG_CIL,
01717                                             "initial dtxfsiz[%d]=%08x\n", i,
01718                                             DWC_READ_REG32(&global_regs->dtxfsiz
01719                                                            [i]));
01720                                 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
01721                                                 ptxfifosize.d32);
01722                                 DWC_DEBUGPL(DBG_CIL, "new dtxfsiz[%d]=%08x\n",
01723                                             i,
01724                                             DWC_READ_REG32(&global_regs->dtxfsiz
01725                                                            [i]));
01726                                 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
01727                         }
01728                 } else {
01729                         /*
01730                          * Tx FIFOs These FIFOs are numbered from 1 to 15.
01731                          * Indexes of the FIFO size module parameters in the
01732                          * dev_tx_fifo_size array and the FIFO size registers in
01733                          * the dtxfsiz array run from 0 to 14.
01734                          */
01735 
01736                         /* Non-periodic Tx FIFO */
01737                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
01738                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
01739 
01740 #ifdef DWC_UTE_CFI
01741                         core_if->pwron_gnptxfsiz =
01742                             (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
01743                         core_if->init_gnptxfsiz =
01744                             params->dev_nperio_tx_fifo_size;
01745 #endif
01746                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
01747                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
01748 
01749                         DWC_WRITE_REG32(&global_regs->gnptxfsiz,
01750                                         nptxfifosize.d32);
01751 
01752                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
01753                                     DWC_READ_REG32(&global_regs->gnptxfsiz));
01754 
01755                         txfifosize.b.startaddr =
01756                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
01757 
01758                         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
01759 
01760                                 txfifosize.b.depth =
01761                                     params->dev_tx_fifo_size[i];
01762 
01763                                 DWC_DEBUGPL(DBG_CIL,
01764                                             "initial dtxfsiz[%d]=%08x\n",
01765                                             i,
01766                                             DWC_READ_REG32(&global_regs->dtxfsiz
01767                                                            [i]));
01768 
01769 #ifdef DWC_UTE_CFI
01770                                 core_if->pwron_txfsiz[i] =
01771                                     (DWC_READ_REG32
01772                                      (&global_regs->dtxfsiz[i]) >> 16);
01773                                 core_if->init_txfsiz[i] =
01774                                     params->dev_tx_fifo_size[i];
01775 #endif
01776                                 DWC_WRITE_REG32(&global_regs->dtxfsiz[i],
01777                                                 txfifosize.d32);
01778 
01779                                 DWC_DEBUGPL(DBG_CIL,
01780                                             "new dtxfsiz[%d]=%08x\n",
01781                                             i,
01782                                             DWC_READ_REG32(&global_regs->dtxfsiz
01783                                                            [i]));
01784 
01785                                 txfifosize.b.startaddr += txfifosize.b.depth;
01786                         }
01787                         /* Calculating DFIFOCFG for Device mode to include RxFIFO and NPTXFIFO */
01788                         gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
01789                         hwcfg3.d32 = DWC_READ_REG32(&global_regs->ghwcfg3);
01790                         gdfifocfg.b.gdfifocfg = (DWC_READ_REG32(&global_regs->ghwcfg3) >> 16);
01791                         DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
01792                         rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
01793                         nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
01794                         gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz;
01795                         DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
01796                 }
01797         }
01798 
01799         /* Flush the FIFOs */
01800         dwc_otg_flush_tx_fifo(core_if, 0x10);   /* all Tx FIFOs */
01801         dwc_otg_flush_rx_fifo(core_if);
01802 
01803         /* Flush the Learning Queue. */
01804         resetctl.b.intknqflsh = 1;
01805         DWC_WRITE_REG32(&core_if->core_global_regs->grstctl, resetctl.d32);
01806 
01807         if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable) {
01808                 core_if->start_predict = 0;
01809                 for (i = 0; i<= core_if->dev_if->num_in_eps; ++i) {
01810                         core_if->nextep_seq[i] = 0xff;  // 0xff - EP not active
01811                 }
01812                 core_if->nextep_seq[0] = 0;     
01813                 core_if->first_in_nextep_seq = 0;
01814                 diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
01815                 diepctl.b.nextep = 0;
01816                 DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
01817                 
01818                 /* Update IN Endpoint Mismatch Count by active IN NP EP count + 1 */
01819                 dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
01820                 dcfg.b.epmscnt = 2;
01821                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
01822 
01823                 DWC_DEBUGPL(DBG_CILV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n", 
01824                         __func__, core_if->first_in_nextep_seq);
01825                 for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
01826                         DWC_DEBUGPL(DBG_CILV, "%2d ", core_if->nextep_seq[i]);
01827                 }
01828                 DWC_DEBUGPL(DBG_CILV,"\n");
01829         }
01830         
01831         /* Clear all pending Device Interrupts */
01835         if (core_if->multiproc_int_enable) {
01836                 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
01837                         DWC_WRITE_REG32(&dev_if->
01838                                         dev_global_regs->diepeachintmsk[i], 0);
01839                 }
01840 
01841                 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
01842                         DWC_WRITE_REG32(&dev_if->
01843                                         dev_global_regs->doepeachintmsk[i], 0);
01844                 }
01845 
01846                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
01847                 DWC_WRITE_REG32(&dev_if->dev_global_regs->deachintmsk, 0);
01848         } else {
01849                 DWC_WRITE_REG32(&dev_if->dev_global_regs->diepmsk, 0);
01850                 DWC_WRITE_REG32(&dev_if->dev_global_regs->doepmsk, 0);
01851                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
01852                 DWC_WRITE_REG32(&dev_if->dev_global_regs->daintmsk, 0);
01853         }
01854 
01855         for (i = 0; i <= dev_if->num_in_eps; i++) {
01856                 depctl_data_t depctl;
01857                 depctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[i]->diepctl);
01858                 if (depctl.b.epena) {
01859                         depctl.d32 = 0;
01860                         depctl.b.epdis = 1;
01861                         depctl.b.snak = 1;
01862                 } else {
01863                         depctl.d32 = 0;
01864                 }
01865 
01866                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
01867 
01868                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
01869                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepdma, 0);
01870                 DWC_WRITE_REG32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
01871         }
01872 
01873         for (i = 0; i <= dev_if->num_out_eps; i++) {
01874                 depctl_data_t depctl;
01875                 depctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[i]->doepctl);
01876                 if (depctl.b.epena) {
01877                         depctl.d32 = 0;
01878                         depctl.b.epdis = 1;
01879                         depctl.b.snak = 1;
01880                 } else {
01881                         depctl.d32 = 0;
01882                 }
01883 
01884                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
01885 
01886                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
01887                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepdma, 0);
01888                 DWC_WRITE_REG32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
01889         }
01890 
01891         if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
01892                 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
01893                 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
01894                 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
01895 
01896                 dev_if->rx_thr_length = params->rx_thr_length;
01897                 dev_if->tx_thr_length = params->tx_thr_length;
01898 
01899                 dev_if->setup_desc_index = 0;
01900 
01901                 dthrctl.d32 = 0;
01902                 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
01903                 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
01904                 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
01905                 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
01906                 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
01907                 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
01908 
01909                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
01910                                 dthrctl.d32);
01911 
01912                 DWC_DEBUGPL(DBG_CIL,
01913                             "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
01914                             dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
01915                             dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
01916                             dthrctl.b.rx_thr_len);
01917 
01918         }
01919 
01920         dwc_otg_enable_device_interrupts(core_if);
01921 
01922         {
01923                 diepmsk_data_t msk = {.d32 = 0 };
01924                 msk.b.txfifoundrn = 1;
01925                 if (core_if->multiproc_int_enable) {
01926                         DWC_MODIFY_REG32(&dev_if->
01927                                          dev_global_regs->diepeachintmsk[0],
01928                                          msk.d32, msk.d32);
01929                 } else {
01930                         DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk,
01931                                          msk.d32, msk.d32);
01932                 }
01933         }
01934 
01935         if (core_if->multiproc_int_enable) {
01936                 /* Set NAK on Babble */
01937                 dctl_data_t dctl = {.d32 = 0 };
01938                 dctl.b.nakonbble = 1;
01939                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
01940         }
01941 
01942         if (core_if->snpsid >= OTG_CORE_REV_2_94a) {
01943                 dctl_data_t dctl = {.d32 = 0 };
01944                 dctl.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dctl);
01945                 dctl.b.sftdiscon = 0;
01946                 DWC_WRITE_REG32(&dev_if->dev_global_regs->dctl, dctl.d32);
01947         }
01948 }
01949 
01955 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
01956 {
01957         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01958         gintmsk_data_t intr_mask = {.d32 = 0 };
01959 
01960         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
01961 
01962         /* Disable all interrupts. */
01963         DWC_WRITE_REG32(&global_regs->gintmsk, 0);
01964 
01965         /* Clear any pending interrupts. */
01966         DWC_WRITE_REG32(&global_regs->gintsts, 0xFFFFFFFF);
01967 
01968         /* Enable the common interrupts */
01969         dwc_otg_enable_common_interrupts(core_if);
01970 
01971         /*
01972          * Enable host mode interrupts without disturbing common
01973          * interrupts.
01974          */
01975 
01976         intr_mask.b.disconnect = 1;
01977         intr_mask.b.portintr = 1;
01978         intr_mask.b.hcintr = 1;
01979 
01980         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
01981 }
01982 
01988 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
01989 {
01990         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01991         gintmsk_data_t intr_mask = {.d32 = 0 };
01992 
01993         DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
01994 
01995         /*
01996          * Disable host mode interrupts without disturbing common
01997          * interrupts.
01998          */
01999         intr_mask.b.sofintr = 1;
02000         intr_mask.b.portintr = 1;
02001         intr_mask.b.hcintr = 1;
02002         intr_mask.b.ptxfempty = 1;
02003         intr_mask.b.nptxfempty = 1;
02004 
02005         DWC_MODIFY_REG32(&global_regs->gintmsk, intr_mask.d32, 0);
02006 }
02007 
02019 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
02020 {
02021         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
02022         dwc_otg_host_if_t *host_if = core_if->host_if;
02023         dwc_otg_core_params_t *params = core_if->core_params;
02024         hprt0_data_t hprt0 = {.d32 = 0 };
02025         fifosize_data_t nptxfifosize;
02026         fifosize_data_t ptxfifosize;
02027         uint16_t rxfsiz, nptxfsiz, hptxfsiz;
02028         gdfifocfg_data_t gdfifocfg = {.d32 = 0 };
02029         int i;
02030         hcchar_data_t hcchar;
02031         hcfg_data_t hcfg;
02032         hfir_data_t hfir;
02033         dwc_otg_hc_regs_t *hc_regs;
02034         int num_channels;
02035         gotgctl_data_t gotgctl = {.d32 = 0 };
02036 
02037         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
02038 
02039         /* Restart the Phy Clock */
02040         DWC_WRITE_REG32(core_if->pcgcctl, 0);
02041 
02042         /* Initialize Host Configuration Register */
02043         init_fslspclksel(core_if);
02044         if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
02045                 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
02046                 hcfg.b.fslssupp = 1;
02047                 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
02048 
02049         }
02050 
02051         /* This bit allows dynamic reloading of the HFIR register
02052          * during runtime. This bit needs to be programmed during 
02053          * initial configuration and its value must not be changed
02054          * during runtime.*/
02055         if (core_if->core_params->reload_ctl == 1) {
02056                 hfir.d32 = DWC_READ_REG32(&host_if->host_global_regs->hfir);
02057                 hfir.b.hfirrldctrl = 1;
02058                 DWC_WRITE_REG32(&host_if->host_global_regs->hfir, hfir.d32);
02059         }
02060 
02061         if (core_if->core_params->dma_desc_enable) {
02062                 uint8_t op_mode = core_if->hwcfg2.b.op_mode;
02063                 if (!
02064                     (core_if->hwcfg4.b.desc_dma
02065                      && (core_if->snpsid >= OTG_CORE_REV_2_90a)
02066                      && ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
02067                          || (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
02068                          || (op_mode ==
02069                              DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG)
02070                          || (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)
02071                          || (op_mode ==
02072                              DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
02073 
02074                         DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
02075                                   "Either core version is below 2.90a or "
02076                                   "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
02077                                   "To run the driver in Buffer DMA host mode set dma_desc_enable "
02078                                   "module parameter to 0.\n");
02079                         return;
02080                 }
02081                 hcfg.d32 = DWC_READ_REG32(&host_if->host_global_regs->hcfg);
02082                 hcfg.b.descdma = 1;
02083                 DWC_WRITE_REG32(&host_if->host_global_regs->hcfg, hcfg.d32);
02084         }
02085 
02086         /* Configure data FIFO sizes */
02087         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
02088                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
02089                             core_if->total_fifo_size);
02090                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
02091                             params->host_rx_fifo_size);
02092                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
02093                             params->host_nperio_tx_fifo_size);
02094                 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
02095                             params->host_perio_tx_fifo_size);
02096 
02097                 /* Rx FIFO */
02098                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
02099                             DWC_READ_REG32(&global_regs->grxfsiz));
02100                 DWC_WRITE_REG32(&global_regs->grxfsiz,
02101                                 params->host_rx_fifo_size);
02102                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
02103                             DWC_READ_REG32(&global_regs->grxfsiz));
02104 
02105                 /* Non-periodic Tx FIFO */
02106                 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
02107                             DWC_READ_REG32(&global_regs->gnptxfsiz));
02108                 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
02109                 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
02110                 DWC_WRITE_REG32(&global_regs->gnptxfsiz, nptxfifosize.d32);
02111                 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
02112                             DWC_READ_REG32(&global_regs->gnptxfsiz));
02113 
02114                 /* Periodic Tx FIFO */
02115                 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
02116                             DWC_READ_REG32(&global_regs->hptxfsiz));
02117                 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
02118                 ptxfifosize.b.startaddr =
02119                     nptxfifosize.b.startaddr + nptxfifosize.b.depth;
02120                 DWC_WRITE_REG32(&global_regs->hptxfsiz, ptxfifosize.d32);
02121                 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
02122                             DWC_READ_REG32(&global_regs->hptxfsiz));
02123                 
02124                 if (core_if->en_multiple_tx_fifo) {
02125                         /* Global DFIFOCFG calculation for Host mode - include RxFIFO, NPTXFIFO and HPTXFIFO */
02126                         gdfifocfg.d32 = DWC_READ_REG32(&global_regs->gdfifocfg);
02127                         rxfsiz = (DWC_READ_REG32(&global_regs->grxfsiz) & 0x0000ffff);
02128                         nptxfsiz = (DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16);
02129                         hptxfsiz = (DWC_READ_REG32(&global_regs->hptxfsiz) >> 16);
02130                         gdfifocfg.b.epinfobase = rxfsiz + nptxfsiz + hptxfsiz;
02131                         DWC_WRITE_REG32(&global_regs->gdfifocfg, gdfifocfg.d32);
02132                 }
02133         }
02134 
02135         /* TODO - check this */
02136         /* Clear Host Set HNP Enable in the OTG Control Register */
02137         gotgctl.b.hstsethnpen = 1;
02138         DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
02139         /* Make sure the FIFOs are flushed. */
02140         dwc_otg_flush_tx_fifo(core_if, 0x10 /* all TX FIFOs */ );
02141         dwc_otg_flush_rx_fifo(core_if);
02142 
02143         /* Clear Host Set HNP Enable in the OTG Control Register */
02144         gotgctl.b.hstsethnpen = 1;
02145         DWC_MODIFY_REG32(&global_regs->gotgctl, gotgctl.d32, 0);
02146 
02147         if (!core_if->core_params->dma_desc_enable) {
02148                 /* Flush out any leftover queued requests. */
02149                 num_channels = core_if->core_params->host_channels;
02150 
02151                 for (i = 0; i < num_channels; i++) {
02152                         hc_regs = core_if->host_if->hc_regs[i];
02153                         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02154                         hcchar.b.chen = 0;
02155                         hcchar.b.chdis = 1;
02156                         hcchar.b.epdir = 0;
02157                         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02158                 }
02159 
02160                 /* Halt all channels to put them into a known state. */
02161                 for (i = 0; i < num_channels; i++) {
02162                         int count = 0;
02163                         hc_regs = core_if->host_if->hc_regs[i];
02164                         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02165                         hcchar.b.chen = 1;
02166                         hcchar.b.chdis = 1;
02167                         hcchar.b.epdir = 0;
02168                         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02169                         DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
02170                         do {
02171                                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02172                                 if (++count > 1000) {
02173                                         DWC_ERROR
02174                                             ("%s: Unable to clear halt on channel %d\n",
02175                                              __func__, i);
02176                                         break;
02177                                 }
02178                                 dwc_udelay(1);
02179                         } while (hcchar.b.chen);
02180                 }
02181         }
02182 
02183         /* Turn on the vbus power. */
02184         DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
02185         if (core_if->op_state == A_HOST) {
02186                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
02187                 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
02188                 if (hprt0.b.prtpwr == 0) {
02189                         hprt0.b.prtpwr = 1;
02190                         DWC_WRITE_REG32(host_if->hprt0, hprt0.d32);
02191                 }
02192         }
02193 
02194         dwc_otg_enable_host_interrupts(core_if);
02195 }
02196 
02206 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02207 {
02208         uint32_t intr_enable;
02209         hcintmsk_data_t hc_intr_mask;
02210         gintmsk_data_t gintmsk = {.d32 = 0 };
02211         hcchar_data_t hcchar;
02212         hcsplt_data_t hcsplt;
02213 
02214         uint8_t hc_num = hc->hc_num;
02215         dwc_otg_host_if_t *host_if = core_if->host_if;
02216         dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
02217 
02218         /* Clear old interrupt conditions for this host channel. */
02219         hc_intr_mask.d32 = 0xFFFFFFFF;
02220         hc_intr_mask.b.reserved14_31 = 0;
02221         DWC_WRITE_REG32(&hc_regs->hcint, hc_intr_mask.d32);
02222 
02223         /* Enable channel interrupts required for this transfer. */
02224         hc_intr_mask.d32 = 0;
02225         hc_intr_mask.b.chhltd = 1;
02226         if (core_if->dma_enable) {
02227                 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
02228                 if (!core_if->dma_desc_enable)
02229                         hc_intr_mask.b.ahberr = 1;
02230                 else {
02231                         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02232                                 hc_intr_mask.b.xfercompl = 1;
02233                 }
02234 
02235                 if (hc->error_state && !hc->do_split &&
02236                     hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
02237                         hc_intr_mask.b.ack = 1;
02238                         if (hc->ep_is_in) {
02239                                 hc_intr_mask.b.datatglerr = 1;
02240                                 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
02241                                         hc_intr_mask.b.nak = 1;
02242                                 }
02243                         }
02244                 }
02245         } else {
02246                 switch (hc->ep_type) {
02247                 case DWC_OTG_EP_TYPE_CONTROL:
02248                 case DWC_OTG_EP_TYPE_BULK:
02249                         hc_intr_mask.b.xfercompl = 1;
02250                         hc_intr_mask.b.stall = 1;
02251                         hc_intr_mask.b.xacterr = 1;
02252                         hc_intr_mask.b.datatglerr = 1;
02253                         if (hc->ep_is_in) {
02254                                 hc_intr_mask.b.bblerr = 1;
02255                         } else {
02256                                 hc_intr_mask.b.nak = 1;
02257                                 hc_intr_mask.b.nyet = 1;
02258                                 if (hc->do_ping) {
02259                                         hc_intr_mask.b.ack = 1;
02260                                 }
02261                         }
02262 
02263                         if (hc->do_split) {
02264                                 hc_intr_mask.b.nak = 1;
02265                                 if (hc->complete_split) {
02266                                         hc_intr_mask.b.nyet = 1;
02267                                 } else {
02268                                         hc_intr_mask.b.ack = 1;
02269                                 }
02270                         }
02271 
02272                         if (hc->error_state) {
02273                                 hc_intr_mask.b.ack = 1;
02274                         }
02275                         break;
02276                 case DWC_OTG_EP_TYPE_INTR:
02277                         hc_intr_mask.b.xfercompl = 1;
02278                         hc_intr_mask.b.nak = 1;
02279                         hc_intr_mask.b.stall = 1;
02280                         hc_intr_mask.b.xacterr = 1;
02281                         hc_intr_mask.b.datatglerr = 1;
02282                         hc_intr_mask.b.frmovrun = 1;
02283 
02284                         if (hc->ep_is_in) {
02285                                 hc_intr_mask.b.bblerr = 1;
02286                         }
02287                         if (hc->error_state) {
02288                                 hc_intr_mask.b.ack = 1;
02289                         }
02290                         if (hc->do_split) {
02291                                 if (hc->complete_split) {
02292                                         hc_intr_mask.b.nyet = 1;
02293                                 } else {
02294                                         hc_intr_mask.b.ack = 1;
02295                                 }
02296                         }
02297                         break;
02298                 case DWC_OTG_EP_TYPE_ISOC:
02299                         hc_intr_mask.b.xfercompl = 1;
02300                         hc_intr_mask.b.frmovrun = 1;
02301                         hc_intr_mask.b.ack = 1;
02302 
02303                         if (hc->ep_is_in) {
02304                                 hc_intr_mask.b.xacterr = 1;
02305                                 hc_intr_mask.b.bblerr = 1;
02306                         }
02307                         break;
02308                 }
02309         }
02310         DWC_WRITE_REG32(&hc_regs->hcintmsk, hc_intr_mask.d32);
02311 
02312         /* Enable the top level host channel interrupt. */
02313         intr_enable = (1 << hc_num);
02314         DWC_MODIFY_REG32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
02315 
02316         /* Make sure host channel interrupts are enabled. */
02317         gintmsk.b.hcintr = 1;
02318         DWC_MODIFY_REG32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
02319 
02320         /*
02321          * Program the HCCHARn register with the endpoint characteristics for
02322          * the current transfer.
02323          */
02324         hcchar.d32 = 0;
02325         hcchar.b.devaddr = hc->dev_addr;
02326         hcchar.b.epnum = hc->ep_num;
02327         hcchar.b.epdir = hc->ep_is_in;
02328         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
02329         hcchar.b.eptype = hc->ep_type;
02330         hcchar.b.mps = hc->max_packet;
02331 
02332         DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
02333 
02334         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02335         DWC_DEBUGPL(DBG_HCDV, "  Dev Addr: %d\n", hcchar.b.devaddr);
02336         DWC_DEBUGPL(DBG_HCDV, "  Ep Num: %d\n", hcchar.b.epnum);
02337         DWC_DEBUGPL(DBG_HCDV, "  Is In: %d\n", hcchar.b.epdir);
02338         DWC_DEBUGPL(DBG_HCDV, "  Is Low Speed: %d\n", hcchar.b.lspddev);
02339         DWC_DEBUGPL(DBG_HCDV, "  Ep Type: %d\n", hcchar.b.eptype);
02340         DWC_DEBUGPL(DBG_HCDV, "  Max Pkt: %d\n", hcchar.b.mps);
02341         DWC_DEBUGPL(DBG_HCDV, "  Multi Cnt: %d\n", hcchar.b.multicnt);
02342 
02343         /*
02344          * Program the HCSPLIT register for SPLITs
02345          */
02346         hcsplt.d32 = 0;
02347         if (hc->do_split) {
02348                 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
02349                             hc->hc_num,
02350                             hc->complete_split ? "CSPLIT" : "SSPLIT");
02351                 hcsplt.b.compsplt = hc->complete_split;
02352                 hcsplt.b.xactpos = hc->xact_pos;
02353                 hcsplt.b.hubaddr = hc->hub_addr;
02354                 hcsplt.b.prtaddr = hc->port_addr;
02355                 DWC_DEBUGPL(DBG_HCDV, "   comp split %d\n", hc->complete_split);
02356                 DWC_DEBUGPL(DBG_HCDV, "   xact pos %d\n", hc->xact_pos);
02357                 DWC_DEBUGPL(DBG_HCDV, "   hub addr %d\n", hc->hub_addr);
02358                 DWC_DEBUGPL(DBG_HCDV, "   port addr %d\n", hc->port_addr);
02359                 DWC_DEBUGPL(DBG_HCDV, "   is_in %d\n", hc->ep_is_in);
02360                 DWC_DEBUGPL(DBG_HCDV, "   Max Pkt: %d\n", hcchar.b.mps);
02361                 DWC_DEBUGPL(DBG_HCDV, "   xferlen: %d\n", hc->xfer_len);
02362         }
02363         DWC_WRITE_REG32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
02364 
02365 }
02366 
02394 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
02395                      dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
02396 {
02397         gnptxsts_data_t nptxsts;
02398         hptxsts_data_t hptxsts;
02399         hcchar_data_t hcchar;
02400         dwc_otg_hc_regs_t *hc_regs;
02401         dwc_otg_core_global_regs_t *global_regs;
02402         dwc_otg_host_global_regs_t *host_global_regs;
02403 
02404         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02405         global_regs = core_if->core_global_regs;
02406         host_global_regs = core_if->host_if->host_global_regs;
02407 
02408         DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
02409                    "halt_status = %d\n", halt_status);
02410 
02411         if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
02412             halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
02413                 /*
02414                  * Disable all channel interrupts except Ch Halted. The QTD
02415                  * and QH state associated with this transfer has been cleared
02416                  * (in the case of URB_DEQUEUE), so the channel needs to be
02417                  * shut down carefully to prevent crashes.
02418                  */
02419                 hcintmsk_data_t hcintmsk;
02420                 hcintmsk.d32 = 0;
02421                 hcintmsk.b.chhltd = 1;
02422                 DWC_WRITE_REG32(&hc_regs->hcintmsk, hcintmsk.d32);
02423 
02424                 /*
02425                  * Make sure no other interrupts besides halt are currently
02426                  * pending. Handling another interrupt could cause a crash due
02427                  * to the QTD and QH state.
02428                  */
02429                 DWC_WRITE_REG32(&hc_regs->hcint, ~hcintmsk.d32);
02430 
02431                 /*
02432                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
02433                  * even if the channel was already halted for some other
02434                  * reason.
02435                  */
02436                 hc->halt_status = halt_status;
02437 
02438                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02439                 if (hcchar.b.chen == 0) {
02440                         /*
02441                          * The channel is either already halted or it hasn't
02442                          * started yet. In DMA mode, the transfer may halt if
02443                          * it finishes normally or a condition occurs that
02444                          * requires driver intervention. Don't want to halt
02445                          * the channel again. In either Slave or DMA mode,
02446                          * it's possible that the transfer has been assigned
02447                          * to a channel, but not started yet when an URB is
02448                          * dequeued. Don't want to halt a channel that hasn't
02449                          * started yet.
02450                          */
02451                         return;
02452                 }
02453         }
02454         if (hc->halt_pending) {
02455                 /*
02456                  * A halt has already been issued for this channel. This might
02457                  * happen when a transfer is aborted by a higher level in
02458                  * the stack.
02459                  */
02460 #ifdef DEBUG
02461                 DWC_PRINTF
02462                     ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
02463                      __func__, hc->hc_num);
02464 
02465 #endif
02466                 return;
02467         }
02468 
02469         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02470 
02471         /* No need to set the bit in DDMA for disabling the channel */
02472         //TODO check it everywhere channel is disabled          
02473         if (!core_if->core_params->dma_desc_enable)
02474                 hcchar.b.chen = 1;
02475         hcchar.b.chdis = 1;
02476 
02477         if (!core_if->dma_enable) {
02478                 /* Check for space in the request queue to issue the halt. */
02479                 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
02480                     hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
02481                         nptxsts.d32 = DWC_READ_REG32(&global_regs->gnptxsts);
02482                         if (nptxsts.b.nptxqspcavail == 0) {
02483                                 hcchar.b.chen = 0;
02484                         }
02485                 } else {
02486                         hptxsts.d32 =
02487                             DWC_READ_REG32(&host_global_regs->hptxsts);
02488                         if ((hptxsts.b.ptxqspcavail == 0)
02489                             || (core_if->queuing_high_bandwidth)) {
02490                                 hcchar.b.chen = 0;
02491                         }
02492                 }
02493         }
02494         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02495 
02496         hc->halt_status = halt_status;
02497 
02498         if (hcchar.b.chen) {
02499                 hc->halt_pending = 1;
02500                 hc->halt_on_queue = 0;
02501         } else {
02502                 hc->halt_on_queue = 1;
02503         }
02504 
02505         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02506         DWC_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n", hcchar.d32);
02507         DWC_DEBUGPL(DBG_HCDV, "  halt_pending: %d\n", hc->halt_pending);
02508         DWC_DEBUGPL(DBG_HCDV, "  halt_on_queue: %d\n", hc->halt_on_queue);
02509         DWC_DEBUGPL(DBG_HCDV, "  halt_status: %d\n", hc->halt_status);
02510 
02511         return;
02512 }
02513 
02521 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02522 {
02523         dwc_otg_hc_regs_t *hc_regs;
02524 
02525         hc->xfer_started = 0;
02526 
02527         /*
02528          * Clear channel interrupt enables and any unhandled channel interrupt
02529          * conditions.
02530          */
02531         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02532         DWC_WRITE_REG32(&hc_regs->hcintmsk, 0);
02533         DWC_WRITE_REG32(&hc_regs->hcint, 0xFFFFFFFF);
02534 #ifdef DEBUG
02535         DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
02536 #endif
02537 }
02538 
02549 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
02550                                          dwc_hc_t * hc, hcchar_data_t * hcchar)
02551 {
02552         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02553             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02554                 hfnum_data_t hfnum;
02555                 hfnum.d32 =
02556                     DWC_READ_REG32(&core_if->host_if->host_global_regs->hfnum);
02557 
02558                 /* 1 if _next_ frame is odd, 0 if it's even */
02559                 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
02560 #ifdef DEBUG
02561                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
02562                     && !hc->complete_split) {
02563                         switch (hfnum.b.frnum & 0x7) {
02564                         case 7:
02565                                 core_if->hfnum_7_samples++;
02566                                 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
02567                                 break;
02568                         case 0:
02569                                 core_if->hfnum_0_samples++;
02570                                 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
02571                                 break;
02572                         default:
02573                                 core_if->hfnum_other_samples++;
02574                                 core_if->hfnum_other_frrem_accum +=
02575                                     hfnum.b.frrem;
02576                                 break;
02577                         }
02578                 }
02579 #endif
02580         }
02581 }
02582 
02583 #ifdef DEBUG
02584 void hc_xfer_timeout(void *ptr)
02585 {
02586         hc_xfer_info_t *xfer_info = NULL;
02587         int hc_num = 0;
02588 
02589         if (ptr)
02590                 xfer_info = (hc_xfer_info_t *) ptr;
02591 
02592         if (!xfer_info->hc) {
02593                 DWC_ERROR("xfer_info->hc = %p\n", xfer_info->hc);
02594                 return;
02595         }
02596 
02597         hc_num = xfer_info->hc->hc_num;
02598         DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
02599         DWC_WARN("      start_hcchar_val 0x%08x\n",
02600                  xfer_info->core_if->start_hcchar_val[hc_num]);
02601 }
02602 #endif
02603 
02604 void ep_xfer_timeout(void *ptr)
02605 {
02606         ep_xfer_info_t *xfer_info = NULL;
02607         int ep_num = 0;
02608         dctl_data_t dctl = {.d32 = 0 };
02609         gintsts_data_t gintsts = {.d32 = 0 };
02610         gintmsk_data_t gintmsk = {.d32 = 0 };
02611 
02612         if (ptr)
02613                 xfer_info = (ep_xfer_info_t *) ptr;
02614 
02615         if (!xfer_info->ep) {
02616                 DWC_ERROR("xfer_info->ep = %p\n", xfer_info->ep);
02617                 return;
02618         }
02619 
02620         ep_num = xfer_info->ep->num;
02621         DWC_WARN("%s: timeout on endpoit %d\n", __func__, ep_num);
02622         /* Put the sate to 2 as it was time outed */
02623         xfer_info->state = 2;
02624 
02625         dctl.d32 = DWC_READ_REG32(&xfer_info->core_if->
02626                 dev_if->dev_global_regs->dctl);
02627         gintsts.d32 = DWC_READ_REG32(&xfer_info->core_if->
02628                 core_global_regs->gintsts);
02629         gintmsk.d32 = DWC_READ_REG32(&xfer_info->core_if->
02630                 core_global_regs->gintmsk);
02631 
02632         if (!gintmsk.b.goutnakeff) {
02633                 /* Unmask it */
02634                 gintmsk.b.goutnakeff = 1;
02635                 DWC_WRITE_REG32(&xfer_info->core_if->
02636                         core_global_regs->gintmsk, gintmsk.d32);
02637 
02638         }
02639 
02640         if (!gintsts.b.goutnakeff) {
02641                 dctl.b.sgoutnak = 1;
02642         }
02643         DWC_WRITE_REG32(&xfer_info->core_if->dev_if->
02644                 dev_global_regs->dctl, dctl.d32);
02645 
02646 }
02647 
02648 void set_pid_isoc(dwc_hc_t * hc)
02649 {
02650         /* Set up the initial PID for the transfer. */
02651         if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
02652                 if (hc->ep_is_in) {
02653                         if (hc->multi_count == 1) {
02654                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02655                         } else if (hc->multi_count == 2) {
02656                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA1;
02657                         } else {
02658                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA2;
02659                         }
02660                 } else {
02661                         if (hc->multi_count == 1) {
02662                                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02663                         } else {
02664                                 hc->data_pid_start = DWC_OTG_HC_PID_MDATA;
02665                         }
02666                 }
02667         } else {
02668                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
02669         }
02670 }
02671 
02703 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02704 {
02705         hcchar_data_t hcchar;
02706         hctsiz_data_t hctsiz;
02707         uint16_t num_packets;
02708         uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
02709         uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
02710         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02711 
02712         hctsiz.d32 = 0;
02713 
02714         if (hc->do_ping) {
02715                 if (!core_if->dma_enable) {
02716                         dwc_otg_hc_do_ping(core_if, hc);
02717                         hc->xfer_started = 1;
02718                         return;
02719                 } else {
02720                         hctsiz.b.dopng = 1;
02721                 }
02722         }
02723 
02724         if (hc->do_split) {
02725                 num_packets = 1;
02726 
02727                 if (hc->complete_split && !hc->ep_is_in) {
02728                         /* For CSPLIT OUT Transfer, set the size to 0 so the
02729                          * core doesn't expect any data written to the FIFO */
02730                         hc->xfer_len = 0;
02731                 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
02732                         hc->xfer_len = hc->max_packet;
02733                 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
02734                         hc->xfer_len = 188;
02735                 }
02736 
02737                 hctsiz.b.xfersize = hc->xfer_len;
02738         } else {
02739                 /*
02740                  * Ensure that the transfer length and packet count will fit
02741                  * in the widths allocated for them in the HCTSIZn register.
02742                  */
02743                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02744                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02745                         /*
02746                          * Make sure the transfer size is no larger than one
02747                          * (micro)frame's worth of data. (A check was done
02748                          * when the periodic transfer was accepted to ensure
02749                          * that a (micro)frame's worth of data can be
02750                          * programmed into a channel.)
02751                          */
02752                         uint32_t max_periodic_len =
02753                             hc->multi_count * hc->max_packet;
02754                         if (hc->xfer_len > max_periodic_len) {
02755                                 hc->xfer_len = max_periodic_len;
02756                         } else {
02757                         }
02758                 } else if (hc->xfer_len > max_hc_xfer_size) {
02759                         /* Make sure that xfer_len is a multiple of max packet size. */
02760                         hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
02761                 }
02762 
02763                 if (hc->xfer_len > 0) {
02764                         num_packets =
02765                             (hc->xfer_len + hc->max_packet -
02766                              1) / hc->max_packet;
02767                         if (num_packets > max_hc_pkt_count) {
02768                                 num_packets = max_hc_pkt_count;
02769                                 hc->xfer_len = num_packets * hc->max_packet;
02770                         }
02771                 } else {
02772                         /* Need 1 packet for transfer length of 0. */
02773                         num_packets = 1;
02774                 }
02775 
02776                 if (hc->ep_is_in) {
02777                         /* Always program an integral # of max packets for IN transfers. */
02778                         hc->xfer_len = num_packets * hc->max_packet;
02779                 }
02780 
02781                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02782                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02783                         /*
02784                          * Make sure that the multi_count field matches the
02785                          * actual transfer length.
02786                          */
02787                         hc->multi_count = num_packets;
02788                 }
02789 
02790                 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02791                         set_pid_isoc(hc);
02792 
02793                 hctsiz.b.xfersize = hc->xfer_len;
02794         }
02795 
02796         hc->start_pkt_count = num_packets;
02797         hctsiz.b.pktcnt = num_packets;
02798         hctsiz.b.pid = hc->data_pid_start;
02799         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
02800 
02801         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02802         DWC_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
02803         DWC_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n", hctsiz.b.pktcnt);
02804         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
02805 
02806         if (core_if->dma_enable) {
02807                 dwc_dma_t dma_addr;
02808                 if (hc->align_buff) {
02809                         dma_addr = hc->align_buff;
02810                 } else {
02811                         dma_addr = ((unsigned long)hc->xfer_buff & 0xffffffff);
02812                 }
02813                 DWC_WRITE_REG32(&hc_regs->hcdma, dma_addr);
02814         }
02815 
02816         /* Start the split */
02817         if (hc->do_split) {
02818                 hcsplt_data_t hcsplt;
02819                 hcsplt.d32 = DWC_READ_REG32(&hc_regs->hcsplt);
02820                 hcsplt.b.spltena = 1;
02821                 DWC_WRITE_REG32(&hc_regs->hcsplt, hcsplt.d32);
02822         }
02823 
02824         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02825         hcchar.b.multicnt = hc->multi_count;
02826         hc_set_even_odd_frame(core_if, hc, &hcchar);
02827 #ifdef DEBUG
02828         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
02829         if (hcchar.b.chdis) {
02830                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
02831                          __func__, hc->hc_num, hcchar.d32);
02832         }
02833 #endif
02834 
02835         /* Set host channel enable after all other setup is complete. */
02836         hcchar.b.chen = 1;
02837         hcchar.b.chdis = 0;
02838         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02839 
02840         hc->xfer_started = 1;
02841         hc->requests++;
02842 
02843         if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
02844                 /* Load OUT packet into the appropriate Tx FIFO. */
02845                 dwc_otg_hc_write_packet(core_if, hc);
02846         }
02847 #ifdef DEBUG
02848         if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
02849                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
02850                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
02851 
02852                 /* Start a timer for this transfer. */
02853                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
02854         }
02855 #endif
02856 }
02857 
02872 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02873 {
02874         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02875         hcchar_data_t hcchar;
02876         hctsiz_data_t hctsiz;
02877         hcdma_data_t hcdma;
02878 
02879         hctsiz.d32 = 0;
02880 
02881         if (hc->do_ping)
02882                 hctsiz.b_ddma.dopng = 1;
02883 
02884         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
02885                 set_pid_isoc(hc);
02886 
02887         /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
02888         hctsiz.b_ddma.pid = hc->data_pid_start;
02889         hctsiz.b_ddma.ntd = hc->ntd - 1;        /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
02890         hctsiz.b_ddma.schinfo = hc->schinfo;    /* Non-zero only for high-speed interrupt endpoints */
02891 
02892         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02893         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
02894         DWC_DEBUGPL(DBG_HCDV, "  NTD: %d\n", hctsiz.b_ddma.ntd);
02895 
02896         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
02897 
02898         hcdma.d32 = 0;
02899         hcdma.b.dma_addr = ((uint32_t) hc->desc_list_addr) >> 11;
02900 
02901         /* Always start from first descriptor. */
02902         hcdma.b.ctd = 0;
02903         DWC_WRITE_REG32(&hc_regs->hcdma, hcdma.d32);
02904 
02905         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02906         hcchar.b.multicnt = hc->multi_count;
02907 
02908 #ifdef DEBUG
02909         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
02910         if (hcchar.b.chdis) {
02911                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
02912                          __func__, hc->hc_num, hcchar.d32);
02913         }
02914 #endif
02915 
02916         /* Set host channel enable after all other setup is complete. */
02917         hcchar.b.chen = 1;
02918         hcchar.b.chdis = 0;
02919 
02920         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02921 
02922         hc->xfer_started = 1;
02923         hc->requests++;
02924 
02925 #ifdef DEBUG
02926         if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR)
02927             && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
02928                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
02929                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
02930                 /* Start a timer for this transfer. */
02931                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
02932         }
02933 #endif
02934 
02935 }
02936 
02952 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02953 {
02954         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02955 
02956         if (hc->do_split) {
02957                 /* SPLITs always queue just once per channel */
02958                 return 0;
02959         } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
02960                 /* SETUPs are queued only once since they can't be NAKed. */
02961                 return 0;
02962         } else if (hc->ep_is_in) {
02963                 /*
02964                  * Always queue another request for other IN transfers. If
02965                  * back-to-back INs are issued and NAKs are received for both,
02966                  * the driver may still be processing the first NAK when the
02967                  * second NAK is received. When the interrupt handler clears
02968                  * the NAK interrupt for the first NAK, the second NAK will
02969                  * not be seen. So we can't depend on the NAK interrupt
02970                  * handler to requeue a NAKed request. Instead, IN requests
02971                  * are issued each time this function is called. When the
02972                  * transfer completes, the extra requests for the channel will
02973                  * be flushed.
02974                  */
02975                 hcchar_data_t hcchar;
02976                 dwc_otg_hc_regs_t *hc_regs =
02977                     core_if->host_if->hc_regs[hc->hc_num];
02978 
02979                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02980                 hc_set_even_odd_frame(core_if, hc, &hcchar);
02981                 hcchar.b.chen = 1;
02982                 hcchar.b.chdis = 0;
02983                 DWC_DEBUGPL(DBG_HCDV, "  IN xfer: hcchar = 0x%08x\n",
02984                             hcchar.d32);
02985                 DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
02986                 hc->requests++;
02987                 return 1;
02988         } else {
02989                 /* OUT transfers. */
02990                 if (hc->xfer_count < hc->xfer_len) {
02991                         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02992                             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02993                                 hcchar_data_t hcchar;
02994                                 dwc_otg_hc_regs_t *hc_regs;
02995                                 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02996                                 hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
02997                                 hc_set_even_odd_frame(core_if, hc, &hcchar);
02998                         }
02999 
03000                         /* Load OUT packet into the appropriate Tx FIFO. */
03001                         dwc_otg_hc_write_packet(core_if, hc);
03002                         hc->requests++;
03003                         return 1;
03004                 } else {
03005                         return 0;
03006                 }
03007         }
03008 }
03009 
03014 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
03015 {
03016         hcchar_data_t hcchar;
03017         hctsiz_data_t hctsiz;
03018         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
03019 
03020         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
03021 
03022         hctsiz.d32 = 0;
03023         hctsiz.b.dopng = 1;
03024         hctsiz.b.pktcnt = 1;
03025         DWC_WRITE_REG32(&hc_regs->hctsiz, hctsiz.d32);
03026 
03027         hcchar.d32 = DWC_READ_REG32(&hc_regs->hcchar);
03028         hcchar.b.chen = 1;
03029         hcchar.b.chdis = 0;
03030         DWC_WRITE_REG32(&hc_regs->hcchar, hcchar.d32);
03031 }
03032 
03033 /*
03034  * This function writes a packet into the Tx FIFO associated with the Host
03035  * Channel. For a channel associated with a non-periodic EP, the non-periodic
03036  * Tx FIFO is written. For a channel associated with a periodic EP, the
03037  * periodic Tx FIFO is written. This function should only be called in Slave
03038  * mode.
03039  *
03040  * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
03041  * then number of bytes written to the Tx FIFO.
03042  */
03043 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
03044 {
03045         uint32_t i;
03046         uint32_t remaining_count;
03047         uint32_t byte_count;
03048         uint32_t dword_count;
03049 
03050         uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
03051         uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
03052 
03053         remaining_count = hc->xfer_len - hc->xfer_count;
03054         if (remaining_count > hc->max_packet) {
03055                 byte_count = hc->max_packet;
03056         } else {
03057                 byte_count = remaining_count;
03058         }
03059 
03060         dword_count = (byte_count + 3) / 4;
03061 
03062         if ((((unsigned long)data_buff) & 0x3) == 0) {
03063                 /* xfer_buff is DWORD aligned. */
03064                 for (i = 0; i < dword_count; i++, data_buff++) {
03065                         DWC_WRITE_REG32(data_fifo, *data_buff);
03066                 }
03067         } else {
03068                 /* xfer_buff is not DWORD aligned. */
03069                 for (i = 0; i < dword_count; i++, data_buff++) {
03070                         uint32_t data;
03071                         data =
03072                             (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
03073                              16 | data_buff[3] << 24);
03074                         DWC_WRITE_REG32(data_fifo, data);
03075                 }
03076         }
03077 
03078         hc->xfer_count += byte_count;
03079         hc->xfer_buff += byte_count;
03080 }
03081 
03086 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
03087 {
03088         dsts_data_t dsts;
03089         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03090 
03091         /* read current frame/microframe number from DSTS register */
03092         return dsts.b.soffn;
03093 }
03094 
03102 uint32_t calc_frame_interval(dwc_otg_core_if_t * core_if)
03103 {
03104         gusbcfg_data_t usbcfg;
03105         hwcfg2_data_t hwcfg2;
03106         hprt0_data_t hprt0;
03107         int clock = 60;         // default value
03108         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
03109         hwcfg2.d32 = DWC_READ_REG32(&core_if->core_global_regs->ghwcfg2);
03110         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
03111         if (!usbcfg.b.physel && usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
03112                 clock = 60;
03113         if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 3)
03114                 clock = 48;
03115         if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03116             !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
03117                 clock = 30;
03118         if (!usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03119             !usbcfg.b.ulpi_utmi_sel && !usbcfg.b.phyif)
03120                 clock = 60;
03121         if (usbcfg.b.phylpwrclksel && !usbcfg.b.physel &&
03122             !usbcfg.b.ulpi_utmi_sel && usbcfg.b.phyif)
03123                 clock = 48;
03124         if (usbcfg.b.physel && !usbcfg.b.phyif && hwcfg2.b.fs_phy_type == 2)
03125                 clock = 48;
03126         if (usbcfg.b.physel && hwcfg2.b.fs_phy_type == 1)
03127                 clock = 48;
03128         if (hprt0.b.prtspd == 0)
03129                 /* High speed case */
03130                 return 125 * clock;
03131         else
03132                 /* FS/LS case */
03133                 return 1000 * clock;
03134 }
03135 
03144 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
03145 {
03146         /* Get the 8 bytes of a setup transaction data */
03147 
03148         /* Pop 2 DWORDS off the receive data FIFO into memory */
03149         dest[0] = DWC_READ_REG32(core_if->data_fifo[0]);
03150         dest[1] = DWC_READ_REG32(core_if->data_fifo[0]);
03151 }
03152 
03161 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03162 {
03163         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03164         dsts_data_t dsts;
03165         depctl_data_t diepctl;
03166         depctl_data_t doepctl;
03167         dctl_data_t dctl = {.d32 = 0 };
03168 
03169         /* Read the Device Status and Endpoint 0 Control registers */
03170         dsts.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dsts);
03171         diepctl.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl);
03172         doepctl.d32 = DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl);
03173 
03174         /* Set the MPS of the IN EP based on the enumeration speed */
03175         switch (dsts.b.enumspd) {
03176         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
03177         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
03178         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
03179                 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
03180                 break;
03181         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
03182                 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
03183                 break;
03184         }
03185 
03186         DWC_WRITE_REG32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
03187 
03188         /* Enable OUT EP for receive */
03189         doepctl.b.epena = 1;
03190         DWC_WRITE_REG32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
03191 
03192 #ifdef VERBOSE
03193         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
03194                     DWC_READ_REG32(&dev_if->out_ep_regs[0]->doepctl));
03195         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
03196                     DWC_READ_REG32(&dev_if->in_ep_regs[0]->diepctl));
03197 #endif
03198         dctl.b.cgnpinnak = 1;
03199 
03200         DWC_MODIFY_REG32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
03201         DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
03202                     DWC_READ_REG32(&dev_if->dev_global_regs->dctl));
03203 
03204 }
03205 
03214 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03215 {
03216         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03217         depctl_data_t depctl;
03218         volatile uint32_t *addr;
03219         daint_data_t daintmsk = {.d32 = 0 };
03220         dcfg_data_t dcfg;
03221         uint8_t i;
03222 
03223         DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
03224                     (ep->is_in ? "IN" : "OUT"));
03225 
03226 #ifdef DWC_UTE_PER_IO
03227         ep->xiso_frame_num = 0xFFFFFFFF;
03228         ep->xiso_active_xfers = 0;
03229         ep->xiso_queued_xfers = 0;
03230 #endif
03231         /* Read DEPCTLn register */
03232         if (ep->is_in == 1) {
03233                 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
03234                 daintmsk.ep.in = 1 << ep->num;
03235         } else {
03236                 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
03237                 daintmsk.ep.out = 1 << ep->num;
03238         }
03239 
03240         /* If the EP is already active don't change the EP Control
03241          * register. */
03242         depctl.d32 = DWC_READ_REG32(addr);
03243         if (!depctl.b.usbactep) {
03244                 depctl.b.mps = ep->maxpacket;
03245                 depctl.b.eptype = ep->type;
03246                 depctl.b.txfnum = ep->tx_fifo_num;
03247 
03248                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03249                         depctl.b.setd0pid = 1;  // ???
03250                 } else {
03251                         depctl.b.setd0pid = 1;
03252                 }
03253                 depctl.b.usbactep = 1;
03254 
03255                 /* Update nextep_seq array and EPMSCNT in DCFG*/
03256                 if (!(depctl.b.eptype & 1) && (ep->is_in == 1)) {       // NP IN EP
03257                         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03258                                 if (core_if->nextep_seq[i] == core_if->first_in_nextep_seq)
03259                                 break;
03260                         }
03261                         core_if->nextep_seq[i] = ep->num;       
03262                         core_if->nextep_seq[ep->num] = core_if->first_in_nextep_seq;
03263                         depctl.b.nextep = core_if->nextep_seq[ep->num];
03264                         dcfg.d32 = DWC_READ_REG32(&dev_if->dev_global_regs->dcfg);
03265                         dcfg.b.epmscnt++;
03266                         DWC_WRITE_REG32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
03267 
03268                         DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n", 
03269                                 __func__, core_if->first_in_nextep_seq);
03270                         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03271                                 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
03272                         }
03273 
03274                 }
03275 
03276 
03277                 DWC_WRITE_REG32(addr, depctl.d32);
03278                 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", DWC_READ_REG32(addr));
03279         }
03280 
03281         /* Enable the Interrupt for this EP */
03282         if (core_if->multiproc_int_enable) {
03283                 if (ep->is_in == 1) {
03284                         diepmsk_data_t diepmsk = {.d32 = 0 };
03285                         diepmsk.b.xfercompl = 1;
03286                         diepmsk.b.timeout = 1;
03287                         diepmsk.b.epdisabled = 1;
03288                         diepmsk.b.ahberr = 1;
03289                         diepmsk.b.intknepmis = 1;
03290                         if (!core_if->en_multiple_tx_fifo && core_if->dma_enable)
03291                                 diepmsk.b.intknepmis = 0; 
03292                         diepmsk.b.txfifoundrn = 1;      //?????
03293                         if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03294                                 diepmsk.b.nak = 1;
03295                         }
03296 
03297                         
03298                         
03299 /*
03300                         if (core_if->dma_desc_enable) {
03301                                 diepmsk.b.bna = 1;
03302                         }
03303 */
03304 /*                      
03305                         if (core_if->dma_enable) {
03306                                 doepmsk.b.nak = 1;
03307                         }
03308 */
03309                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
03310                                         diepeachintmsk[ep->num], diepmsk.d32);
03311 
03312                 } else {
03313                         doepmsk_data_t doepmsk = {.d32 = 0 };
03314                         doepmsk.b.xfercompl = 1;
03315                         doepmsk.b.ahberr = 1;
03316                         doepmsk.b.epdisabled = 1;
03317                         if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03318                                 doepmsk.b.outtknepdis = 1;
03319 
03320 /*                      
03321 
03322                         if (core_if->dma_desc_enable) {
03323                                 doepmsk.b.bna = 1;
03324                         }
03325 */
03326 /*                      
03327                         doepmsk.b.babble = 1;
03328                         doepmsk.b.nyet = 1;
03329                         doepmsk.b.nak = 1;
03330 */
03331                         DWC_WRITE_REG32(&dev_if->dev_global_regs->
03332                                         doepeachintmsk[ep->num], doepmsk.d32);
03333                 }
03334                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->deachintmsk,
03335                                  0, daintmsk.d32);
03336         } else {
03337                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
03338                         if (ep->is_in)
03339                         {
03340                                 diepmsk_data_t diepmsk = {.d32 = 0 };
03341                                 diepmsk.b.nak = 1;
03342                                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->diepmsk, 0, diepmsk.d32);
03343                         } else {
03344                                 doepmsk_data_t doepmsk = {.d32 = 0 };
03345                                 doepmsk.b.outtknepdis = 1;
03346                                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->doepmsk, 0, doepmsk.d32);
03347                         }
03348                 }
03349                 DWC_MODIFY_REG32(&dev_if->dev_global_regs->daintmsk,
03350                                  0, daintmsk.d32);
03351         }
03352 
03353         DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
03354                     DWC_READ_REG32(&dev_if->dev_global_regs->daintmsk));
03355 
03356         ep->stall_clear_flag = 0;
03357 
03358         return;
03359 }
03360 
03369 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03370 {
03371         depctl_data_t depctl = {.d32 = 0 };
03372         volatile uint32_t *addr;
03373         daint_data_t daintmsk = {.d32 = 0 };
03374         dcfg_data_t dcfg;
03375         uint8_t i = 0;
03376 
03377 #ifdef DWC_UTE_PER_IO
03378         ep->xiso_frame_num = 0xFFFFFFFF;
03379         ep->xiso_active_xfers = 0;
03380         ep->xiso_queued_xfers = 0;
03381 #endif
03382 
03383         /* Read DEPCTLn register */
03384         if (ep->is_in == 1) {
03385                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
03386                 daintmsk.ep.in = 1 << ep->num;
03387         } else {
03388                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
03389                 daintmsk.ep.out = 1 << ep->num;
03390         }
03391 
03392         depctl.d32 = DWC_READ_REG32(addr);
03393 
03394         depctl.b.usbactep = 0;
03395         
03396         /* Update nextep_seq array and EPMSCNT in DCFG*/
03397         if (!(depctl.b.eptype & 1) && ep->is_in == 1) { // NP EP IN
03398                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03399                         if (core_if->nextep_seq[i] == ep->num)
03400                         break;
03401                 }
03402                 core_if->nextep_seq[i] = core_if->nextep_seq[ep->num];  
03403                 if (core_if->first_in_nextep_seq == ep->num)
03404                         core_if->first_in_nextep_seq = i;
03405                 core_if->nextep_seq[ep->num] = 0xff;
03406                 depctl.b.nextep = 0;
03407                 dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
03408                 dcfg.b.epmscnt--;
03409                 DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
03410 
03411                         DWC_DEBUGPL(DBG_PCDV,"%s first_in_nextep_seq= %2d; nextep_seq[]:\n", 
03412                                 __func__, core_if->first_in_nextep_seq);
03413                         for (i=0; i <= core_if->dev_if->num_in_eps; i++) {
03414                                 DWC_DEBUGPL(DBG_PCDV, "%2d\n", core_if->nextep_seq[i]);
03415                         }
03416         }
03417                 
03418         if (ep->is_in == 1)
03419                 depctl.b.txfnum = 0;
03420 
03421         if (core_if->dma_desc_enable)
03422                 depctl.b.epdis = 1;
03423 
03424         DWC_WRITE_REG32(addr, depctl.d32);
03425         depctl.d32 = DWC_READ_REG32(addr);
03426         if (core_if->dma_enable && ep->type == DWC_OTG_EP_TYPE_ISOC && depctl.b.epena)
03427         {
03428                 depctl_data_t depctl = {.d32 = 0};
03429                 if (ep->is_in)
03430                 {
03431                         diepint_data_t diepint = {.d32 = 0};
03432                         
03433                         depctl.b.snak = 1;
03434                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl, depctl.d32);
03435                         do 
03436                         {
03437                                 dwc_udelay(10);
03438                                 diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03439                                                                                         in_ep_regs[ep->num]->diepint);
03440                         } while (!diepint.b.inepnakeff); 
03441                         diepint.b.inepnakeff = 1;
03442                         DWC_WRITE_REG32(&core_if->dev_if->
03443                                                         in_ep_regs[ep->num]->diepint, diepint.d32);
03444                         depctl.d32 = 0;
03445                         depctl.b.epdis = 1;
03446                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepctl, depctl.d32);
03447                         do 
03448                         {
03449                                 dwc_udelay(10);
03450                                 diepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03451                                                                                         in_ep_regs[ep->num]->diepint);
03452                         } while (!diepint.b.epdisabled); 
03453                         diepint.b.epdisabled = 1;
03454                         DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->diepint, diepint.d32);
03455                 } else {
03456                         dctl_data_t dctl = {.d32 = 0};
03457                         gintmsk_data_t gintsts = {.d32 = 0};
03458                         doepint_data_t doepint = {.d32 = 0};
03459                         dctl.b.sgoutnak = 1;
03460                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
03461                         do 
03462                         {
03463                                 dwc_udelay(10);
03464                                 gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
03465                         } while (!gintsts.b.goutnakeff); 
03466                         gintsts.d32 = 0;
03467                         gintsts.b.goutnakeff = 1;
03468                         DWC_WRITE_REG32(&core_if->core_global_regs->gintsts, gintsts.d32);
03469 
03470                         depctl.d32 = 0;
03471                         depctl.b.epdis = 1;
03472                         depctl.b.snak = 1;
03473                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepctl, depctl.d32);
03474                         do 
03475                         {
03476                                 dwc_udelay(10);
03477                                 doepint.d32 = DWC_READ_REG32(&core_if->dev_if->
03478                                                                                         out_ep_regs[ep->num]->doepint);
03479                         } while (!doepint.b.epdisabled); 
03480 
03481                         doepint.b.epdisabled = 1;
03482                         DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->doepint, doepint.d32);
03483 
03484                         dctl.d32 = 0;
03485                         dctl.b.cgoutnak = 1;
03486                         DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->dctl, 0, dctl.d32);
03487                 }               
03488         }
03489 
03490         /* Disable the Interrupt for this EP */
03491         if (core_if->multiproc_int_enable) {
03492                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->deachintmsk,
03493                                  daintmsk.d32, 0);
03494 
03495                 if (ep->is_in == 1) {
03496                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
03497                                         diepeachintmsk[ep->num], 0);
03498                 } else {
03499                         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->
03500                                         doepeachintmsk[ep->num], 0);
03501                 }
03502         } else {
03503                 DWC_MODIFY_REG32(&core_if->dev_if->dev_global_regs->daintmsk,
03504                                  daintmsk.d32, 0);
03505         }
03506 
03507 }
03508 
03515 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03516 {
03517         dwc_otg_dev_dma_desc_t *dma_desc;
03518         uint32_t offset;
03519         uint32_t xfer_est;
03520         int i;
03521         unsigned maxxfer_local, total_len;
03522         
03523         if (!ep->is_in && ep->type == DWC_OTG_EP_TYPE_INTR && 
03524                                         (ep->maxpacket%4)) {
03525                 maxxfer_local = ep->maxpacket;
03526                 total_len = ep->xfer_len;
03527         } else {
03528                 maxxfer_local = ep->maxxfer;
03529                 total_len = ep->total_len;
03530         }
03531 
03532         ep->desc_cnt = (total_len / maxxfer_local) +
03533             ((total_len % maxxfer_local) ? 1 : 0);
03534 
03535         if (!ep->desc_cnt)
03536                 ep->desc_cnt = 1;
03537 
03538         if (ep->desc_cnt > MAX_DMA_DESC_CNT)
03539                 ep->desc_cnt = MAX_DMA_DESC_CNT;
03540 
03541         dma_desc = ep->desc_addr;
03542         if (maxxfer_local == ep->maxpacket) {
03543                 if ((total_len % maxxfer_local) &&
03544                                 (total_len/maxxfer_local < MAX_DMA_DESC_CNT)) {
03545                         xfer_est = (ep->desc_cnt - 1) * maxxfer_local +
03546                                         (total_len % maxxfer_local);
03547                 } else
03548                         xfer_est = ep->desc_cnt * maxxfer_local;
03549         }
03550         else
03551                 xfer_est = total_len;
03552         offset = 0;
03553         for (i = 0; i < ep->desc_cnt; ++i) {
03555                 if (xfer_est > maxxfer_local) {
03556                         dma_desc->status.b.bs = BS_HOST_BUSY;
03557                         dma_desc->status.b.l = 0;
03558                         dma_desc->status.b.ioc = 0;
03559                         dma_desc->status.b.sp = 0;
03560                         dma_desc->status.b.bytes = maxxfer_local;
03561                         dma_desc->buf = ep->dma_addr + offset;
03562                         dma_desc->status.b.sts = 0;
03563                         dma_desc->status.b.bs = BS_HOST_READY;
03564 
03565                         xfer_est -= maxxfer_local;
03566                         offset += maxxfer_local;
03567                 } else {
03568                         dma_desc->status.b.bs = BS_HOST_BUSY;
03569                         dma_desc->status.b.l = 1;
03570                         dma_desc->status.b.ioc = 1;
03571                         if (ep->is_in) {
03572                                 dma_desc->status.b.sp =
03573                                     (xfer_est %
03574                                      ep->maxpacket) ? 1 : ((ep->
03575                                                             sent_zlp) ? 1 : 0);
03576                                 dma_desc->status.b.bytes = xfer_est;
03577                         } else {
03578                                 if (maxxfer_local == ep->maxpacket)
03579                                         dma_desc->status.b.bytes = xfer_est;
03580                                 else    
03581                                         dma_desc->status.b.bytes =
03582                                                 xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
03583                         }
03584 
03585                         dma_desc->buf = ep->dma_addr + offset;
03586                         dma_desc->status.b.sts = 0;
03587                         dma_desc->status.b.bs = BS_HOST_READY;
03588                 }
03589                 dma_desc++;
03590         }
03591 }
03596 static int32_t write_isoc_tx_fifo(dwc_otg_core_if_t * core_if, dwc_ep_t * dwc_ep)
03597 {
03598         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
03599         dwc_otg_dev_in_ep_regs_t *ep_regs;
03600         dtxfsts_data_t txstatus = {.d32 = 0 };
03601         uint32_t len = 0;
03602         int epnum = dwc_ep->num;
03603         int dwords;
03604 
03605         DWC_DEBUGPL(DBG_PCD, "Dedicated TxFifo Empty: %d \n", epnum);
03606 
03607         ep_regs = core_if->dev_if->in_ep_regs[epnum];
03608 
03609         len = dwc_ep->xfer_len - dwc_ep->xfer_count;
03610 
03611         if (len > dwc_ep->maxpacket) {
03612                 len = dwc_ep->maxpacket;
03613         }
03614 
03615         dwords = (len + 3) / 4;
03616 
03617         /* While there is space in the queue and space in the FIFO and
03618          * More data to tranfer, Write packets to the Tx FIFO */
03619         txstatus.d32 = DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
03620         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum, txstatus.d32);
03621 
03622         while (txstatus.b.txfspcavail > dwords &&
03623                dwc_ep->xfer_count < dwc_ep->xfer_len &&
03624                dwc_ep->xfer_len != 0) {
03625                 /* Write the FIFO */
03626                 dwc_otg_ep_write_packet(core_if, dwc_ep, 0);
03627 
03628                 len = dwc_ep->xfer_len - dwc_ep->xfer_count;
03629                 if (len > dwc_ep->maxpacket) {
03630                         len = dwc_ep->maxpacket;
03631                 }
03632 
03633                 dwords = (len + 3) / 4;
03634                 txstatus.d32 =
03635                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts);
03636                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", epnum,
03637                             txstatus.d32);
03638         }
03639 
03640         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", epnum,
03641                     DWC_READ_REG32(&dev_if->in_ep_regs[epnum]->dtxfsts));
03642 
03643         return 1;
03644 }
03655 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03656 {
03657         depctl_data_t depctl;
03658         deptsiz_data_t deptsiz;
03659         gintmsk_data_t intr_mask = {.d32 = 0 };
03660 
03661         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
03662         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
03663                     "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
03664                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
03665                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
03666                     ep->total_len);
03667         /* IN endpoint */
03668         if (ep->is_in == 1) {
03669                 dwc_otg_dev_in_ep_regs_t *in_regs =
03670                     core_if->dev_if->in_ep_regs[ep->num];
03671 
03672                 gnptxsts_data_t gtxstatus;
03673 
03674                 gtxstatus.d32 =
03675                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
03676 
03677                 if (core_if->en_multiple_tx_fifo == 0
03678                     && gtxstatus.b.nptxqspcavail == 0
03679                     && !core_if->dma_enable) {
03680 #ifdef DEBUG
03681                         DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
03682 #endif
03683                         return;
03684                 }
03685 
03686                 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
03687                 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
03688 
03689                 if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
03690                         ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
03691                                 ep->maxxfer : (ep->total_len - ep->xfer_len);
03692                 else 
03693                         ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len - ep->xfer_len)) ?
03694                                  MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
03695 
03696 
03697                 /* Zero Length Packet? */
03698                 if ((ep->xfer_len - ep->xfer_count) == 0) {
03699                         deptsiz.b.xfersize = 0;
03700                         deptsiz.b.pktcnt = 1;
03701                 } else {
03702                         /* Program the transfer size and packet count
03703                          *      as follows: xfersize = N * maxpacket +
03704                          *      short_packet pktcnt = N + (short_packet
03705                          *      exist ? 1 : 0) 
03706                          */
03707                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
03708                         deptsiz.b.pktcnt =
03709                             (ep->xfer_len - ep->xfer_count - 1 +
03710                              ep->maxpacket) / ep->maxpacket;
03711                         if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
03712                                 deptsiz.b.pktcnt = MAX_PKT_CNT;
03713                                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
03714                         } 
03715                         if (ep->type == DWC_OTG_EP_TYPE_ISOC) 
03716                                 deptsiz.b.mc = deptsiz.b.pktcnt;
03717                 }
03718 
03719                 /* Write the DMA register */
03720                 if (core_if->dma_enable) {
03721                         if (core_if->dma_desc_enable == 0) {
03722                                 if (ep->type != DWC_OTG_EP_TYPE_ISOC)
03723                                         deptsiz.b.mc = 1;
03724                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
03725                                                 deptsiz.d32);
03726                                 DWC_WRITE_REG32(&(in_regs->diepdma),
03727                                                 (uint32_t) ep->dma_addr);
03728                         } else {
03729 #ifdef DWC_UTE_CFI
03730                                 /* The descriptor chain should be already initialized by now */
03731                                 if (ep->buff_mode != BM_STANDARD) {
03732                                         DWC_WRITE_REG32(&in_regs->diepdma,
03733                                                         ep->descs_dma_addr);
03734                                 } else {
03735 #endif
03736                                         init_dma_desc_chain(core_if, ep);
03738                                         DWC_WRITE_REG32(&in_regs->diepdma,
03739                                                         ep->dma_desc_addr);
03740 #ifdef DWC_UTE_CFI
03741                                 }
03742 #endif
03743                         }
03744                 } else {
03745                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
03746                         if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
03752                                 if (core_if->en_multiple_tx_fifo == 0) {
03753                                         intr_mask.b.nptxfempty = 1;
03754                                         DWC_MODIFY_REG32
03755                                             (&core_if->core_global_regs->gintmsk,
03756                                              intr_mask.d32, intr_mask.d32);
03757                                 } else {
03758                                         /* Enable the Tx FIFO Empty Interrupt for this EP */
03759                                         if (ep->xfer_len > 0) {
03760                                                 uint32_t fifoemptymsk = 0;
03761                                                 fifoemptymsk = 1 << ep->num;
03762                                                 DWC_MODIFY_REG32
03763                                                     (&core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03764                                                      0, fifoemptymsk);
03765 
03766                                         }
03767                                 }
03768                         }  else {
03769                                          write_isoc_tx_fifo(core_if, ep);
03770                         }
03771                 }
03772                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
03773                         depctl.b.nextep = core_if->nextep_seq[ep->num];
03774                 
03775                 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03776                 {
03777                         dsts_data_t dsts = {.d32 = 0};
03778                         if (ep->bInterval == 1) {
03779                                 dsts.d32 =
03780                                         DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03781                                 ep->frame_num = dsts.b.soffn + ep->bInterval;
03782                                 if (ep->frame_num > 0x3FFF)
03783                                 {
03784                                         ep->frm_overrun = 1;
03785                                         ep->frame_num &= 0x3FFF;
03786                                 } else 
03787                                         ep->frm_overrun = 0;
03788                                 if (ep->frame_num & 0x1) {
03789                                         depctl.b.setd1pid = 1;
03790                                 } else {
03791                                         depctl.b.setd0pid = 1;
03792                                 }
03793                         }
03794                 }
03795                 /* EP enable, IN data in FIFO */
03796                 depctl.b.cnak = 1;
03797                 depctl.b.epena = 1;
03798                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
03799 
03800         } else {
03801                 /* OUT endpoint */
03802                 dwc_otg_dev_out_ep_regs_t *out_regs =
03803                     core_if->dev_if->out_ep_regs[ep->num];
03804 
03805                 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
03806                 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
03807 
03808                 if (!core_if->dma_desc_enable) {        
03809                         if (ep->maxpacket > ep->maxxfer / MAX_PKT_CNT)
03810                                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
03811                                 ep->maxxfer : (ep->total_len - ep->xfer_len);
03812                 else
03813                                         ep->xfer_len += (MAX_PKT_CNT * ep->maxpacket < (ep->total_len 
03814                                         - ep->xfer_len)) ? MAX_PKT_CNT * ep->maxpacket : (ep->total_len - ep->xfer_len);
03815                 }
03816 
03817                 /* Program the transfer size and packet count as follows:
03818                  *
03819                  *      pktcnt = N                                                                                
03820                  *      xfersize = N * maxpacket
03821                  */
03822                 if ((ep->xfer_len - ep->xfer_count) == 0) {
03823                         /* Zero Length Packet */
03824                         deptsiz.b.xfersize = ep->maxpacket;
03825                         deptsiz.b.pktcnt = 1;
03826                 } else {
03827                         deptsiz.b.pktcnt =
03828                             (ep->xfer_len - ep->xfer_count +
03829                              (ep->maxpacket - 1)) / ep->maxpacket;
03830                         if (deptsiz.b.pktcnt > MAX_PKT_CNT) {
03831                                 deptsiz.b.pktcnt = MAX_PKT_CNT;
03832                         }
03833                         if (!core_if->dma_desc_enable) {
03834                                 ep->xfer_len =
03835                                         deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
03836                         }
03837                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
03838                 }
03839 
03840                 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
03841                             ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
03842 
03843                 if (core_if->dma_enable) {
03844                         if (!core_if->dma_desc_enable) {
03845                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
03846                                                 deptsiz.d32);
03847 
03848                                 DWC_WRITE_REG32(&(out_regs->doepdma),
03849                                                 (uint32_t) ep->dma_addr);
03850                         } else {
03851 #ifdef DWC_UTE_CFI
03852                                 /* The descriptor chain should be already initialized by now */
03853                                 if (ep->buff_mode != BM_STANDARD) {
03854                                         DWC_WRITE_REG32(&out_regs->doepdma,
03855                                                         ep->descs_dma_addr);
03856                                 } else {
03857 #endif
03858 
03859                                         if (!ep->xfer_len)
03860                                                 ep->xfer_len = ep->total_len;
03861                                         init_dma_desc_chain(core_if, ep);
03862 
03863                                         if (core_if->core_params->dev_out_nak) {
03864                                                 if (ep->type == DWC_OTG_EP_TYPE_BULK) {
03865                                                         deptsiz.b.pktcnt = (ep->total_len +
03866                                                                 (ep->maxpacket - 1)) / ep->maxpacket;
03867                                                         deptsiz.b.xfersize = ep->total_len;
03868                                                         /* Remember initial value of doeptsiz */
03869                                                         core_if->start_doeptsiz_val[ep->num] = deptsiz.d32;
03870                                                         DWC_WRITE_REG32(&out_regs->doeptsiz,
03871                                                                 deptsiz.d32);                                                                                                   
03872                                                 }
03873                                         }
03875                                         DWC_WRITE_REG32(&out_regs->doepdma,
03876                                                         ep->dma_desc_addr);
03877 #ifdef DWC_UTE_CFI
03878                                 }
03879 #endif
03880                         }
03881                 } else {
03882                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
03883                 }
03884 
03885                 if (ep->type == DWC_OTG_EP_TYPE_ISOC)
03886                 {
03887                         dsts_data_t dsts = {.d32 = 0};
03888                         if (ep->bInterval == 1) {
03889                                 dsts.d32 =
03890                                         DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
03891                                 ep->frame_num = dsts.b.soffn + ep->bInterval;
03892                                 if (ep->frame_num > 0x3FFF)
03893                                 {
03894                                         ep->frm_overrun = 1;
03895                                         ep->frame_num &= 0x3FFF;
03896                                 } else 
03897                                         ep->frm_overrun = 0;
03898 
03899                                 if (ep->frame_num & 0x1) {
03900                                         depctl.b.setd1pid = 1;
03901                                 } else {
03902                                         depctl.b.setd0pid = 1;
03903                                 }
03904                         }
03905                 }
03906 
03907                 /* EP enable */
03908                 depctl.b.cnak = 1;
03909                 depctl.b.epena = 1;
03910 
03911                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
03912 
03913                 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
03914                             DWC_READ_REG32(&out_regs->doepctl),
03915                             DWC_READ_REG32(&out_regs->doeptsiz));
03916                 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
03917                             DWC_READ_REG32(&core_if->dev_if->
03918                                            dev_global_regs->daintmsk),
03919                             DWC_READ_REG32(&core_if->
03920                                            core_global_regs->gintmsk));
03921 
03922 
03923                 /* Timer is scheduling only for out bulk transfers for 
03924                  * "Device DDMA OUT NAK Enhancement" feature to inform user 
03925                  * about received data payload in case of timeout 
03926                  */
03927                 if (core_if->core_params->dev_out_nak) {
03928                         if (ep->type == DWC_OTG_EP_TYPE_BULK) {
03929                                 core_if->ep_xfer_info[ep->num].core_if = core_if;
03930                                 core_if->ep_xfer_info[ep->num].ep = ep;
03931                                 core_if->ep_xfer_info[ep->num].state = 1;
03932 
03933                                 /* Start a timer for this transfer. */
03934                                 DWC_TIMER_SCHEDULE(core_if->ep_xfer_timer[ep->num], 10000);
03935                         }
03936                 }
03937         }
03938 }
03939 
03948 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03949 {
03950 
03951         depctl_data_t depctl;
03952         deptsiz_data_t deptsiz;
03953         gintmsk_data_t intr_mask = {.d32 = 0 };
03954 
03955         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
03956         DWC_PRINTF("zero length transfer is called\n");
03957 
03958         /* IN endpoint */
03959         if (ep->is_in == 1) {
03960                 dwc_otg_dev_in_ep_regs_t *in_regs =
03961                     core_if->dev_if->in_ep_regs[ep->num];
03962 
03963                 depctl.d32 = DWC_READ_REG32(&(in_regs->diepctl));
03964                 deptsiz.d32 = DWC_READ_REG32(&(in_regs->dieptsiz));
03965 
03966                 deptsiz.b.xfersize = 0;
03967                 deptsiz.b.pktcnt = 1;
03968 
03969                 /* Write the DMA register */
03970                 if (core_if->dma_enable) {
03971                         if (core_if->dma_desc_enable == 0) {
03972                                 deptsiz.b.mc = 1;
03973                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
03974                                                 deptsiz.d32);
03975                                 DWC_WRITE_REG32(&(in_regs->diepdma),
03976                                                 (uint32_t) ep->dma_addr);
03977                         }
03978                 } else {
03979                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
03985                         if (core_if->en_multiple_tx_fifo == 0) {
03986                                 intr_mask.b.nptxfempty = 1;
03987                                 DWC_MODIFY_REG32(&core_if->
03988                                                  core_global_regs->gintmsk,
03989                                                  intr_mask.d32, intr_mask.d32);
03990                         } else {
03991                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
03992                                 if (ep->xfer_len > 0) {
03993                                         uint32_t fifoemptymsk = 0;
03994                                         fifoemptymsk = 1 << ep->num;
03995                                         DWC_MODIFY_REG32(&core_if->
03996                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
03997                                                          0, fifoemptymsk);
03998                                 }
03999                         }
04000                 }
04001 
04002                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04003                         depctl.b.nextep = core_if->nextep_seq[ep->num];
04004                 /* EP enable, IN data in FIFO */
04005                 depctl.b.cnak = 1;
04006                 depctl.b.epena = 1;
04007                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04008 
04009         } else {
04010                 /* OUT endpoint */
04011                 dwc_otg_dev_out_ep_regs_t *out_regs =
04012                     core_if->dev_if->out_ep_regs[ep->num];
04013 
04014                 depctl.d32 = DWC_READ_REG32(&(out_regs->doepctl));
04015                 deptsiz.d32 = DWC_READ_REG32(&(out_regs->doeptsiz));
04016 
04017                 /* Zero Length Packet */
04018                 deptsiz.b.xfersize = ep->maxpacket;
04019                 deptsiz.b.pktcnt = 1;
04020 
04021                 if (core_if->dma_enable) {
04022                         if (!core_if->dma_desc_enable) {
04023                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
04024                                                 deptsiz.d32);
04025 
04026                                 DWC_WRITE_REG32(&(out_regs->doepdma),
04027                                                 (uint32_t) ep->dma_addr);
04028                         }
04029                 } else {
04030                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04031                 }
04032 
04033                 /* EP enable */
04034                 depctl.b.cnak = 1;
04035                 depctl.b.epena = 1;
04036 
04037                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
04038 
04039         }
04040 }
04041 
04051 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04052 {
04053         depctl_data_t depctl;
04054         deptsiz0_data_t deptsiz;
04055         gintmsk_data_t intr_mask = {.d32 = 0 };
04056         dwc_otg_dev_dma_desc_t *dma_desc;
04057 
04058         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
04059                     "xfer_buff=%p start_xfer_buff=%p \n",
04060                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
04061                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
04062 
04063         ep->total_len = ep->xfer_len;
04064 
04065         /* IN endpoint */
04066         if (ep->is_in == 1) {
04067                 dwc_otg_dev_in_ep_regs_t *in_regs =
04068                     core_if->dev_if->in_ep_regs[0];
04069 
04070                 gnptxsts_data_t gtxstatus;
04071 
04072                 gtxstatus.d32 =
04073                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
04074 
04075                 if (core_if->en_multiple_tx_fifo == 0
04076                     && gtxstatus.b.nptxqspcavail == 0
04077                     && !core_if->dma_enable) {
04078 #ifdef DEBUG
04079                         deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04080                         DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
04081                                     DWC_READ_REG32(&in_regs->diepctl));
04082                         DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
04083                                     deptsiz.d32,
04084                                     deptsiz.b.xfersize, deptsiz.b.pktcnt);
04085                         DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
04086                                    gtxstatus.d32);
04087 #endif
04088                         return;
04089                 }
04090 
04091                 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
04092                 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04093 
04094                 /* Zero Length Packet? */
04095                 if (ep->xfer_len == 0) {
04096                         deptsiz.b.xfersize = 0;
04097                         deptsiz.b.pktcnt = 1;
04098                 } else {
04099                         /* Program the transfer size and packet count
04100                          *      as follows: xfersize = N * maxpacket +
04101                          *      short_packet pktcnt = N + (short_packet
04102                          *      exist ? 1 : 0) 
04103                          */
04104                         if (ep->xfer_len > ep->maxpacket) {
04105                                 ep->xfer_len = ep->maxpacket;
04106                                 deptsiz.b.xfersize = ep->maxpacket;
04107                         } else {
04108                                 deptsiz.b.xfersize = ep->xfer_len;
04109                         }
04110                         deptsiz.b.pktcnt = 1;
04111 
04112                 }
04113                 DWC_DEBUGPL(DBG_PCDV,
04114                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
04115                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04116                             deptsiz.d32);
04117 
04118                 /* Write the DMA register */
04119                 if (core_if->dma_enable) {
04120                         if (core_if->dma_desc_enable == 0) {
04121                                 DWC_WRITE_REG32(&in_regs->dieptsiz,
04122                                                 deptsiz.d32);
04123 
04124                                 DWC_WRITE_REG32(&(in_regs->diepdma),
04125                                                 (uint32_t) ep->dma_addr);
04126                         } else {
04127                                 dma_desc = core_if->dev_if->in_desc_addr;
04128 
04130                                 dma_desc->status.b.bs = BS_HOST_BUSY;
04131                                 dma_desc->status.b.l = 1;
04132                                 dma_desc->status.b.ioc = 1;
04133                                 dma_desc->status.b.sp =
04134                                     (ep->xfer_len == ep->maxpacket) ? 0 : 1;
04135                                 dma_desc->status.b.bytes = ep->xfer_len;
04136                                 dma_desc->buf = ep->dma_addr;
04137                                 dma_desc->status.b.sts = 0;
04138                                 dma_desc->status.b.bs = BS_HOST_READY;
04139 
04141                                 DWC_WRITE_REG32(&in_regs->diepdma,
04142                                                 core_if->
04143                                                 dev_if->dma_in_desc_addr);
04144                         }
04145                 } else {
04146                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
04147                 }
04148 
04149                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04150                         depctl.b.nextep = core_if->nextep_seq[ep->num];
04151                 /* EP enable, IN data in FIFO */
04152                 depctl.b.cnak = 1;
04153                 depctl.b.epena = 1;
04154                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04155 
04160                 if (!core_if->dma_enable) {
04161                         if (core_if->en_multiple_tx_fifo == 0) {
04162                                 intr_mask.b.nptxfempty = 1;
04163                                 DWC_MODIFY_REG32(&core_if->
04164                                                  core_global_regs->gintmsk,
04165                                                  intr_mask.d32, intr_mask.d32);
04166                         } else {
04167                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
04168                                 if (ep->xfer_len > 0) {
04169                                         uint32_t fifoemptymsk = 0;
04170                                         fifoemptymsk |= 1 << ep->num;
04171                                         DWC_MODIFY_REG32(&core_if->
04172                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
04173                                                          0, fifoemptymsk);
04174                                 }
04175                         }
04176                 }
04177         } else {
04178                 /* OUT endpoint */
04179                 dwc_otg_dev_out_ep_regs_t *out_regs =
04180                     core_if->dev_if->out_ep_regs[0];
04181 
04182                 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
04183                 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
04184 
04185                 /* Program the transfer size and packet count as follows:
04186                  *      xfersize = N * (maxpacket + 4 - (maxpacket % 4))
04187                  *      pktcnt = N                                                                                      */
04188                 /* Zero Length Packet */
04189                 deptsiz.b.xfersize = ep->maxpacket;
04190                 deptsiz.b.pktcnt = 1;
04191 
04192                 DWC_DEBUGPL(DBG_PCDV, "len=%d  xfersize=%d pktcnt=%d\n",
04193                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
04194 
04195                 if (core_if->dma_enable) {
04196                         if (!core_if->dma_desc_enable) {
04197                                 DWC_WRITE_REG32(&out_regs->doeptsiz,
04198                                                 deptsiz.d32);
04199 
04200                                 DWC_WRITE_REG32(&(out_regs->doepdma),
04201                                                 (uint32_t) ep->dma_addr);
04202                         } else {
04203                                 dma_desc = core_if->dev_if->out_desc_addr;
04204 
04206                                 dma_desc->status.b.bs = BS_HOST_BUSY;
04207                                 dma_desc->status.b.l = 1;
04208                                 dma_desc->status.b.ioc = 1;
04209                                 dma_desc->status.b.bytes = ep->maxpacket;
04210                                 dma_desc->buf = ep->dma_addr;
04211                                 dma_desc->status.b.sts = 0;
04212                                 dma_desc->status.b.bs = BS_HOST_READY;
04213 
04215                                 DWC_WRITE_REG32(&out_regs->doepdma,
04216                                                 core_if->
04217                                                 dev_if->dma_out_desc_addr);
04218                         }
04219                 } else {
04220                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04221                 }
04222 
04223                 /* EP enable */
04224                 depctl.b.cnak = 1;
04225                 depctl.b.epena = 1;
04226                 DWC_WRITE_REG32(&(out_regs->doepctl), depctl.d32);
04227         }
04228 }
04229 
04239 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04240 {
04241         depctl_data_t depctl;
04242         deptsiz0_data_t deptsiz;
04243         gintmsk_data_t intr_mask = {.d32 = 0 };
04244         dwc_otg_dev_dma_desc_t *dma_desc;
04245 
04246         if (ep->is_in == 1) {
04247                 dwc_otg_dev_in_ep_regs_t *in_regs =
04248                     core_if->dev_if->in_ep_regs[0];
04249                 gnptxsts_data_t tx_status = {.d32 = 0 };
04250 
04251                 tx_status.d32 =
04252                     DWC_READ_REG32(&core_if->core_global_regs->gnptxsts);
04256                 depctl.d32 = DWC_READ_REG32(&in_regs->diepctl);
04257                 deptsiz.d32 = DWC_READ_REG32(&in_regs->dieptsiz);
04258 
04259                 /* Program the transfer size and packet count
04260                  *      as follows: xfersize = N * maxpacket +
04261                  *      short_packet pktcnt = N + (short_packet
04262                  *      exist ? 1 : 0) 
04263                  */
04264 
04265                 if (core_if->dma_desc_enable == 0) {
04266                         deptsiz.b.xfersize =
04267                             (ep->total_len - ep->xfer_count) >
04268                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
04269                                                              ep->xfer_count);
04270                         deptsiz.b.pktcnt = 1;
04271                         if (core_if->dma_enable == 0) {
04272                                 ep->xfer_len += deptsiz.b.xfersize;
04273                         } else {
04274                                 ep->xfer_len = deptsiz.b.xfersize;
04275                         }
04276                         DWC_WRITE_REG32(&in_regs->dieptsiz, deptsiz.d32);
04277                 } else {
04278                         ep->xfer_len =
04279                             (ep->total_len - ep->xfer_count) >
04280                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
04281                                                              ep->xfer_count);
04282 
04283                         dma_desc = core_if->dev_if->in_desc_addr;
04284 
04286                         dma_desc->status.b.bs = BS_HOST_BUSY;
04287                         dma_desc->status.b.l = 1;
04288                         dma_desc->status.b.ioc = 1;
04289                         dma_desc->status.b.sp =
04290                             (ep->xfer_len == ep->maxpacket) ? 0 : 1;
04291                         dma_desc->status.b.bytes = ep->xfer_len;
04292                         dma_desc->buf = ep->dma_addr;
04293                         dma_desc->status.b.sts = 0;
04294                         dma_desc->status.b.bs = BS_HOST_READY;
04295 
04297                         DWC_WRITE_REG32(&in_regs->diepdma,
04298                                         core_if->dev_if->dma_in_desc_addr);
04299                 }
04300 
04301                 DWC_DEBUGPL(DBG_PCDV,
04302                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
04303                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04304                             deptsiz.d32);
04305 
04306                 /* Write the DMA register */
04307                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
04308                         if (core_if->dma_desc_enable == 0)
04309                                 DWC_WRITE_REG32(&(in_regs->diepdma),
04310                                                 (uint32_t) ep->dma_addr);
04311                 }
04312                 if (!core_if->core_params->en_multiple_tx_fifo && core_if->dma_enable)
04313                         depctl.b.nextep = core_if->nextep_seq[ep->num];
04314                 /* EP enable, IN data in FIFO */
04315                 depctl.b.cnak = 1;
04316                 depctl.b.epena = 1;
04317                 DWC_WRITE_REG32(&in_regs->diepctl, depctl.d32);
04318 
04323                 if (!core_if->dma_enable) {
04324                         if (core_if->en_multiple_tx_fifo == 0) {
04325                                 /* First clear it from GINTSTS */
04326                                 intr_mask.b.nptxfempty = 1;
04327                                 DWC_MODIFY_REG32(&core_if->
04328                                                  core_global_regs->gintmsk,
04329                                                  intr_mask.d32, intr_mask.d32);
04330 
04331                         } else {
04332                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
04333                                 if (ep->xfer_len > 0) {
04334                                         uint32_t fifoemptymsk = 0;
04335                                         fifoemptymsk |= 1 << ep->num;
04336                                         DWC_MODIFY_REG32(&core_if->
04337                                                          dev_if->dev_global_regs->dtknqr4_fifoemptymsk,
04338                                                          0, fifoemptymsk);
04339                                 }
04340                         }
04341                 }
04342         } else {
04343                 dwc_otg_dev_out_ep_regs_t *out_regs =
04344                     core_if->dev_if->out_ep_regs[0];
04345 
04346                 depctl.d32 = DWC_READ_REG32(&out_regs->doepctl);
04347                 deptsiz.d32 = DWC_READ_REG32(&out_regs->doeptsiz);
04348 
04349                 /* Program the transfer size and packet count
04350                  *      as follows: xfersize = N * maxpacket +
04351                  *      short_packet pktcnt = N + (short_packet
04352                  *      exist ? 1 : 0) 
04353                  */
04354                 deptsiz.b.xfersize = ep->maxpacket;
04355                 deptsiz.b.pktcnt = 1;
04356 
04357                 if (core_if->dma_desc_enable == 0) {
04358                         DWC_WRITE_REG32(&out_regs->doeptsiz, deptsiz.d32);
04359                 } else {
04360                         dma_desc = core_if->dev_if->out_desc_addr;
04361 
04363                         dma_desc->status.b.bs = BS_HOST_BUSY;
04364                         dma_desc->status.b.l = 1;
04365                         dma_desc->status.b.ioc = 1;
04366                         dma_desc->status.b.bytes = ep->maxpacket;
04367                         dma_desc->buf = ep->dma_addr;
04368                         dma_desc->status.b.sts = 0;
04369                         dma_desc->status.b.bs = BS_HOST_READY;
04370 
04372                         DWC_WRITE_REG32(&out_regs->doepdma,
04373                                         core_if->dev_if->dma_out_desc_addr);
04374                 }
04375 
04376                 DWC_DEBUGPL(DBG_PCDV,
04377                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
04378                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
04379                             deptsiz.d32);
04380 
04381                 /* Write the DMA register */
04382                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
04383                         if (core_if->dma_desc_enable == 0)
04384                                 DWC_WRITE_REG32(&(out_regs->doepdma),
04385                                                 (uint32_t) ep->dma_addr);
04386 
04387                 }
04388 
04389                 /* EP enable, IN data in FIFO */
04390                 depctl.b.cnak = 1;
04391                 depctl.b.epena = 1;
04392                 DWC_WRITE_REG32(&out_regs->doepctl, depctl.d32);
04393 
04394         }
04395 }
04396 
04397 #ifdef DEBUG
04398 void dump_msg(const u8 * buf, unsigned int length)
04399 {
04400         unsigned int start, num, i;
04401         char line[52], *p;
04402 
04403         if (length >= 512)
04404                 return;
04405         start = 0;
04406         while (length > 0) {
04407                 num = length < 16u ? length : 16u;
04408                 p = line;
04409                 for (i = 0; i < num; ++i) {
04410                         if (i == 8)
04411                                 *p++ = ' ';
04412                         DWC_SPRINTF(p, " %02x", buf[i]);
04413                         p += 3;
04414                 }
04415                 *p = 0;
04416                 DWC_PRINTF("%6x: %s\n", start, line);
04417                 buf += num;
04418                 start += num;
04419                 length -= num;
04420         }
04421 }
04422 #else
04423 static inline void dump_msg(const u8 * buf, unsigned int length)
04424 {
04425 }
04426 #endif
04427 
04438 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
04439                              int dma)
04440 {
04456         uint32_t i;
04457         uint32_t byte_count;
04458         uint32_t dword_count;
04459         uint32_t *fifo;
04460         uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
04461 
04462         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
04463                     ep);
04464         if (ep->xfer_count >= ep->xfer_len) {
04465                 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
04466                 return;
04467         }
04468 
04469         /* Find the byte length of the packet either short packet or MPS */
04470         if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
04471                 byte_count = ep->xfer_len - ep->xfer_count;
04472         } else {
04473                 byte_count = ep->maxpacket;
04474         }
04475 
04476         /* Find the DWORD length, padded by extra bytes as neccessary if MPS
04477          * is not a multiple of DWORD */
04478         dword_count = (byte_count + 3) / 4;
04479 
04480 #ifdef VERBOSE
04481         dump_msg(ep->xfer_buff, byte_count);
04482 #endif
04483 
04487         fifo = core_if->data_fifo[ep->num];
04488 
04489         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
04490                     fifo, data_buff, *data_buff, byte_count);
04491 
04492         if (!dma) {
04493                 for (i = 0; i < dword_count; i++, data_buff++) {
04494                         DWC_WRITE_REG32(fifo, *data_buff);
04495                 }
04496         }
04497 
04498         ep->xfer_count += byte_count;
04499         ep->xfer_buff += byte_count;
04500         ep->dma_addr += byte_count;
04501 }
04502 
04509 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04510 {
04511         depctl_data_t depctl;
04512         volatile uint32_t *depctl_addr;
04513 
04514         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
04515                     (ep->is_in ? "IN" : "OUT"));
04516 
04517         if (ep->is_in == 1) {
04518                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
04519                 depctl.d32 = DWC_READ_REG32(depctl_addr);
04520 
04521                 /* set the disable and stall bits */
04522                 if (depctl.b.epena) {
04523                         depctl.b.epdis = 1;
04524                 }
04525                 depctl.b.stall = 1;
04526                 DWC_WRITE_REG32(depctl_addr, depctl.d32);
04527         } else {
04528                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
04529                 depctl.d32 = DWC_READ_REG32(depctl_addr);
04530 
04531                 /* set the stall bit */
04532                 depctl.b.stall = 1;
04533                 DWC_WRITE_REG32(depctl_addr, depctl.d32);
04534         }
04535 
04536         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
04537 
04538         return;
04539 }
04540 
04547 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
04548 {
04549         depctl_data_t depctl;
04550         volatile uint32_t *depctl_addr;
04551 
04552         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
04553                     (ep->is_in ? "IN" : "OUT"));
04554 
04555         if (ep->is_in == 1) {
04556                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
04557         } else {
04558                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
04559         }
04560 
04561         depctl.d32 = DWC_READ_REG32(depctl_addr);
04562 
04563         /* clear the stall bits */
04564         depctl.b.stall = 0;
04565 
04566         /*
04567          * USB Spec 9.4.5: For endpoints using data toggle, regardless
04568          * of whether an endpoint has the Halt feature set, a
04569          * ClearFeature(ENDPOINT_HALT) request always results in the
04570          * data toggle being reinitialized to DATA0.
04571          */
04572         if (ep->type == DWC_OTG_EP_TYPE_INTR ||
04573             ep->type == DWC_OTG_EP_TYPE_BULK) {
04574                 depctl.b.setd0pid = 1;  /* DATA0 */
04575         }
04576 
04577         DWC_WRITE_REG32(depctl_addr, depctl.d32);
04578         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", DWC_READ_REG32(depctl_addr));
04579         return;
04580 }
04581 
04590 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
04591                          uint8_t * dest, uint16_t bytes)
04592 {
04593         int i;
04594         int word_count = (bytes + 3) / 4;
04595 
04596         volatile uint32_t *fifo = core_if->data_fifo[0];
04597         uint32_t *data_buff = (uint32_t *) dest;
04598 
04605         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
04606                     core_if, dest, bytes);
04607 
04608         for (i = 0; i < word_count; i++, data_buff++) {
04609                 *data_buff = DWC_READ_REG32(fifo);
04610         }
04611 
04612         return;
04613 }
04614 
04620 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
04621 {
04622         int i;
04623         volatile uint32_t *addr;
04624 
04625         DWC_PRINTF("Device Global Registers\n");
04626         addr = &core_if->dev_if->dev_global_regs->dcfg;
04627         DWC_PRINTF("DCFG                 @0x%08lX : 0x%08X\n", (unsigned long) addr,
04628                    DWC_READ_REG32(addr));
04629         addr = &core_if->dev_if->dev_global_regs->dctl;
04630         DWC_PRINTF("DCTL                 @0x%08lX : 0x%08X\n", (unsigned long) addr,
04631                    DWC_READ_REG32(addr));
04632         addr = &core_if->dev_if->dev_global_regs->dsts;
04633         DWC_PRINTF("DSTS                 @0x%08lX : 0x%08X\n", (unsigned long) addr,
04634                    DWC_READ_REG32(addr));
04635         addr = &core_if->dev_if->dev_global_regs->diepmsk;
04636         DWC_PRINTF("DIEPMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04637                    DWC_READ_REG32(addr));
04638         addr = &core_if->dev_if->dev_global_regs->doepmsk;
04639         DWC_PRINTF("DOEPMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04640                    DWC_READ_REG32(addr));
04641         addr = &core_if->dev_if->dev_global_regs->daint;
04642         DWC_PRINTF("DAINT        @0x%08lX : 0x%08X\n", (unsigned long)addr,
04643                    DWC_READ_REG32(addr));
04644         addr = &core_if->dev_if->dev_global_regs->daintmsk;
04645         DWC_PRINTF("DAINTMSK     @0x%08lX : 0x%08X\n", (unsigned long)addr,
04646                    DWC_READ_REG32(addr));
04647         addr = &core_if->dev_if->dev_global_regs->dtknqr1;
04648         DWC_PRINTF("DTKNQR1      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04649                    DWC_READ_REG32(addr));
04650         if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
04651                 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
04652                 DWC_PRINTF("DTKNQR2      @0x%08lX : 0x%08X\n",
04653                            (unsigned long)addr, DWC_READ_REG32(addr));
04654         }
04655 
04656         addr = &core_if->dev_if->dev_global_regs->dvbusdis;
04657         DWC_PRINTF("DVBUSID      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04658                    DWC_READ_REG32(addr));
04659 
04660         addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
04661         DWC_PRINTF("DVBUSPULSE  @0x%08lX : 0x%08X\n",
04662                    (unsigned long)addr, DWC_READ_REG32(addr));
04663 
04664         addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
04665         DWC_PRINTF("DTKNQR3_DTHRCTL      @0x%08lX : 0x%08X\n",
04666                    (unsigned long)addr, DWC_READ_REG32(addr));
04667 
04668         if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
04669                 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
04670                 DWC_PRINTF("DTKNQR4      @0x%08lX : 0x%08X\n",
04671                            (unsigned long)addr, DWC_READ_REG32(addr));
04672         }
04673 
04674         addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
04675         DWC_PRINTF("FIFOEMPMSK   @0x%08lX : 0x%08X\n", (unsigned long)addr,
04676                    DWC_READ_REG32(addr));
04677 
04678         if (core_if->hwcfg2.b.multi_proc_int) {
04679 
04680                 addr = &core_if->dev_if->dev_global_regs->deachint;
04681                 DWC_PRINTF("DEACHINT     @0x%08lX : 0x%08X\n",
04682                            (unsigned long)addr, DWC_READ_REG32(addr));
04683                 addr = &core_if->dev_if->dev_global_regs->deachintmsk;
04684                 DWC_PRINTF("DEACHINTMSK  @0x%08lX : 0x%08X\n",
04685                            (unsigned long)addr, DWC_READ_REG32(addr));
04686 
04687                 for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
04688                         addr =
04689                             &core_if->dev_if->dev_global_regs->
04690                             diepeachintmsk[i];
04691                         DWC_PRINTF("DIEPEACHINTMSK[%d]   @0x%08lX : 0x%08X\n",
04692                                    i, (unsigned long)addr,
04693                                    DWC_READ_REG32(addr));
04694                 }
04695 
04696                 for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
04697                         addr =
04698                             &core_if->dev_if->dev_global_regs->
04699                             doepeachintmsk[i];
04700                         DWC_PRINTF("DOEPEACHINTMSK[%d]   @0x%08lX : 0x%08X\n",
04701                                    i, (unsigned long)addr,
04702                                    DWC_READ_REG32(addr));
04703                 }
04704         }
04705 
04706         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
04707                 DWC_PRINTF("Device IN EP %d Registers\n", i);
04708                 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
04709                 DWC_PRINTF("DIEPCTL      @0x%08lX : 0x%08X\n",
04710                            (unsigned long)addr, DWC_READ_REG32(addr));
04711                 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
04712                 DWC_PRINTF("DIEPINT      @0x%08lX : 0x%08X\n",
04713                            (unsigned long)addr, DWC_READ_REG32(addr));
04714                 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
04715                 DWC_PRINTF("DIETSIZ      @0x%08lX : 0x%08X\n",
04716                            (unsigned long)addr, DWC_READ_REG32(addr));
04717                 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
04718                 DWC_PRINTF("DIEPDMA      @0x%08lX : 0x%08X\n",
04719                            (unsigned long)addr, DWC_READ_REG32(addr));
04720                 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
04721                 DWC_PRINTF("DTXFSTS      @0x%08lX : 0x%08X\n",
04722                            (unsigned long)addr, DWC_READ_REG32(addr));
04723                 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
04724                 DWC_PRINTF("DIEPDMAB     @0x%08lX : 0x%08X\n",
04725                            (unsigned long)addr, 0 /*DWC_READ_REG32(addr) */ );
04726         }
04727 
04728         for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
04729                 DWC_PRINTF("Device OUT EP %d Registers\n", i);
04730                 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
04731                 DWC_PRINTF("DOEPCTL      @0x%08lX : 0x%08X\n",
04732                            (unsigned long)addr, DWC_READ_REG32(addr));
04733                 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
04734                 DWC_PRINTF("DOEPINT      @0x%08lX : 0x%08X\n",
04735                            (unsigned long)addr, DWC_READ_REG32(addr));
04736                 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
04737                 DWC_PRINTF("DOETSIZ      @0x%08lX : 0x%08X\n",
04738                            (unsigned long)addr, DWC_READ_REG32(addr));
04739                 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
04740                 DWC_PRINTF("DOEPDMA      @0x%08lX : 0x%08X\n",
04741                            (unsigned long)addr, DWC_READ_REG32(addr));
04742                 if (core_if->dma_enable) {      /* Don't access this register in SLAVE mode */
04743                         addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
04744                         DWC_PRINTF("DOEPDMAB     @0x%08lX : 0x%08X\n",
04745                                    (unsigned long)addr, DWC_READ_REG32(addr));
04746                 }
04747 
04748         }
04749 }
04750 
04756 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
04757 {
04758         volatile uint8_t *addr, *start_addr, *end_addr;
04759 
04760         DWC_PRINTF("SPRAM Data:\n");
04761         start_addr = (void *)core_if->core_global_regs;
04762         DWC_PRINTF("Base Address: 0x%8lX\n", (unsigned long)start_addr);
04763         start_addr += 0x00028000;
04764         end_addr = (void *)core_if->core_global_regs;
04765         end_addr += 0x000280e0;
04766 
04767         for (addr = start_addr; addr < end_addr; addr += 16) {
04768                 DWC_PRINTF
04769                     ("0x%8lX:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
04770                      (unsigned long)addr, addr[0], addr[1], addr[2], addr[3],
04771                      addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
04772                      addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
04773                     );
04774         }
04775 
04776         return;
04777 }
04778 
04784 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
04785 {
04786         int i;
04787         volatile uint32_t *addr;
04788 
04789         DWC_PRINTF("Host Global Registers\n");
04790         addr = &core_if->host_if->host_global_regs->hcfg;
04791         DWC_PRINTF("HCFG                 @0x%08lX : 0x%08X\n",
04792                    (unsigned long)addr, DWC_READ_REG32(addr));
04793         addr = &core_if->host_if->host_global_regs->hfir;
04794         DWC_PRINTF("HFIR                 @0x%08lX : 0x%08X\n",
04795                    (unsigned long)addr, DWC_READ_REG32(addr));
04796         addr = &core_if->host_if->host_global_regs->hfnum;
04797         DWC_PRINTF("HFNUM        @0x%08lX : 0x%08X\n", (unsigned long)addr,
04798                    DWC_READ_REG32(addr));
04799         addr = &core_if->host_if->host_global_regs->hptxsts;
04800         DWC_PRINTF("HPTXSTS      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04801                    DWC_READ_REG32(addr));
04802         addr = &core_if->host_if->host_global_regs->haint;
04803         DWC_PRINTF("HAINT        @0x%08lX : 0x%08X\n", (unsigned long)addr,
04804                    DWC_READ_REG32(addr));
04805         addr = &core_if->host_if->host_global_regs->haintmsk;
04806         DWC_PRINTF("HAINTMSK     @0x%08lX : 0x%08X\n", (unsigned long)addr,
04807                    DWC_READ_REG32(addr));
04808         if (core_if->dma_desc_enable) {
04809                 addr = &core_if->host_if->host_global_regs->hflbaddr;
04810                 DWC_PRINTF("HFLBADDR     @0x%08lX : 0x%08X\n",
04811                            (unsigned long)addr, DWC_READ_REG32(addr));
04812         }
04813 
04814         addr = core_if->host_if->hprt0;
04815         DWC_PRINTF("HPRT0        @0x%08lX : 0x%08X\n", (unsigned long)addr,
04816                    DWC_READ_REG32(addr));
04817 
04818         for (i = 0; i < core_if->core_params->host_channels; i++) {
04819                 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
04820                 addr = &core_if->host_if->hc_regs[i]->hcchar;
04821                 DWC_PRINTF("HCCHAR       @0x%08lX : 0x%08X\n",
04822                            (unsigned long)addr, DWC_READ_REG32(addr));
04823                 addr = &core_if->host_if->hc_regs[i]->hcsplt;
04824                 DWC_PRINTF("HCSPLT       @0x%08lX : 0x%08X\n",
04825                            (unsigned long)addr, DWC_READ_REG32(addr));
04826                 addr = &core_if->host_if->hc_regs[i]->hcint;
04827                 DWC_PRINTF("HCINT        @0x%08lX : 0x%08X\n",
04828                            (unsigned long)addr, DWC_READ_REG32(addr));
04829                 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
04830                 DWC_PRINTF("HCINTMSK     @0x%08lX : 0x%08X\n",
04831                            (unsigned long)addr, DWC_READ_REG32(addr));
04832                 addr = &core_if->host_if->hc_regs[i]->hctsiz;
04833                 DWC_PRINTF("HCTSIZ       @0x%08lX : 0x%08X\n",
04834                            (unsigned long)addr, DWC_READ_REG32(addr));
04835                 addr = &core_if->host_if->hc_regs[i]->hcdma;
04836                 DWC_PRINTF("HCDMA        @0x%08lX : 0x%08X\n",
04837                            (unsigned long)addr, DWC_READ_REG32(addr));
04838                 if (core_if->dma_desc_enable) {
04839                         addr = &core_if->host_if->hc_regs[i]->hcdmab;
04840                         DWC_PRINTF("HCDMAB       @0x%08lX : 0x%08X\n",
04841                                    (unsigned long)addr, DWC_READ_REG32(addr));
04842                 }
04843 
04844         }
04845         return;
04846 }
04847 
04853 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
04854 {
04855         int i, ep_num;
04856         volatile uint32_t *addr;
04857         char *txfsiz;
04858 
04859         DWC_PRINTF("Core Global Registers\n");
04860         addr = &core_if->core_global_regs->gotgctl;
04861         DWC_PRINTF("GOTGCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04862                    DWC_READ_REG32(addr));
04863         addr = &core_if->core_global_regs->gotgint;
04864         DWC_PRINTF("GOTGINT      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04865                    DWC_READ_REG32(addr));
04866         addr = &core_if->core_global_regs->gahbcfg;
04867         DWC_PRINTF("GAHBCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04868                    DWC_READ_REG32(addr));
04869         addr = &core_if->core_global_regs->gusbcfg;
04870         DWC_PRINTF("GUSBCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04871                    DWC_READ_REG32(addr));
04872         addr = &core_if->core_global_regs->grstctl;
04873         DWC_PRINTF("GRSTCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04874                    DWC_READ_REG32(addr));
04875         addr = &core_if->core_global_regs->gintsts;
04876         DWC_PRINTF("GINTSTS      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04877                    DWC_READ_REG32(addr));
04878         addr = &core_if->core_global_regs->gintmsk;
04879         DWC_PRINTF("GINTMSK      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04880                    DWC_READ_REG32(addr));
04881         addr = &core_if->core_global_regs->grxstsr;
04882         DWC_PRINTF("GRXSTSR      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04883                    DWC_READ_REG32(addr));
04884         addr = &core_if->core_global_regs->grxfsiz;
04885         DWC_PRINTF("GRXFSIZ      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04886                    DWC_READ_REG32(addr));
04887         addr = &core_if->core_global_regs->gnptxfsiz;
04888         DWC_PRINTF("GNPTXFSIZ @0x%08lX : 0x%08X\n", (unsigned long)addr,
04889                    DWC_READ_REG32(addr));
04890         addr = &core_if->core_global_regs->gnptxsts;
04891         DWC_PRINTF("GNPTXSTS     @0x%08lX : 0x%08X\n", (unsigned long)addr,
04892                    DWC_READ_REG32(addr));
04893         addr = &core_if->core_global_regs->gi2cctl;
04894         DWC_PRINTF("GI2CCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04895                    DWC_READ_REG32(addr));
04896         addr = &core_if->core_global_regs->gpvndctl;
04897         DWC_PRINTF("GPVNDCTL     @0x%08lX : 0x%08X\n", (unsigned long)addr,
04898                    DWC_READ_REG32(addr));
04899         addr = &core_if->core_global_regs->ggpio;
04900         DWC_PRINTF("GGPIO        @0x%08lX : 0x%08X\n", (unsigned long)addr,
04901                    DWC_READ_REG32(addr));
04902         addr = &core_if->core_global_regs->guid;
04903         DWC_PRINTF("GUID                 @0x%08lX : 0x%08X\n",
04904                    (unsigned long)addr, DWC_READ_REG32(addr));
04905         addr = &core_if->core_global_regs->gsnpsid;
04906         DWC_PRINTF("GSNPSID      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04907                    DWC_READ_REG32(addr));
04908         addr = &core_if->core_global_regs->ghwcfg1;
04909         DWC_PRINTF("GHWCFG1      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04910                    DWC_READ_REG32(addr));
04911         addr = &core_if->core_global_regs->ghwcfg2;
04912         DWC_PRINTF("GHWCFG2      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04913                    DWC_READ_REG32(addr));
04914         addr = &core_if->core_global_regs->ghwcfg3;
04915         DWC_PRINTF("GHWCFG3      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04916                    DWC_READ_REG32(addr));
04917         addr = &core_if->core_global_regs->ghwcfg4;
04918         DWC_PRINTF("GHWCFG4      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04919                    DWC_READ_REG32(addr));
04920         addr = &core_if->core_global_regs->glpmcfg;
04921         DWC_PRINTF("GLPMCFG      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04922                    DWC_READ_REG32(addr));
04923         addr = &core_if->core_global_regs->gpwrdn;
04924         DWC_PRINTF("GPWRDN       @0x%08lX : 0x%08X\n", (unsigned long)addr,
04925                    DWC_READ_REG32(addr));
04926         addr = &core_if->core_global_regs->gdfifocfg;
04927         DWC_PRINTF("GDFIFOCFG    @0x%08lX : 0x%08X\n", (unsigned long)addr,
04928                    DWC_READ_REG32(addr));
04929         addr = &core_if->core_global_regs->adpctl;
04930         DWC_PRINTF("ADPCTL       @0x%08lX : 0x%08X\n", (unsigned long)addr,
04931                    dwc_otg_adp_read_reg(core_if));
04932         addr = &core_if->core_global_regs->hptxfsiz;
04933         DWC_PRINTF("HPTXFSIZ     @0x%08lX : 0x%08X\n", (unsigned long)addr,
04934                    DWC_READ_REG32(addr));
04935 
04936         if (core_if->en_multiple_tx_fifo == 0) {
04937                 ep_num = core_if->hwcfg4.b.num_dev_perio_in_ep;
04938                 txfsiz = "DPTXFSIZ";
04939         } else {
04940                 ep_num = core_if->hwcfg4.b.num_in_eps;
04941                 txfsiz = "DIENPTXF";
04942         }
04943         for (i = 0; i < ep_num; i++) {
04944                 addr = &core_if->core_global_regs->dtxfsiz[i];
04945                 DWC_PRINTF("%s[%d] @0x%08lX : 0x%08X\n", txfsiz, i + 1,
04946                            (unsigned long)addr, DWC_READ_REG32(addr));
04947         }
04948         addr = core_if->pcgcctl;
04949         DWC_PRINTF("PCGCCTL      @0x%08lX : 0x%08X\n", (unsigned long)addr,
04950                    DWC_READ_REG32(addr));
04951 }
04952 
04959 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
04960 {
04961         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04962         volatile grstctl_t greset = {.d32 = 0 };
04963         int count = 0;
04964 
04965         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
04966 
04967         greset.b.txfflsh = 1;
04968         greset.b.txfnum = num;
04969         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
04970 
04971         do {
04972                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
04973                 if (++count > 10000) {
04974                         DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
04975                                  __func__, greset.d32,
04976                                  DWC_READ_REG32(&global_regs->gnptxsts));
04977                         break;
04978                 }
04979                 dwc_udelay(1);
04980         } while (greset.b.txfflsh == 1);
04981 
04982         /* Wait for 3 PHY Clocks */
04983         dwc_udelay(1);
04984 }
04985 
04991 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
04992 {
04993         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
04994         volatile grstctl_t greset = {.d32 = 0 };
04995         int count = 0;
04996 
04997         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
04998         /*
04999          *
05000          */
05001         greset.b.rxfflsh = 1;
05002         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
05003 
05004         do {
05005                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05006                 if (++count > 10000) {
05007                         DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
05008                                  greset.d32);
05009                         break;
05010                 }
05011                 dwc_udelay(1);
05012         } while (greset.b.rxfflsh == 1);
05013 
05014         /* Wait for 3 PHY Clocks */
05015         dwc_udelay(1);
05016 }
05017 
05022 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
05023 {
05024         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
05025         volatile grstctl_t greset = {.d32 = 0 };
05026         int count = 0;
05027 
05028         DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
05029         /* Wait for AHB master IDLE state. */
05030         do {
05031                 dwc_udelay(10);
05032                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05033                 if (++count > 100000) {
05034                         DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
05035                                  greset.d32);
05036                         return;
05037                 }
05038         }
05039         while (greset.b.ahbidle == 0);
05040 
05041         /* Core Soft Reset */
05042         count = 0;
05043         greset.b.csftrst = 1;
05044         DWC_WRITE_REG32(&global_regs->grstctl, greset.d32);
05045         do {
05046                 greset.d32 = DWC_READ_REG32(&global_regs->grstctl);
05047                 if (++count > 10000) {
05048                         DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
05049                                  __func__, greset.d32);
05050                         break;
05051                 }
05052                 dwc_udelay(1);
05053         }
05054         while (greset.b.csftrst == 1);
05055 
05056         /* Wait for 3 PHY Clocks */
05057         dwc_mdelay(100);
05058 }
05059 
05060 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
05061 {
05062         return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
05063 }
05064 
05065 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
05066 {
05067         return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
05068 }
05069 
05078 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
05079                                         dwc_otg_cil_callbacks_t * cb, void *p)
05080 {
05081         core_if->hcd_cb = cb;
05082         cb->p = p;
05083 }
05084 
05093 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
05094                                         dwc_otg_cil_callbacks_t * cb, void *p)
05095 {
05096         core_if->pcd_cb = cb;
05097         cb->p = p;
05098 }
05099 
05100 #ifdef DWC_EN_ISOC
05101 
05109 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
05110 {
05111         dwc_otg_dev_in_ep_regs_t *ep_regs;
05112         dtxfsts_data_t txstatus = {.d32 = 0 };
05113         uint32_t len = 0;
05114         uint32_t dwords;
05115 
05116         ep->xfer_len = ep->data_per_frame;
05117         ep->xfer_count = 0;
05118 
05119         ep_regs = core_if->dev_if->in_ep_regs[ep->num];
05120 
05121         len = ep->xfer_len - ep->xfer_count;
05122 
05123         if (len > ep->maxpacket) {
05124                 len = ep->maxpacket;
05125         }
05126 
05127         dwords = (len + 3) / 4;
05128 
05129         /* While there is space in the queue and space in the FIFO and
05130          * More data to tranfer, Write packets to the Tx FIFO */
05131         txstatus.d32 =
05132             DWC_READ_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
05133         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
05134 
05135         while (txstatus.b.txfspcavail > dwords &&
05136                ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
05137                 /* Write the FIFO */
05138                 dwc_otg_ep_write_packet(core_if, ep, 0);
05139 
05140                 len = ep->xfer_len - ep->xfer_count;
05141                 if (len > ep->maxpacket) {
05142                         len = ep->maxpacket;
05143                 }
05144 
05145                 dwords = (len + 3) / 4;
05146                 txstatus.d32 =
05147                     DWC_READ_REG32(&core_if->dev_if->
05148                                    in_ep_regs[ep->num]->dtxfsts);
05149                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
05150                             txstatus.d32);
05151         }
05152 }
05153 
05161 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
05162                                        dwc_ep_t * ep)
05163 {
05164         deptsiz_data_t deptsiz = {.d32 = 0 };
05165         depctl_data_t depctl = {.d32 = 0 };
05166         dsts_data_t dsts = {.d32 = 0 };
05167         volatile uint32_t *addr;
05168 
05169         if (ep->is_in) {
05170                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
05171         } else {
05172                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
05173         }
05174 
05175         ep->xfer_len = ep->data_per_frame;
05176         ep->xfer_count = 0;
05177         ep->xfer_buff = ep->cur_pkt_addr;
05178         ep->dma_addr = ep->cur_pkt_dma_addr;
05179 
05180         if (ep->is_in) {
05181                 /* Program the transfer size and packet count
05182                  *      as follows: xfersize = N * maxpacket +
05183                  *      short_packet pktcnt = N + (short_packet
05184                  *      exist ? 1 : 0) 
05185                  */
05186                 deptsiz.b.xfersize = ep->xfer_len;
05187                 deptsiz.b.pktcnt =
05188                     (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
05189                 deptsiz.b.mc = deptsiz.b.pktcnt;
05190                 DWC_WRITE_REG32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
05191                                 deptsiz.d32);
05192 
05193                 /* Write the DMA register */
05194                 if (core_if->dma_enable) {
05195                         DWC_WRITE_REG32(&
05196                                         (core_if->dev_if->in_ep_regs[ep->num]->
05197                                          diepdma), (uint32_t) ep->dma_addr);
05198                 }
05199         } else {
05200                 deptsiz.b.pktcnt =
05201                     (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
05202                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
05203 
05204                 DWC_WRITE_REG32(&core_if->dev_if->out_ep_regs[ep->num]->
05205                                 doeptsiz, deptsiz.d32);
05206 
05207                 if (core_if->dma_enable) {
05208                         DWC_WRITE_REG32(&
05209                                         (core_if->dev_if->out_ep_regs[ep->num]->
05210                                          doepdma), (uint32_t) ep->dma_addr);
05211                 }
05212         }
05213 
05216         depctl.d32 = 0;
05217         if (ep->bInterval == 1) {
05218                 dsts.d32 =
05219                     DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
05220                 ep->next_frame = dsts.b.soffn + ep->bInterval;
05221 
05222                 if (ep->next_frame & 0x1) {
05223                         depctl.b.setd1pid = 1;
05224                 } else {
05225                         depctl.b.setd0pid = 1;
05226                 }
05227         } else {
05228                 ep->next_frame += ep->bInterval;
05229 
05230                 if (ep->next_frame & 0x1) {
05231                         depctl.b.setd1pid = 1;
05232                 } else {
05233                         depctl.b.setd0pid = 1;
05234                 }
05235         }
05236         depctl.b.epena = 1;
05237         depctl.b.cnak = 1;
05238 
05239         DWC_MODIFY_REG32(addr, 0, depctl.d32);
05240         depctl.d32 = DWC_READ_REG32(addr);
05241 
05242         if (ep->is_in && core_if->dma_enable == 0) {
05243                 write_isoc_frame_data(core_if, ep);
05244         }
05245 
05246 }
05247 #endif /* DWC_EN_ISOC */
05248 
05249 static void dwc_otg_set_uninitialized(int32_t * p, int size)
05250 {
05251         int i;
05252         for (i = 0; i < size; i++) {
05253                 p[i] = -1;
05254         }
05255 }
05256 
05257 static int dwc_otg_param_initialized(int32_t val)
05258 {
05259         return val != -1;
05260 }
05261 
05262 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
05263 {
05264         int i;
05265         core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
05266         if (!core_if->core_params) {
05267                 return -DWC_E_NO_MEMORY;
05268         }
05269         dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
05270                                   sizeof(*core_if->core_params) /
05271                                   sizeof(int32_t));
05272         DWC_PRINTF("Setting default values for core params\n");
05273         dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
05274         dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
05275         dwc_otg_set_param_dma_desc_enable(core_if,
05276                                           dwc_param_dma_desc_enable_default);
05277         dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
05278         dwc_otg_set_param_dma_burst_size(core_if,
05279                                          dwc_param_dma_burst_size_default);
05280         dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
05281                                                        dwc_param_host_support_fs_ls_low_power_default);
05282         dwc_otg_set_param_enable_dynamic_fifo(core_if,
05283                                               dwc_param_enable_dynamic_fifo_default);
05284         dwc_otg_set_param_data_fifo_size(core_if,
05285                                          dwc_param_data_fifo_size_default);
05286         dwc_otg_set_param_dev_rx_fifo_size(core_if,
05287                                            dwc_param_dev_rx_fifo_size_default);
05288         dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
05289                                                   dwc_param_dev_nperio_tx_fifo_size_default);
05290         dwc_otg_set_param_host_rx_fifo_size(core_if,
05291                                             dwc_param_host_rx_fifo_size_default);
05292         dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
05293                                                    dwc_param_host_nperio_tx_fifo_size_default);
05294         dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
05295                                                   dwc_param_host_perio_tx_fifo_size_default);
05296         dwc_otg_set_param_max_transfer_size(core_if,
05297                                             dwc_param_max_transfer_size_default);
05298         dwc_otg_set_param_max_packet_count(core_if,
05299                                            dwc_param_max_packet_count_default);
05300         dwc_otg_set_param_host_channels(core_if,
05301                                         dwc_param_host_channels_default);
05302         dwc_otg_set_param_dev_endpoints(core_if,
05303                                         dwc_param_dev_endpoints_default);
05304         dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
05305         dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
05306         dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
05307                                                     dwc_param_host_ls_low_power_phy_clk_default);
05308         dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
05309         dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
05310                                             dwc_param_phy_ulpi_ext_vbus_default);
05311         dwc_otg_set_param_phy_utmi_width(core_if,
05312                                          dwc_param_phy_utmi_width_default);
05313         dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
05314         dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
05315         dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
05316         dwc_otg_set_param_en_multiple_tx_fifo(core_if,
05317                                               dwc_param_en_multiple_tx_fifo_default);
05318         for (i = 0; i < 15; i++) {
05319                 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
05320                                                          dwc_param_dev_perio_tx_fifo_size_default,
05321                                                          i);
05322         }
05323 
05324         for (i = 0; i < 15; i++) {
05325                 dwc_otg_set_param_dev_tx_fifo_size(core_if,
05326                                                    dwc_param_dev_tx_fifo_size_default,
05327                                                    i);
05328         }
05329         dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
05330         dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
05331         dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
05332         dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
05333         dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
05334         dwc_otg_set_param_tx_thr_length(core_if,
05335                                         dwc_param_tx_thr_length_default);
05336         dwc_otg_set_param_rx_thr_length(core_if,
05337                                         dwc_param_rx_thr_length_default);
05338         dwc_otg_set_param_ahb_thr_ratio(core_if,
05339                                         dwc_param_ahb_thr_ratio_default);
05340         dwc_otg_set_param_power_down(core_if, dwc_param_power_down_default);
05341         dwc_otg_set_param_reload_ctl(core_if, dwc_param_reload_ctl_default);
05342         dwc_otg_set_param_dev_out_nak(core_if, dwc_param_dev_out_nak_default);
05343         dwc_otg_set_param_cont_on_bna(core_if, dwc_param_cont_on_bna_default);
05344         dwc_otg_set_param_ahb_single(core_if, dwc_param_ahb_single_default);
05345         dwc_otg_set_param_otg_ver(core_if, dwc_param_otg_ver_default);
05346         dwc_otg_set_param_adp_enable(core_if, dwc_param_adp_enable_default);
05347         return 0;
05348 }
05349 
05350 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
05351 {
05352         return core_if->dma_enable;
05353 }
05354 
05355 /* Checks if the parameter is outside of its valid range of values */
05356 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
05357                 (((_param_) < (_low_)) || \
05358                 ((_param_) > (_high_)))
05359 
05360 /* Parameter access functions */
05361 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
05362 {
05363         int valid;
05364         int retval = 0;
05365         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
05366                 DWC_WARN("Wrong value for otg_cap parameter\n");
05367                 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
05368                 retval = -DWC_E_INVALID;
05369                 goto out;
05370         }
05371 
05372         valid = 1;
05373         switch (val) {
05374         case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
05375                 if (core_if->hwcfg2.b.op_mode !=
05376                     DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05377                         valid = 0;
05378                 break;
05379         case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
05380                 if ((core_if->hwcfg2.b.op_mode !=
05381                      DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05382                     && (core_if->hwcfg2.b.op_mode !=
05383                         DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
05384                     && (core_if->hwcfg2.b.op_mode !=
05385                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
05386                     && (core_if->hwcfg2.b.op_mode !=
05387                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
05388                         valid = 0;
05389                 }
05390                 break;
05391         case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
05392                 /* always valid */
05393                 break;
05394         }
05395         if (!valid) {
05396                 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
05397                         DWC_ERROR
05398                             ("%d invalid for otg_cap paremter. Check HW configuration.\n",
05399                              val);
05400                 }
05401                 val =
05402                     (((core_if->hwcfg2.b.op_mode ==
05403                        DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
05404                       || (core_if->hwcfg2.b.op_mode ==
05405                           DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
05406                       || (core_if->hwcfg2.b.op_mode ==
05407                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
05408                       || (core_if->hwcfg2.b.op_mode ==
05409                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
05410                      DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
05411                      DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
05412                 retval = -DWC_E_INVALID;
05413         }
05414 
05415         core_if->core_params->otg_cap = val;
05416 out:
05417         return retval;
05418 }
05419 
05420 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
05421 {
05422         return core_if->core_params->otg_cap;
05423 }
05424 
05425 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
05426 {
05427         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05428                 DWC_WARN("Wrong value for opt parameter\n");
05429                 return -DWC_E_INVALID;
05430         }
05431         core_if->core_params->opt = val;
05432         return 0;
05433 }
05434 
05435 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
05436 {
05437         return core_if->core_params->opt;
05438 }
05439 
05440 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
05441 {
05442         int retval = 0;
05443         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05444                 DWC_WARN("Wrong value for dma enable\n");
05445                 return -DWC_E_INVALID;
05446         }
05447 
05448         if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
05449                 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
05450                         DWC_ERROR
05451                             ("%d invalid for dma_enable paremter. Check HW configuration.\n",
05452                              val);
05453                 }
05454                 val = 0;
05455                 retval = -DWC_E_INVALID;
05456         }
05457 
05458         core_if->core_params->dma_enable = val;
05459         if (val == 0) {
05460                 dwc_otg_set_param_dma_desc_enable(core_if, 0);
05461         }
05462         return retval;
05463 }
05464 
05465 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
05466 {
05467         return core_if->core_params->dma_enable;
05468 }
05469 
05470 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
05471 {
05472         int retval = 0;
05473         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05474                 DWC_WARN("Wrong value for dma_enable\n");
05475                 DWC_WARN("dma_desc_enable must be 0 or 1\n");
05476                 return -DWC_E_INVALID;
05477         }
05478 
05479         if ((val == 1)
05480             && ((dwc_otg_get_param_dma_enable(core_if) == 0)
05481                 || (core_if->hwcfg4.b.desc_dma == 0))) {
05482                 if (dwc_otg_param_initialized
05483                     (core_if->core_params->dma_desc_enable)) {
05484                         DWC_ERROR
05485                             ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
05486                              val);
05487                 }
05488                 val = 0;
05489                 retval = -DWC_E_INVALID;
05490         }
05491         core_if->core_params->dma_desc_enable = val;
05492         return retval;
05493 }
05494 
05495 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
05496 {
05497         return core_if->core_params->dma_desc_enable;
05498 }
05499 
05500 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
05501                                                    int32_t val)
05502 {
05503         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05504                 DWC_WARN("Wrong value for host_support_fs_low_power\n");
05505                 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
05506                 return -DWC_E_INVALID;
05507         }
05508         core_if->core_params->host_support_fs_ls_low_power = val;
05509         return 0;
05510 }
05511 
05512 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
05513                                                        core_if)
05514 {
05515         return core_if->core_params->host_support_fs_ls_low_power;
05516 }
05517 
05518 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
05519                                           int32_t val)
05520 {
05521         int retval = 0;
05522         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05523                 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
05524                 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
05525                 return -DWC_E_INVALID;
05526         }
05527 
05528         if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
05529                 if (dwc_otg_param_initialized
05530                     (core_if->core_params->enable_dynamic_fifo)) {
05531                         DWC_ERROR
05532                             ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
05533                              val);
05534                 }
05535                 val = 0;
05536                 retval = -DWC_E_INVALID;
05537         }
05538         core_if->core_params->enable_dynamic_fifo = val;
05539         return retval;
05540 }
05541 
05542 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
05543 {
05544         return core_if->core_params->enable_dynamic_fifo;
05545 }
05546 
05547 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
05548 {
05549         int retval = 0;
05550         if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
05551                 DWC_WARN("Wrong value for data_fifo_size\n");
05552                 DWC_WARN("data_fifo_size must be 32-32768\n");
05553                 return -DWC_E_INVALID;
05554         }
05555 
05556         if (val > core_if->hwcfg3.b.dfifo_depth) {
05557                 if (dwc_otg_param_initialized
05558                     (core_if->core_params->data_fifo_size)) {
05559                         DWC_ERROR
05560                             ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
05561                              val);
05562                 }
05563                 val = core_if->hwcfg3.b.dfifo_depth;
05564                 retval = -DWC_E_INVALID;
05565         }
05566 
05567         core_if->core_params->data_fifo_size = val;
05568         return retval;
05569 }
05570 
05571 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
05572 {
05573         return core_if->core_params->data_fifo_size;
05574 }
05575 
05576 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
05577 {
05578         int retval = 0;
05579         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05580                 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
05581                 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
05582                 return -DWC_E_INVALID;
05583         }
05584 
05585         if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
05586                 if (dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
05587                 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
05588                 }
05589                 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
05590                 retval = -DWC_E_INVALID;
05591         }
05592 
05593         core_if->core_params->dev_rx_fifo_size = val;
05594         return retval;
05595 }
05596 
05597 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
05598 {
05599         return core_if->core_params->dev_rx_fifo_size;
05600 }
05601 
05602 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05603                                               int32_t val)
05604 {
05605         int retval = 0;
05606 
05607         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05608                 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
05609                 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
05610                 return -DWC_E_INVALID;
05611         }
05612 
05613         if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
05614                 if (dwc_otg_param_initialized
05615                     (core_if->core_params->dev_nperio_tx_fifo_size)) {
05616                         DWC_ERROR
05617                             ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
05618                              val);
05619                 }
05620                 val =
05621                     (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
05622                      16);
05623                 retval = -DWC_E_INVALID;
05624         }
05625 
05626         core_if->core_params->dev_nperio_tx_fifo_size = val;
05627         return retval;
05628 }
05629 
05630 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05631 {
05632         return core_if->core_params->dev_nperio_tx_fifo_size;
05633 }
05634 
05635 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
05636                                         int32_t val)
05637 {
05638         int retval = 0;
05639 
05640         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05641                 DWC_WARN("Wrong value for host_rx_fifo_size\n");
05642                 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
05643                 return -DWC_E_INVALID;
05644         }
05645 
05646         if (val > DWC_READ_REG32(&core_if->core_global_regs->grxfsiz)) {
05647                 if (dwc_otg_param_initialized
05648                     (core_if->core_params->host_rx_fifo_size)) {
05649                         DWC_ERROR
05650                             ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
05651                              val);
05652                 }
05653                 val = DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
05654                 retval = -DWC_E_INVALID;
05655         }
05656 
05657         core_if->core_params->host_rx_fifo_size = val;
05658         return retval;
05659 
05660 }
05661 
05662 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
05663 {
05664         return core_if->core_params->host_rx_fifo_size;
05665 }
05666 
05667 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05668                                                int32_t val)
05669 {
05670         int retval = 0;
05671 
05672         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05673                 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
05674                 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
05675                 return -DWC_E_INVALID;
05676         }
05677 
05678         if (val > (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
05679                 if (dwc_otg_param_initialized
05680                     (core_if->core_params->host_nperio_tx_fifo_size)) {
05681                         DWC_ERROR
05682                             ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
05683                              val);
05684                 }
05685                 val =
05686                     (DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz) >>
05687                      16);
05688                 retval = -DWC_E_INVALID;
05689         }
05690 
05691         core_if->core_params->host_nperio_tx_fifo_size = val;
05692         return retval;
05693 }
05694 
05695 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05696 {
05697         return core_if->core_params->host_nperio_tx_fifo_size;
05698 }
05699 
05700 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
05701                                               int32_t val)
05702 {
05703         int retval = 0;
05704         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
05705                 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
05706                 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
05707                 return -DWC_E_INVALID;
05708         }
05709 
05710         if (val >
05711                 ((core_if->hptxfsiz.d32)>> 16)) {
05712                 if (dwc_otg_param_initialized
05713                     (core_if->core_params->host_perio_tx_fifo_size)) {
05714                         DWC_ERROR
05715                             ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
05716                              val);
05717                 }
05718                 val = (core_if->hptxfsiz.d32) >> 16;
05719                 retval = -DWC_E_INVALID;
05720         }
05721 
05722         core_if->core_params->host_perio_tx_fifo_size = val;
05723         return retval;
05724 }
05725 
05726 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
05727 {
05728         return core_if->core_params->host_perio_tx_fifo_size;
05729 }
05730 
05731 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
05732                                         int32_t val)
05733 {
05734         int retval = 0;
05735 
05736         if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
05737                 DWC_WARN("Wrong value for max_transfer_size\n");
05738                 DWC_WARN("max_transfer_size must be 2047-524288\n");
05739                 return -DWC_E_INVALID;
05740         }
05741 
05742         if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
05743                 if (dwc_otg_param_initialized
05744                     (core_if->core_params->max_transfer_size)) {
05745                         DWC_ERROR
05746                             ("%d invalid for max_transfer_size. Check HW configuration.\n",
05747                              val);
05748                 }
05749                 val =
05750                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
05751                      1);
05752                 retval = -DWC_E_INVALID;
05753         }
05754 
05755         core_if->core_params->max_transfer_size = val;
05756         return retval;
05757 }
05758 
05759 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
05760 {
05761         return core_if->core_params->max_transfer_size;
05762 }
05763 
05764 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
05765 {
05766         int retval = 0;
05767 
05768         if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
05769                 DWC_WARN("Wrong value for max_packet_count\n");
05770                 DWC_WARN("max_packet_count must be 15-511\n");
05771                 return -DWC_E_INVALID;
05772         }
05773 
05774         if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
05775                 if (dwc_otg_param_initialized
05776                     (core_if->core_params->max_packet_count)) {
05777                         DWC_ERROR
05778                             ("%d invalid for max_packet_count. Check HW configuration.\n",
05779                              val);
05780                 }
05781                 val =
05782                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
05783                 retval = -DWC_E_INVALID;
05784         }
05785 
05786         core_if->core_params->max_packet_count = val;
05787         return retval;
05788 }
05789 
05790 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
05791 {
05792         return core_if->core_params->max_packet_count;
05793 }
05794 
05795 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
05796 {
05797         int retval = 0;
05798 
05799         if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
05800                 DWC_WARN("Wrong value for host_channels\n");
05801                 DWC_WARN("host_channels must be 1-16\n");
05802                 return -DWC_E_INVALID;
05803         }
05804 
05805         if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
05806                 if (dwc_otg_param_initialized
05807                     (core_if->core_params->host_channels)) {
05808                         DWC_ERROR
05809                             ("%d invalid for host_channels. Check HW configurations.\n",
05810                              val);
05811                 }
05812                 val = (core_if->hwcfg2.b.num_host_chan + 1);
05813                 retval = -DWC_E_INVALID;
05814         }
05815 
05816         core_if->core_params->host_channels = val;
05817         return retval;
05818 }
05819 
05820 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
05821 {
05822         return core_if->core_params->host_channels;
05823 }
05824 
05825 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
05826 {
05827         int retval = 0;
05828 
05829         if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
05830                 DWC_WARN("Wrong value for dev_endpoints\n");
05831                 DWC_WARN("dev_endpoints must be 1-15\n");
05832                 return -DWC_E_INVALID;
05833         }
05834 
05835         if (val > (core_if->hwcfg2.b.num_dev_ep)) {
05836                 if (dwc_otg_param_initialized
05837                     (core_if->core_params->dev_endpoints)) {
05838                         DWC_ERROR
05839                             ("%d invalid for dev_endpoints. Check HW configurations.\n",
05840                              val);
05841                 }
05842                 val = core_if->hwcfg2.b.num_dev_ep;
05843                 retval = -DWC_E_INVALID;
05844         }
05845 
05846         core_if->core_params->dev_endpoints = val;
05847         return retval;
05848 }
05849 
05850 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
05851 {
05852         return core_if->core_params->dev_endpoints;
05853 }
05854 
05855 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
05856 {
05857         int retval = 0;
05858         int valid = 0;
05859 
05860         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
05861                 DWC_WARN("Wrong value for phy_type\n");
05862                 DWC_WARN("phy_type must be 0,1 or 2\n");
05863                 return -DWC_E_INVALID;
05864         }
05865 #ifndef NO_FS_PHY_HW_CHECKS
05866         if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
05867             ((core_if->hwcfg2.b.hs_phy_type == 1) ||
05868              (core_if->hwcfg2.b.hs_phy_type == 3))) {
05869                 valid = 1;
05870         } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
05871                    ((core_if->hwcfg2.b.hs_phy_type == 2) ||
05872                     (core_if->hwcfg2.b.hs_phy_type == 3))) {
05873                 valid = 1;
05874         } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
05875                    (core_if->hwcfg2.b.fs_phy_type == 1)) {
05876                 valid = 1;
05877         }
05878         if (!valid) {
05879                 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
05880                         DWC_ERROR
05881                             ("%d invalid for phy_type. Check HW configurations.\n",
05882                              val);
05883                 }
05884                 if (core_if->hwcfg2.b.hs_phy_type) {
05885                         if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
05886                             (core_if->hwcfg2.b.hs_phy_type == 1)) {
05887                                 val = DWC_PHY_TYPE_PARAM_UTMI;
05888                         } else {
05889                                 val = DWC_PHY_TYPE_PARAM_ULPI;
05890                         }
05891                 }
05892                 retval = -DWC_E_INVALID;
05893         }
05894 #endif
05895         core_if->core_params->phy_type = val;
05896         return retval;
05897 }
05898 
05899 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
05900 {
05901         return core_if->core_params->phy_type;
05902 }
05903 
05904 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
05905 {
05906         int retval = 0;
05907         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05908                 DWC_WARN("Wrong value for speed parameter\n");
05909                 DWC_WARN("max_speed parameter must be 0 or 1\n");
05910                 return -DWC_E_INVALID;
05911         }
05912         if ((val == 0)
05913             && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
05914                 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
05915                         DWC_ERROR
05916                             ("%d invalid for speed paremter. Check HW configuration.\n",
05917                              val);
05918                 }
05919                 val =
05920                     (dwc_otg_get_param_phy_type(core_if) ==
05921                      DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
05922                 retval = -DWC_E_INVALID;
05923         }
05924         core_if->core_params->speed = val;
05925         return retval;
05926 }
05927 
05928 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
05929 {
05930         return core_if->core_params->speed;
05931 }
05932 
05933 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
05934                                                 int32_t val)
05935 {
05936         int retval = 0;
05937 
05938         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05939                 DWC_WARN
05940                     ("Wrong value for host_ls_low_power_phy_clk parameter\n");
05941                 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
05942                 return -DWC_E_INVALID;
05943         }
05944 
05945         if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
05946             && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
05947                 if (dwc_otg_param_initialized
05948                     (core_if->core_params->host_ls_low_power_phy_clk)) {
05949                         DWC_ERROR
05950                             ("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
05951                              val);
05952                 }
05953                 val =
05954                     (dwc_otg_get_param_phy_type(core_if) ==
05955                      DWC_PHY_TYPE_PARAM_FS) ?
05956                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
05957                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
05958                 retval = -DWC_E_INVALID;
05959         }
05960 
05961         core_if->core_params->host_ls_low_power_phy_clk = val;
05962         return retval;
05963 }
05964 
05965 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
05966 {
05967         return core_if->core_params->host_ls_low_power_phy_clk;
05968 }
05969 
05970 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
05971 {
05972         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05973                 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
05974                 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
05975                 return -DWC_E_INVALID;
05976         }
05977 
05978         core_if->core_params->phy_ulpi_ddr = val;
05979         return 0;
05980 }
05981 
05982 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
05983 {
05984         return core_if->core_params->phy_ulpi_ddr;
05985 }
05986 
05987 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
05988                                         int32_t val)
05989 {
05990         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05991                 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
05992                 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
05993                 return -DWC_E_INVALID;
05994         }
05995 
05996         core_if->core_params->phy_ulpi_ext_vbus = val;
05997         return 0;
05998 }
05999 
06000 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
06001 {
06002         return core_if->core_params->phy_ulpi_ext_vbus;
06003 }
06004 
06005 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
06006 {
06007         if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
06008                 DWC_WARN("Wrong valaue for phy_utmi_width\n");
06009                 DWC_WARN("phy_utmi_width must be 8 or 16\n");
06010                 return -DWC_E_INVALID;
06011         }
06012 
06013         core_if->core_params->phy_utmi_width = val;
06014         return 0;
06015 }
06016 
06017 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
06018 {
06019         return core_if->core_params->phy_utmi_width;
06020 }
06021 
06022 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
06023 {
06024         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06025                 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
06026                 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
06027                 return -DWC_E_INVALID;
06028         }
06029 
06030         core_if->core_params->ulpi_fs_ls = val;
06031         return 0;
06032 }
06033 
06034 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
06035 {
06036         return core_if->core_params->ulpi_fs_ls;
06037 }
06038 
06039 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
06040 {
06041         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06042                 DWC_WARN("Wrong valaue for ts_dline\n");
06043                 DWC_WARN("ts_dline must be 0 or 1\n");
06044                 return -DWC_E_INVALID;
06045         }
06046 
06047         core_if->core_params->ts_dline = val;
06048         return 0;
06049 }
06050 
06051 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
06052 {
06053         return core_if->core_params->ts_dline;
06054 }
06055 
06056 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
06057 {
06058         int retval = 0;
06059         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06060                 DWC_WARN("Wrong valaue for i2c_enable\n");
06061                 DWC_WARN("i2c_enable must be 0 or 1\n");
06062                 return -DWC_E_INVALID;
06063         }
06064 #ifndef NO_FS_PHY_HW_CHECK
06065         if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
06066                 if (dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
06067                         DWC_ERROR
06068                             ("%d invalid for i2c_enable. Check HW configuration.\n",
06069                              val);
06070                 }
06071                 val = 0;
06072                 retval = -DWC_E_INVALID;
06073         }
06074 #endif
06075 
06076         core_if->core_params->i2c_enable = val;
06077         return retval;
06078 }
06079 
06080 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
06081 {
06082         return core_if->core_params->i2c_enable;
06083 }
06084 
06085 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
06086                                              int32_t val, int fifo_num)
06087 {
06088         int retval = 0;
06089 
06090         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
06091                 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
06092                 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
06093                 return -DWC_E_INVALID;
06094         }
06095 
06096         if (val >
06097             (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
06098                 if (dwc_otg_param_initialized
06099                     (core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
06100                         DWC_ERROR
06101                             ("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
06102                              val, fifo_num);
06103                 }
06104                 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
06105                 retval = -DWC_E_INVALID;
06106         }
06107 
06108         core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
06109         return retval;
06110 }
06111 
06112 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
06113                                                  int fifo_num)
06114 {
06115         return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
06116 }
06117 
06118 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
06119                                           int32_t val)
06120 {
06121         int retval = 0;
06122         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06123                 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
06124                 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
06125                 return -DWC_E_INVALID;
06126         }
06127 
06128         if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
06129                 if (dwc_otg_param_initialized
06130                     (core_if->core_params->en_multiple_tx_fifo)) {
06131                         DWC_ERROR
06132                             ("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
06133                              val);
06134                 }
06135                 val = 0;
06136                 retval = -DWC_E_INVALID;
06137         }
06138 
06139         core_if->core_params->en_multiple_tx_fifo = val;
06140         return retval;
06141 }
06142 
06143 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
06144 {
06145         return core_if->core_params->en_multiple_tx_fifo;
06146 }
06147 
06148 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
06149                                        int fifo_num)
06150 {
06151         int retval = 0;
06152 
06153         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
06154                 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
06155                 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
06156                 return -DWC_E_INVALID;
06157         }
06158 
06159         if (val >
06160             (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]))) {
06161                 if (dwc_otg_param_initialized
06162                     (core_if->core_params->dev_tx_fifo_size[fifo_num])) {
06163                         DWC_ERROR
06164                             ("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
06165                              val, fifo_num);
06166                 }
06167                 val = (DWC_READ_REG32(&core_if->core_global_regs->dtxfsiz[fifo_num]));
06168                 retval = -DWC_E_INVALID;
06169         }
06170 
06171         core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
06172         return retval;
06173 }
06174 
06175 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
06176                                            int fifo_num)
06177 {
06178         return core_if->core_params->dev_tx_fifo_size[fifo_num];
06179 }
06180 
06181 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
06182 {
06183         int retval = 0;
06184 
06185         if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
06186                 DWC_WARN("Wrong value for thr_ctl\n");
06187                 DWC_WARN("thr_ctl must be 0-7\n");
06188                 return -DWC_E_INVALID;
06189         }
06190 
06191         if ((val != 0) &&
06192             (!dwc_otg_get_param_dma_enable(core_if) ||
06193              !core_if->hwcfg4.b.ded_fifo_en)) {
06194                 if (dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
06195                         DWC_ERROR
06196                             ("%d invalid for parameter thr_ctl. Check HW configuration.\n",
06197                              val);
06198                 }
06199                 val = 0;
06200                 retval = -DWC_E_INVALID;
06201         }
06202 
06203         core_if->core_params->thr_ctl = val;
06204         return retval;
06205 }
06206 
06207 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
06208 {
06209         return core_if->core_params->thr_ctl;
06210 }
06211 
06212 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
06213 {
06214         int retval = 0;
06215 
06216         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06217                 DWC_WARN("Wrong value for lpm_enable\n");
06218                 DWC_WARN("lpm_enable must be 0 or 1\n");
06219                 return -DWC_E_INVALID;
06220         }
06221 
06222         if (val && !core_if->hwcfg3.b.otg_lpm_en) {
06223                 if (dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
06224                         DWC_ERROR
06225                             ("%d invalid for parameter lpm_enable. Check HW configuration.\n",
06226                              val);
06227                 }
06228                 val = 0;
06229                 retval = -DWC_E_INVALID;
06230         }
06231 
06232         core_if->core_params->lpm_enable = val;
06233         return retval;
06234 }
06235 
06236 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
06237 {
06238         return core_if->core_params->lpm_enable;
06239 }
06240 
06241 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
06242 {
06243         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
06244                 DWC_WARN("Wrong valaue for tx_thr_length\n");
06245                 DWC_WARN("tx_thr_length must be 8 - 128\n");
06246                 return -DWC_E_INVALID;
06247         }
06248 
06249         core_if->core_params->tx_thr_length = val;
06250         return 0;
06251 }
06252 
06253 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
06254 {
06255         return core_if->core_params->tx_thr_length;
06256 }
06257 
06258 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
06259 {
06260         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
06261                 DWC_WARN("Wrong valaue for rx_thr_length\n");
06262                 DWC_WARN("rx_thr_length must be 8 - 128\n");
06263                 return -DWC_E_INVALID;
06264         }
06265 
06266         core_if->core_params->rx_thr_length = val;
06267         return 0;
06268 }
06269 
06270 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
06271 {
06272         return core_if->core_params->rx_thr_length;
06273 }
06274 
06275 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
06276 {
06277         if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
06278             DWC_OTG_PARAM_TEST(val, 4, 4) &&
06279             DWC_OTG_PARAM_TEST(val, 8, 8) &&
06280             DWC_OTG_PARAM_TEST(val, 16, 16) &&
06281             DWC_OTG_PARAM_TEST(val, 32, 32) &&
06282             DWC_OTG_PARAM_TEST(val, 64, 64) &&
06283             DWC_OTG_PARAM_TEST(val, 128, 128) &&
06284             DWC_OTG_PARAM_TEST(val, 256, 256)) {
06285                 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
06286                 return -DWC_E_INVALID;
06287         }
06288         core_if->core_params->dma_burst_size = val;
06289         return 0;
06290 }
06291 
06292 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
06293 {
06294         return core_if->core_params->dma_burst_size;
06295 }
06296 
06297 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
06298 {
06299         int retval = 0;
06300         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06301                 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
06302                 return -DWC_E_INVALID;
06303         }
06304         if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
06305                 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
06306                         DWC_ERROR
06307                             ("%d invalid for parameter pti_enable. Check HW configuration.\n",
06308                              val);
06309                 }
06310                 retval = -DWC_E_INVALID;
06311                 val = 0;
06312         }
06313         core_if->core_params->pti_enable = val;
06314         return retval;
06315 }
06316 
06317 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
06318 {
06319         return core_if->core_params->pti_enable;
06320 }
06321 
06322 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
06323 {
06324         int retval = 0;
06325         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06326                 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
06327                 return -DWC_E_INVALID;
06328         }
06329         if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
06330                 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
06331                         DWC_ERROR
06332                             ("%d invalid for parameter mpi_enable. Check HW configuration.\n",
06333                              val);
06334                 }
06335                 retval = -DWC_E_INVALID;
06336                 val = 0;
06337         }
06338         core_if->core_params->mpi_enable = val;
06339         return retval;
06340 }
06341 
06342 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
06343 {
06344         return core_if->core_params->mpi_enable;
06345 }
06346 
06347 int dwc_otg_set_param_adp_enable(dwc_otg_core_if_t * core_if, int32_t val)
06348 {
06349         int retval = 0;
06350         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06351                 DWC_WARN("`%d' invalid for parameter `adp_enable'\n", val);
06352                 return -DWC_E_INVALID;
06353         }
06354         if (val && (core_if->hwcfg3.b.adp_supp == 0)) {
06355                 if (dwc_otg_param_initialized
06356                     (core_if->core_params->adp_supp_enable)) {
06357                         DWC_ERROR
06358                             ("%d invalid for parameter adp_enable. Check HW configuration.\n",
06359                              val);
06360                 }
06361                 retval = -DWC_E_INVALID;
06362                 val = 0;
06363         }
06364         core_if->core_params->adp_supp_enable = val;
06365         /*Set OTG version 2.0 in case of enabling ADP*/
06366         if (val)
06367                 dwc_otg_set_param_otg_ver(core_if, 1);
06368 
06369         return retval;
06370 }
06371 
06372 int32_t dwc_otg_get_param_adp_enable(dwc_otg_core_if_t * core_if)
06373 {
06374         return core_if->core_params->adp_supp_enable;
06375 }
06376 
06377 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if, int32_t val)
06378 {
06379         int retval = 0;
06380         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06381                 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
06382                 DWC_WARN("ic_usb_cap must be 0 or 1\n");
06383                 return -DWC_E_INVALID;
06384         }
06385 
06386         if (val && (core_if->hwcfg2.b.otg_enable_ic_usb == 0)) {
06387                 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
06388                         DWC_ERROR
06389                             ("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
06390                              val);
06391                 }
06392                 retval = -DWC_E_INVALID;
06393                 val = 0;
06394         }
06395         core_if->core_params->ic_usb_cap = val;
06396         return retval;
06397 }
06398 
06399 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
06400 {
06401         return core_if->core_params->ic_usb_cap;
06402 }
06403 
06404 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
06405 {
06406         int retval = 0;
06407         int valid = 1;
06408 
06409         if (DWC_OTG_PARAM_TEST(val, 0, 3)) {
06410                 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
06411                 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
06412                 return -DWC_E_INVALID;
06413         }
06414 
06415         if (val
06416             && (core_if->snpsid < OTG_CORE_REV_2_81a
06417                 || !dwc_otg_get_param_thr_ctl(core_if))) {
06418                 valid = 0;
06419         } else if (val
06420                    && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) <
06421                        4)) {
06422                 valid = 0;
06423         }
06424         if (valid == 0) {
06425                 if (dwc_otg_param_initialized
06426                     (core_if->core_params->ahb_thr_ratio)) {
06427                         DWC_ERROR
06428                             ("%d invalid for parameter ahb_thr_ratio. Check HW configuration.\n",
06429                              val);
06430                 }
06431                 retval = -DWC_E_INVALID;
06432                 val = 0;
06433         }
06434 
06435         core_if->core_params->ahb_thr_ratio = val;
06436         return retval;
06437 }
06438 
06439 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
06440 {
06441         return core_if->core_params->ahb_thr_ratio;
06442 }
06443 
06444 int dwc_otg_set_param_power_down(dwc_otg_core_if_t * core_if, int32_t val)
06445 {
06446         int retval = 0;
06447         int valid = 1;
06448 
06449         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
06450                 DWC_WARN("`%d' invalid for parameter `power_down'\n", val);
06451                 DWC_WARN("power_down must be 0 - 2\n");
06452                 return -DWC_E_INVALID;
06453         }
06454 
06455         if ((val == 2) && (core_if->snpsid < OTG_CORE_REV_2_91a)) {
06456                 valid = 0;
06457         }
06458         if (valid == 0) {
06459                 if (dwc_otg_param_initialized(core_if->core_params->power_down)) {
06460                         DWC_ERROR
06461                             ("%d invalid for parameter power_down. Check HW configuration.\n",
06462                              val);
06463                 }
06464                 retval = -DWC_E_INVALID;
06465                 val = 0;
06466         }
06467         core_if->core_params->power_down = val;
06468         return retval;
06469 }
06470 
06471 int32_t dwc_otg_get_param_power_down(dwc_otg_core_if_t * core_if)
06472 {
06473         return core_if->core_params->power_down;
06474 }
06475 
06476 int dwc_otg_set_param_reload_ctl(dwc_otg_core_if_t * core_if, int32_t val)
06477 {
06478         int retval = 0;
06479         int valid = 1;
06480 
06481         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06482                 DWC_WARN("`%d' invalid for parameter `reload_ctl'\n", val);
06483                 DWC_WARN("reload_ctl must be 0 or 1\n");
06484                 return -DWC_E_INVALID;
06485         }
06486 
06487         if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_92a)) {
06488                 valid = 0;
06489         }
06490         if (valid == 0) {
06491                 if (dwc_otg_param_initialized(core_if->core_params->reload_ctl)) {
06492                         DWC_ERROR("%d invalid for parameter reload_ctl."
06493                                   "Check HW configuration.\n", val);
06494                 }
06495                 retval = -DWC_E_INVALID;
06496                 val = 0;
06497         }
06498         core_if->core_params->reload_ctl = val;
06499         return retval;
06500 }
06501 
06502 int32_t dwc_otg_get_param_reload_ctl(dwc_otg_core_if_t * core_if)
06503 {
06504         return core_if->core_params->reload_ctl;
06505 }
06506 
06507 int dwc_otg_set_param_dev_out_nak(dwc_otg_core_if_t * core_if, int32_t val)
06508 {
06509         int retval = 0;
06510         int valid = 1;
06511 
06512         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06513                 DWC_WARN("`%d' invalid for parameter `dev_out_nak'\n", val);
06514                 DWC_WARN("dev_out_nak must be 0 or 1\n");
06515                 return -DWC_E_INVALID;
06516         }
06517 
06518         if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_93a) ||
06519                 !(core_if->core_params->dma_desc_enable))) {
06520                 valid = 0;
06521         }
06522         if (valid == 0) {
06523                 if (dwc_otg_param_initialized(core_if->core_params->dev_out_nak)) {
06524                         DWC_ERROR("%d invalid for parameter dev_out_nak."
06525                                 "Check HW configuration.\n", val);
06526                 }
06527                 retval = -DWC_E_INVALID;
06528                 val = 0;
06529         }
06530         core_if->core_params->dev_out_nak = val;
06531         return retval;
06532 }
06533 
06534 int32_t dwc_otg_get_param_dev_out_nak(dwc_otg_core_if_t * core_if)
06535 {
06536         return core_if->core_params->dev_out_nak;
06537 }
06538 
06539 int dwc_otg_set_param_cont_on_bna(dwc_otg_core_if_t * core_if, int32_t val)
06540 {
06541         int retval = 0;
06542         int valid = 1;
06543 
06544         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06545                 DWC_WARN("`%d' invalid for parameter `cont_on_bna'\n", val);
06546                 DWC_WARN("cont_on_bna must be 0 or 1\n");
06547                 return -DWC_E_INVALID;
06548         }
06549 
06550         if ((val == 1) && ((core_if->snpsid < OTG_CORE_REV_2_94a) ||
06551                 !(core_if->core_params->dma_desc_enable))) {
06552                         valid = 0;
06553         }
06554         if (valid == 0) {
06555                 if (dwc_otg_param_initialized(core_if->core_params->cont_on_bna)) {
06556                         DWC_ERROR("%d invalid for parameter cont_on_bna."
06557                                 "Check HW configuration.\n", val);
06558                 }
06559                 retval = -DWC_E_INVALID;
06560                 val = 0;
06561         }
06562         core_if->core_params->cont_on_bna = val;
06563         return retval;
06564 }
06565 
06566 int32_t dwc_otg_get_param_cont_on_bna(dwc_otg_core_if_t * core_if)
06567 {
06568         return core_if->core_params->cont_on_bna;
06569 }
06570 
06571 int dwc_otg_set_param_ahb_single(dwc_otg_core_if_t * core_if, int32_t val)
06572 {
06573         int retval = 0;
06574         int valid = 1;
06575 
06576         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06577                 DWC_WARN("`%d' invalid for parameter `ahb_single'\n", val);
06578                 DWC_WARN("ahb_single must be 0 or 1\n");
06579                 return -DWC_E_INVALID;
06580         }
06581 
06582         if ((val == 1) && (core_if->snpsid < OTG_CORE_REV_2_94a)) {
06583                         valid = 0;
06584         }
06585         if (valid == 0) {
06586                 if (dwc_otg_param_initialized(core_if->core_params->ahb_single)) {
06587                         DWC_ERROR("%d invalid for parameter ahb_single."
06588                                 "Check HW configuration.\n", val);
06589                 }
06590                 retval = -DWC_E_INVALID;
06591                 val = 0;
06592         }
06593         core_if->core_params->ahb_single = val;
06594         return retval;
06595 }
06596 
06597 int32_t dwc_otg_get_param_ahb_single(dwc_otg_core_if_t * core_if)
06598 {
06599         return core_if->core_params->ahb_single;
06600 }
06601 
06602 int dwc_otg_set_param_otg_ver(dwc_otg_core_if_t * core_if, int32_t val)
06603 {
06604         int retval = 0;
06605 
06606         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
06607                 DWC_WARN("`%d' invalid for parameter `otg_ver'\n", val);
06608                 DWC_WARN
06609                     ("otg_ver must be 0(for OTG 1.3 support) or 1(for OTG 2.0 support)\n");
06610                 return -DWC_E_INVALID;
06611         }
06612 
06613         core_if->core_params->otg_ver = val;
06614         return retval;
06615 }
06616 
06617 int32_t dwc_otg_get_param_otg_ver(dwc_otg_core_if_t * core_if)
06618 {
06619         return core_if->core_params->otg_ver;
06620 }
06621 
06622 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
06623 {
06624         gotgctl_data_t otgctl;
06625         otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06626         return otgctl.b.hstnegscs;
06627 }
06628 
06629 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
06630 {
06631         gotgctl_data_t otgctl;
06632         otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06633         return otgctl.b.sesreqscs;
06634 }
06635 
06636 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
06637 {
06638         if(core_if->otg_ver == 0) {
06639                 gotgctl_data_t otgctl;
06640                 otgctl.d32 = DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06641                 otgctl.b.hnpreq = val;
06642                 DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, otgctl.d32);
06643         } else {
06644                 core_if->otg_sts = val;
06645         }
06646 }
06647 
06648 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
06649 {
06650         return core_if->snpsid;
06651 }
06652 
06653 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
06654 {
06655         gintsts_data_t gintsts;
06656         gintsts.d32 = DWC_READ_REG32(&core_if->core_global_regs->gintsts);
06657         return gintsts.b.curmode;
06658 }
06659 
06660 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
06661 {
06662         gusbcfg_data_t usbcfg;
06663         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06664         return usbcfg.b.hnpcap;
06665 }
06666 
06667 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
06668 {
06669         gusbcfg_data_t usbcfg;
06670         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06671         usbcfg.b.hnpcap = val;
06672         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
06673 }
06674 
06675 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
06676 {
06677         gusbcfg_data_t usbcfg;
06678         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06679         return usbcfg.b.srpcap;
06680 }
06681 
06682 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
06683 {
06684         gusbcfg_data_t usbcfg;
06685         usbcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06686         usbcfg.b.srpcap = val;
06687         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
06688 }
06689 
06690 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
06691 {
06692         dcfg_data_t dcfg;
06693         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
06694         return dcfg.b.devspd;
06695 }
06696 
06697 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
06698 {
06699         dcfg_data_t dcfg;
06700         dcfg.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dcfg);
06701         dcfg.b.devspd = val;
06702         DWC_WRITE_REG32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
06703 }
06704 
06705 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
06706 {
06707         hprt0_data_t hprt0;
06708         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06709         return hprt0.b.prtconnsts;
06710 }
06711 
06712 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
06713 {
06714         dsts_data_t dsts;
06715         dsts.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dsts);
06716         return dsts.b.enumspd;
06717 }
06718 
06719 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
06720 {
06721         hprt0_data_t hprt0;
06722         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06723         return hprt0.b.prtpwr;
06724 
06725 }
06726 
06727 uint32_t dwc_otg_get_core_state(dwc_otg_core_if_t * core_if)
06728 {
06729         return core_if->hibernation_suspend;
06730 }
06731 
06732 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
06733 {
06734         hprt0_data_t hprt0;
06735         hprt0.d32 = dwc_otg_read_hprt0(core_if);
06736         hprt0.b.prtpwr = val;
06737         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06738 }
06739 
06740 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
06741 {
06742         hprt0_data_t hprt0;
06743         hprt0.d32 = DWC_READ_REG32(core_if->host_if->hprt0);
06744         return hprt0.b.prtsusp;
06745 
06746 }
06747 
06748 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
06749 {
06750         hprt0_data_t hprt0;
06751         hprt0.d32 = dwc_otg_read_hprt0(core_if);
06752         hprt0.b.prtsusp = val;
06753         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06754 }
06755 
06756 uint32_t dwc_otg_get_fr_interval(dwc_otg_core_if_t * core_if)
06757 {
06758         hfir_data_t hfir;
06759         hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
06760         return hfir.b.frint;
06761 
06762 }
06763 
06764 void dwc_otg_set_fr_interval(dwc_otg_core_if_t * core_if, uint32_t val)
06765 {
06766         hfir_data_t hfir;
06767         uint32_t fram_int;
06768         fram_int = calc_frame_interval(core_if);
06769         hfir.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hfir);
06770         if (!core_if->core_params->reload_ctl) {
06771                 DWC_WARN("\nCannot reload HFIR register.HFIR.HFIRRldCtrl bit is"
06772                          "not set to 1.\nShould load driver with reload_ctl=1"
06773                          " module parameter\n");
06774                 return;
06775         }
06776         switch (fram_int) {
06777         case 3750:
06778                 if ((val < 3350) || (val > 4150)) {
06779                         DWC_WARN("HFIR interval for HS core and 30 MHz"
06780                                  "clock freq should be from 3350 to 4150\n");
06781                         return;
06782                 }
06783                 break;
06784         case 30000:
06785                 if ((val < 26820) || (val > 33180)) {
06786                         DWC_WARN("HFIR interval for FS/LS core and 30 MHz"
06787                                  "clock freq should be from 26820 to 33180\n");
06788                         return;
06789                 }
06790                 break;
06791         case 6000:
06792                 if ((val < 5360) || (val > 6640)) {
06793                         DWC_WARN("HFIR interval for HS core and 48 MHz"
06794                                  "clock freq should be from 5360 to 6640\n");
06795                         return;
06796                 }
06797                 break;
06798         case 48000:
06799                 if ((val < 42912) || (val > 53088)) {
06800                         DWC_WARN("HFIR interval for FS/LS core and 48 MHz"
06801                                  "clock freq should be from 42912 to 53088\n");
06802                         return;
06803                 }
06804                 break;
06805         case 7500:
06806                 if ((val < 6700) || (val > 8300)) {
06807                         DWC_WARN("HFIR interval for HS core and 60 MHz"
06808                                  "clock freq should be from 6700 to 8300\n");
06809                         return;
06810                 }
06811                 break;
06812         case 60000:
06813                 if ((val < 53640) || (val > 65536)) {
06814                         DWC_WARN("HFIR interval for FS/LS core and 60 MHz"
06815                                  "clock freq should be from 53640 to 65536\n");
06816                         return;
06817                 }
06818                 break;
06819         default:
06820                 DWC_WARN("Unknown frame interval\n");
06821                 return;
06822                 break;
06823 
06824         }
06825         hfir.b.frint = val;
06826         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hfir, hfir.d32);
06827 }
06828 
06829 uint32_t dwc_otg_get_mode_ch_tim(dwc_otg_core_if_t * core_if)
06830 {
06831         hcfg_data_t hcfg;
06832         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
06833         return hcfg.b.modechtimen;
06834 
06835 }
06836 
06837 void dwc_otg_set_mode_ch_tim(dwc_otg_core_if_t * core_if, uint32_t val)
06838 {
06839         hcfg_data_t hcfg;
06840         hcfg.d32 = DWC_READ_REG32(&core_if->host_if->host_global_regs->hcfg);
06841         hcfg.b.modechtimen = val;
06842         DWC_WRITE_REG32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
06843 }
06844 
06845 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
06846 {
06847         hprt0_data_t hprt0;
06848         hprt0.d32 = dwc_otg_read_hprt0(core_if);
06849         hprt0.b.prtres = val;
06850         DWC_WRITE_REG32(core_if->host_if->hprt0, hprt0.d32);
06851 }
06852 
06853 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
06854 {
06855         dctl_data_t dctl;
06856         dctl.d32 = DWC_READ_REG32(&core_if->dev_if->dev_global_regs->dctl);
06857         return dctl.b.rmtwkupsig;
06858 }
06859 
06860 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
06861 {
06862         glpmcfg_data_t lpmcfg;
06863         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06864 
06865         DWC_ASSERT(!
06866                    ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
06867                    "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
06868                    core_if->lx_state, lpmcfg.b.prt_sleep_sts);
06869 
06870         return lpmcfg.b.prt_sleep_sts;
06871 }
06872 
06873 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
06874 {
06875         glpmcfg_data_t lpmcfg;
06876         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06877         return lpmcfg.b.rem_wkup_en;
06878 }
06879 
06880 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
06881 {
06882         glpmcfg_data_t lpmcfg;
06883         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06884         return lpmcfg.b.appl_resp;
06885 }
06886 
06887 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
06888 {
06889         glpmcfg_data_t lpmcfg;
06890         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06891         lpmcfg.b.appl_resp = val;
06892         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06893 }
06894 
06895 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
06896 {
06897         glpmcfg_data_t lpmcfg;
06898         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06899         return lpmcfg.b.hsic_connect;
06900 }
06901 
06902 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
06903 {
06904         glpmcfg_data_t lpmcfg;
06905         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06906         lpmcfg.b.hsic_connect = val;
06907         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06908 }
06909 
06910 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
06911 {
06912         glpmcfg_data_t lpmcfg;
06913         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06914         return lpmcfg.b.inv_sel_hsic;
06915 
06916 }
06917 
06918 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
06919 {
06920         glpmcfg_data_t lpmcfg;
06921         lpmcfg.d32 = DWC_READ_REG32(&core_if->core_global_regs->glpmcfg);
06922         lpmcfg.b.inv_sel_hsic = val;
06923         DWC_WRITE_REG32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
06924 }
06925 
06926 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
06927 {
06928         return DWC_READ_REG32(&core_if->core_global_regs->gotgctl);
06929 }
06930 
06931 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
06932 {
06933         DWC_WRITE_REG32(&core_if->core_global_regs->gotgctl, val);
06934 }
06935 
06936 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
06937 {
06938         return DWC_READ_REG32(&core_if->core_global_regs->gusbcfg);
06939 }
06940 
06941 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
06942 {
06943         DWC_WRITE_REG32(&core_if->core_global_regs->gusbcfg, val);
06944 }
06945 
06946 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
06947 {
06948         return DWC_READ_REG32(&core_if->core_global_regs->grxfsiz);
06949 }
06950 
06951 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
06952 {
06953         DWC_WRITE_REG32(&core_if->core_global_regs->grxfsiz, val);
06954 }
06955 
06956 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
06957 {
06958         return DWC_READ_REG32(&core_if->core_global_regs->gnptxfsiz);
06959 }
06960 
06961 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
06962 {
06963         DWC_WRITE_REG32(&core_if->core_global_regs->gnptxfsiz, val);
06964 }
06965 
06966 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
06967 {
06968         return DWC_READ_REG32(&core_if->core_global_regs->gpvndctl);
06969 }
06970 
06971 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
06972 {
06973         DWC_WRITE_REG32(&core_if->core_global_regs->gpvndctl, val);
06974 }
06975 
06976 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
06977 {
06978         return DWC_READ_REG32(&core_if->core_global_regs->ggpio);
06979 }
06980 
06981 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
06982 {
06983         DWC_WRITE_REG32(&core_if->core_global_regs->ggpio, val);
06984 }
06985 
06986 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
06987 {
06988         return DWC_READ_REG32(core_if->host_if->hprt0);
06989 
06990 }
06991 
06992 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
06993 {
06994         DWC_WRITE_REG32(core_if->host_if->hprt0, val);
06995 }
06996 
06997 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
06998 {
06999         return DWC_READ_REG32(&core_if->core_global_regs->guid);
07000 }
07001 
07002 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
07003 {
07004         DWC_WRITE_REG32(&core_if->core_global_regs->guid, val);
07005 }
07006 
07007 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
07008 {
07009         return DWC_READ_REG32(&core_if->core_global_regs->hptxfsiz);
07010 }
07011 
07012 uint16_t dwc_otg_get_otg_version(dwc_otg_core_if_t * core_if)
07013 {
07014         return ((core_if->otg_ver == 1) ? (uint16_t)0x0200 : (uint16_t)0x0103);
07015 }
07016 
07023 void dwc_otg_pcd_start_srp_timer(dwc_otg_core_if_t * core_if)
07024 {
07025         core_if->srp_timer_started = 1;
07026         DWC_TIMER_SCHEDULE(core_if->srp_timer, 6000 /* 6 secs */ );
07027 }
07028 
07029 void dwc_otg_initiate_srp(dwc_otg_core_if_t * core_if)
07030 {
07031         uint32_t *addr = (uint32_t *) & (core_if->core_global_regs->gotgctl);
07032         gotgctl_data_t mem;
07033         gotgctl_data_t val;
07034 
07035         val.d32 = DWC_READ_REG32(addr);
07036         if (val.b.sesreq) {
07037                 DWC_ERROR("Session Request Already active!\n");
07038                 return;
07039         }
07040 
07041         DWC_INFO("Session Request Initated\n"); //NOTICE
07042         mem.d32 = DWC_READ_REG32(addr);
07043         mem.b.sesreq = 1;
07044         DWC_WRITE_REG32(addr, mem.d32);
07045 
07046         /* Start the SRP timer */
07047         dwc_otg_pcd_start_srp_timer(core_if);
07048         return;
07049 }

Generated on Thu Oct 27 03:56:37 2011 for DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver by  doxygen 1.3.9.1