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: #159 $
00004  * $Date: 2009/04/21 $
00005  * $Change: 1237465 $
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 == 0) {
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 == 0) {
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 == 0) {
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%08x\n",
00165                             i, (unsigned)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         DWC_DEBUGPL(DBG_CILV, "hwcfg1=%08x\n", core_if->hwcfg1.d32);
00186         DWC_DEBUGPL(DBG_CILV, "hwcfg2=%08x\n", core_if->hwcfg2.d32);
00187         DWC_DEBUGPL(DBG_CILV, "hwcfg3=%08x\n", core_if->hwcfg3.d32);
00188         DWC_DEBUGPL(DBG_CILV, "hwcfg4=%08x\n", core_if->hwcfg4.d32);
00189 
00190         core_if->hcfg.d32 =
00191             dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
00192         core_if->dcfg.d32 =
00193             dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
00194 
00195         DWC_DEBUGPL(DBG_CILV, "hcfg=%08x\n", core_if->hcfg.d32);
00196         DWC_DEBUGPL(DBG_CILV, "dcfg=%08x\n", core_if->dcfg.d32);
00197 
00198         DWC_DEBUGPL(DBG_CILV, "op_mode=%0x\n", core_if->hwcfg2.b.op_mode);
00199         DWC_DEBUGPL(DBG_CILV, "arch=%0x\n", core_if->hwcfg2.b.architecture);
00200         DWC_DEBUGPL(DBG_CILV, "num_dev_ep=%d\n", core_if->hwcfg2.b.num_dev_ep);
00201         DWC_DEBUGPL(DBG_CILV, "num_host_chan=%d\n",
00202                     core_if->hwcfg2.b.num_host_chan);
00203         DWC_DEBUGPL(DBG_CILV, "nonperio_tx_q_depth=0x%0x\n",
00204                     core_if->hwcfg2.b.nonperio_tx_q_depth);
00205         DWC_DEBUGPL(DBG_CILV, "host_perio_tx_q_depth=0x%0x\n",
00206                     core_if->hwcfg2.b.host_perio_tx_q_depth);
00207         DWC_DEBUGPL(DBG_CILV, "dev_token_q_depth=0x%0x\n",
00208                     core_if->hwcfg2.b.dev_token_q_depth);
00209 
00210         DWC_DEBUGPL(DBG_CILV, "Total FIFO SZ=%d\n",
00211                     core_if->hwcfg3.b.dfifo_depth);
00212         DWC_DEBUGPL(DBG_CILV, "xfer_size_cntr_width=%0x\n",
00213                     core_if->hwcfg3.b.xfer_size_cntr_width);
00214 
00215         /*
00216          * Set the SRP sucess bit for FS-I2c
00217          */
00218         core_if->srp_success = 0;
00219         core_if->srp_timer_started = 0;
00220 
00221         /*
00222          * Create new workqueue and init works
00223          */
00224         core_if->wq_otg = DWC_WORKQ_ALLOC("dwc_otg");
00225         if (core_if->wq_otg == 0) {
00226                 DWC_WARN("DWC_WORKQ_ALLOC failed\n");
00227                 dwc_free(host_if);
00228                 dwc_free(dev_if);
00229                 dwc_free(core_if);
00230                 return 0;
00231         }
00232 
00233         core_if->snpsid = dwc_read_reg32(&core_if->core_global_regs->gsnpsid);
00234 
00235         DWC_PRINTF("Core Release: %x.%x%x%x\n",
00236                    (core_if->snpsid >> 12 & 0xF),
00237                    (core_if->snpsid >> 8 & 0xF),
00238                    (core_if->snpsid >> 4 & 0xF), (core_if->snpsid & 0xF));
00239 
00240         core_if->wkp_timer = DWC_TIMER_ALLOC("Wake Up Timer",
00241                                              w_wakeup_detected, core_if);
00242         if (core_if->wkp_timer == 0) {
00243                 DWC_WARN("DWC_TIMER_ALLOC failed\n");
00244                 dwc_free(host_if);
00245                 dwc_free(dev_if);
00246                 DWC_WORKQ_FREE(core_if->wq_otg);
00247                 dwc_free(core_if);
00248                 return 0;
00249         }
00250 
00251         if (dwc_otg_setup_params(core_if)) {
00252                 DWC_WARN("Error while setting core params\n");
00253         }
00254 
00255         return core_if;
00256 }
00257 
00265 void dwc_otg_cil_remove(dwc_otg_core_if_t * core_if)
00266 {
00267         /* Disable all interrupts */
00268         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 1, 0);
00269         dwc_write_reg32(&core_if->core_global_regs->gintmsk, 0);
00270 
00271         if (core_if->wq_otg) {
00272                 DWC_WORKQ_WAIT_WORK_DONE(core_if->wq_otg, 500);
00273                 DWC_WORKQ_FREE(core_if->wq_otg);
00274         }
00275         if (core_if->dev_if) {
00276                 dwc_free(core_if->dev_if);
00277         }
00278         if (core_if->host_if) {
00279                 dwc_free(core_if->host_if);
00280         }
00281         dwc_free(core_if);
00282         DWC_TIMER_FREE(core_if->wkp_timer);
00283         DWC_FREE(core_if->core_params);
00284 }
00285 
00292 void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * core_if)
00293 {
00294         gahbcfg_data_t ahbcfg = {.d32 = 0 };
00295         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
00296         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, 0, ahbcfg.d32);
00297 }
00298 
00305 void dwc_otg_disable_global_interrupts(dwc_otg_core_if_t * core_if)
00306 {
00307         gahbcfg_data_t ahbcfg = {.d32 = 0 };
00308         ahbcfg.b.glblintrmsk = 1;       /* Enable interrupts */
00309         dwc_modify_reg32(&core_if->core_global_regs->gahbcfg, ahbcfg.d32, 0);
00310 }
00311 
00319 static void dwc_otg_enable_common_interrupts(dwc_otg_core_if_t * core_if)
00320 {
00321         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00322         gintmsk_data_t intr_mask = {.d32 = 0 };
00323 
00324         /* Clear any pending OTG Interrupts */
00325         dwc_write_reg32(&global_regs->gotgint, 0xFFFFFFFF);
00326 
00327         /* Clear any pending interrupts */
00328         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
00329 
00330         /* 
00331          * Enable the interrupts in the GINTMSK. 
00332          */
00333         intr_mask.b.modemismatch = 1;
00334         intr_mask.b.otgintr = 1;
00335 
00336         if (!core_if->dma_enable) {
00337                 intr_mask.b.rxstsqlvl = 1;
00338         }
00339 
00340         intr_mask.b.conidstschng = 1;
00341         intr_mask.b.wkupintr = 1;
00342         intr_mask.b.disconnect = 1;
00343         intr_mask.b.usbsuspend = 1;
00344         intr_mask.b.sessreqintr = 1;
00345 #ifdef CONFIG_USB_DWC_OTG_LPM
00346         if (core_if->core_params->lpm_enable) {
00347                 intr_mask.b.lpmtranrcvd = 1;
00348         }
00349 #endif
00350         dwc_write_reg32(&global_regs->gintmsk, intr_mask.d32);
00351 }
00352 
00357 static void init_fslspclksel(dwc_otg_core_if_t * core_if)
00358 {
00359         uint32_t val;
00360         hcfg_data_t hcfg;
00361 
00362         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
00363              (core_if->hwcfg2.b.fs_phy_type == 1) &&
00364              (core_if->core_params->ulpi_fs_ls)) ||
00365             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
00366                 /* Full speed PHY */
00367                 val = DWC_HCFG_48_MHZ;
00368         } else {
00369                 /* High speed PHY running at full speed or high speed */
00370                 val = DWC_HCFG_30_60_MHZ;
00371         }
00372 
00373         DWC_DEBUGPL(DBG_CIL, "Initializing HCFG.FSLSPClkSel to 0x%1x\n", val);
00374         hcfg.d32 = dwc_read_reg32(&core_if->host_if->host_global_regs->hcfg);
00375         hcfg.b.fslspclksel = val;
00376         dwc_write_reg32(&core_if->host_if->host_global_regs->hcfg, hcfg.d32);
00377 }
00378 
00383 static void init_devspd(dwc_otg_core_if_t * core_if)
00384 {
00385         uint32_t val;
00386         dcfg_data_t dcfg;
00387 
00388         if (((core_if->hwcfg2.b.hs_phy_type == 2) &&
00389              (core_if->hwcfg2.b.fs_phy_type == 1) &&
00390              (core_if->core_params->ulpi_fs_ls)) ||
00391             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
00392                 /* Full speed PHY */
00393                 val = 0x3;
00394         } else if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
00395                 /* High speed PHY running at full speed */
00396                 val = 0x1;
00397         } else {
00398                 /* High speed PHY running at high speed */
00399                 val = 0x0;
00400         }
00401 
00402         DWC_DEBUGPL(DBG_CIL, "Initializing DCFG.DevSpd to 0x%1x\n", val);
00403 
00404         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
00405         dcfg.b.devspd = val;
00406         dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
00407 }
00408 
00415 static uint32_t calc_num_in_eps(dwc_otg_core_if_t * core_if)
00416 {
00417         uint32_t num_in_eps = 0;
00418         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
00419         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 3;
00420         uint32_t num_tx_fifos = core_if->hwcfg4.b.num_in_eps;
00421         int i;
00422 
00423         for (i = 0; i < num_eps; ++i) {
00424                 if (!(hwcfg1 & 0x1))
00425                         num_in_eps++;
00426 
00427                 hwcfg1 >>= 2;
00428         }
00429 
00430         if (core_if->hwcfg4.b.ded_fifo_en) {
00431                 num_in_eps =
00432                     (num_in_eps > num_tx_fifos) ? num_tx_fifos : num_in_eps;
00433         }
00434 
00435         return num_in_eps;
00436 }
00437 
00444 static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
00445 {
00446         uint32_t num_out_eps = 0;
00447         uint32_t num_eps = core_if->hwcfg2.b.num_dev_ep;
00448         uint32_t hwcfg1 = core_if->hwcfg1.d32 >> 2;
00449         int i;
00450 
00451         for (i = 0; i < num_eps; ++i) {
00452                 if (!(hwcfg1 & 0x1))
00453                         num_out_eps++;
00454 
00455                 hwcfg1 >>= 2;
00456         }
00457         return num_out_eps;
00458 }
00459 
00467 void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
00468 {
00469         int i = 0;
00470         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00471         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00472         gahbcfg_data_t ahbcfg = {.d32 = 0 };
00473         gusbcfg_data_t usbcfg = {.d32 = 0 };
00474         gi2cctl_data_t i2cctl = {.d32 = 0 };
00475 
00476         DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
00477 
00478         /* Common Initialization */
00479 
00480         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00481 
00482         /* Program the ULPI External VBUS bit if needed */
00483         usbcfg.b.ulpi_ext_vbus_drv =
00484             (core_if->core_params->phy_ulpi_ext_vbus ==
00485              DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
00486 
00487         /* Set external TS Dline pulsing */
00488         usbcfg.b.term_sel_dl_pulse =
00489             (core_if->core_params->ts_dline == 1) ? 1 : 0;
00490         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00491 
00492         /* Reset the Controller */
00493         dwc_otg_core_reset(core_if);
00494 
00495         /* Initialize parameters from Hardware configuration registers. */
00496         dev_if->num_in_eps = calc_num_in_eps(core_if);
00497         dev_if->num_out_eps = calc_num_out_eps(core_if);
00498 
00499         DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
00500                     core_if->hwcfg4.b.num_dev_perio_in_ep);
00501 
00502         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
00503                 dev_if->perio_tx_fifo_size[i] =
00504                     dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
00505                 DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
00506                             i, dev_if->perio_tx_fifo_size[i]);
00507         }
00508 
00509         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
00510                 dev_if->tx_fifo_size[i] =
00511                     dwc_read_reg32(&global_regs->dptxfsiz_dieptxf[i]) >> 16;
00512                 DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
00513                             i, dev_if->perio_tx_fifo_size[i]);
00514         }
00515 
00516         core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
00517         core_if->rx_fifo_size = dwc_read_reg32(&global_regs->grxfsiz);
00518         core_if->nperio_tx_fifo_size =
00519             dwc_read_reg32(&global_regs->gnptxfsiz) >> 16;
00520 
00521         DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
00522         DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
00523         DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
00524                     core_if->nperio_tx_fifo_size);
00525 
00526         /* This programming sequence needs to happen in FS mode before any other
00527          * programming occurs */
00528         if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
00529             (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
00530                 /* If FS mode with FS PHY */
00531 
00532                 /* core_init() is now called on every switch so only call the
00533                  * following for the first time through. */
00534                 if (!core_if->phy_init_done) {
00535                         core_if->phy_init_done = 1;
00536                         DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
00537                         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00538                         usbcfg.b.physel = 1;
00539                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00540 
00541                         /* Reset after a PHY select */
00542                         dwc_otg_core_reset(core_if);
00543                 }
00544 
00545                 /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
00546                  * do this on HNP Dev/Host mode switches (done in dev_init and
00547                  * host_init). */
00548                 if (dwc_otg_is_host_mode(core_if)) {
00549                         init_fslspclksel(core_if);
00550                 } else {
00551                         init_devspd(core_if);
00552                 }
00553 
00554                 if (core_if->core_params->i2c_enable) {
00555                         DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
00556                         /* Program GUSBCFG.OtgUtmifsSel to I2C */
00557                         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00558                         usbcfg.b.otgutmifssel = 1;
00559                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00560 
00561                         /* Program GI2CCTL.I2CEn */
00562                         i2cctl.d32 = dwc_read_reg32(&global_regs->gi2cctl);
00563                         i2cctl.b.i2cdevaddr = 1;
00564                         i2cctl.b.i2cen = 0;
00565                         dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
00566                         i2cctl.b.i2cen = 1;
00567                         dwc_write_reg32(&global_regs->gi2cctl, i2cctl.d32);
00568                 }
00569 
00570         } /* endif speed == DWC_SPEED_PARAM_FULL */
00571         else {
00572                 /* High speed PHY. */
00573                 if (!core_if->phy_init_done) {
00574                         core_if->phy_init_done = 1;
00575                         /* HS PHY parameters.  These parameters are preserved
00576                          * during soft reset so only program the first time.  Do
00577                          * a soft reset immediately after setting phyif.  */
00578                         usbcfg.b.ulpi_utmi_sel = core_if->core_params->phy_type;
00579                         if (usbcfg.b.ulpi_utmi_sel == 1) {
00580                                 /* ULPI interface */
00581                                 usbcfg.b.phyif = 0;
00582                                 usbcfg.b.ddrsel =
00583                                     core_if->core_params->phy_ulpi_ddr;
00584                         } else {
00585                                 /* UTMI+ interface */
00586                                 if (core_if->core_params->phy_utmi_width == 16) {
00587                                         usbcfg.b.phyif = 1;
00588 
00589                                 } else {
00590                                         usbcfg.b.phyif = 0;
00591                                 }
00592 
00593                         }
00594 
00595                         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00596                         /* Reset after setting the PHY parameters */
00597                         dwc_otg_core_reset(core_if);
00598                 }
00599         }
00600 
00601         if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
00602             (core_if->hwcfg2.b.fs_phy_type == 1) &&
00603             (core_if->core_params->ulpi_fs_ls)) {
00604                 DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
00605                 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00606                 usbcfg.b.ulpi_fsls = 1;
00607                 usbcfg.b.ulpi_clk_sus_m = 1;
00608                 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00609         } else {
00610                 usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00611                 usbcfg.b.ulpi_fsls = 0;
00612                 usbcfg.b.ulpi_clk_sus_m = 0;
00613                 dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00614         }
00615 
00616         /* Program the GAHBCFG Register. */
00617         switch (core_if->hwcfg2.b.architecture) {
00618 
00619         case DWC_SLAVE_ONLY_ARCH:
00620                 DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
00621                 ahbcfg.b.nptxfemplvl_txfemplvl =
00622                     DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
00623                 ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
00624                 core_if->dma_enable = 0;
00625                 core_if->dma_desc_enable = 0;
00626                 break;
00627 
00628         case DWC_EXT_DMA_ARCH:
00629                 DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
00630                 {
00631                         uint8_t brst_sz = core_if->core_params->dma_burst_size;
00632                         ahbcfg.b.hburstlen = 0;
00633                         while (brst_sz > 1) {
00634                                 ahbcfg.b.hburstlen++;
00635                                 brst_sz >>= 1;
00636                         }
00637                 }
00638                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
00639                 core_if->dma_desc_enable =
00640                     (core_if->core_params->dma_desc_enable != 0);
00641                 break;
00642 
00643         case DWC_INT_DMA_ARCH:
00644                 DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
00645                 ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR;
00646                 core_if->dma_enable = (core_if->core_params->dma_enable != 0);
00647                 core_if->dma_desc_enable =
00648                     (core_if->core_params->dma_desc_enable != 0);
00649                 break;
00650 
00651         }
00652         if (core_if->dma_enable) {
00653                 if (core_if->dma_desc_enable) {
00654                         DWC_PRINTF("Using Descriptor DMA mode\n");
00655                 } else {
00656                         DWC_PRINTF("Using Buffer DMA mode\n");
00657 
00658                 }
00659         } else {
00660                 DWC_PRINTF("Using Slave mode\n");
00661                 core_if->dma_desc_enable = 0;
00662         }
00663         
00664         ahbcfg.b.dmaenable = core_if->dma_enable;
00665         dwc_write_reg32(&global_regs->gahbcfg, ahbcfg.d32);
00666 
00667         core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
00668 
00669         core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
00670         core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
00671         DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
00672                    ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
00673         DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
00674                    ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
00675 
00676         /* 
00677          * Program the GUSBCFG register. 
00678          */
00679         usbcfg.d32 = dwc_read_reg32(&global_regs->gusbcfg);
00680 
00681         switch (core_if->hwcfg2.b.op_mode) {
00682         case DWC_MODE_HNP_SRP_CAPABLE:
00683                 usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
00684                                    DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
00685                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
00686                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
00687                 break;
00688 
00689         case DWC_MODE_SRP_ONLY_CAPABLE:
00690                 usbcfg.b.hnpcap = 0;
00691                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
00692                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
00693                 break;
00694 
00695         case DWC_MODE_NO_HNP_SRP_CAPABLE:
00696                 usbcfg.b.hnpcap = 0;
00697                 usbcfg.b.srpcap = 0;
00698                 break;
00699 
00700         case DWC_MODE_SRP_CAPABLE_DEVICE:
00701                 usbcfg.b.hnpcap = 0;
00702                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
00703                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
00704                 break;
00705 
00706         case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
00707                 usbcfg.b.hnpcap = 0;
00708                 usbcfg.b.srpcap = 0;
00709                 break;
00710 
00711         case DWC_MODE_SRP_CAPABLE_HOST:
00712                 usbcfg.b.hnpcap = 0;
00713                 usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
00714                                    DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
00715                 break;
00716 
00717         case DWC_MODE_NO_SRP_CAPABLE_HOST:
00718                 usbcfg.b.hnpcap = 0;
00719                 usbcfg.b.srpcap = 0;
00720                 break;
00721         }
00722 
00723         dwc_write_reg32(&global_regs->gusbcfg, usbcfg.d32);
00724 
00725 #ifdef CONFIG_USB_DWC_OTG_LPM
00726         if (core_if->core_params->lpm_enable) {
00727                 glpmcfg_data_t lpmcfg = {.d32 = 0 };
00728 
00729                 /* To enable LPM support set lpm_cap_en bit */
00730                 lpmcfg.b.lpm_cap_en = 1;
00731 
00732                 /* Make AppL1Res ACK */
00733                 lpmcfg.b.appl_resp = 1;
00734 
00735                 /* Retry 3 times */
00736                 lpmcfg.b.retry_count = 3;
00737 
00738                 dwc_modify_reg32(&core_if->core_global_regs->glpmcfg,
00739                                  0, lpmcfg.d32);
00740 
00741         }
00742 #endif
00743         if (core_if->core_params->ic_usb_cap) {
00744                 gusbcfg_data_t gusbcfg = {.d32 = 0 };
00745                 gusbcfg.b.ic_usb_cap = 1;
00746                 dwc_modify_reg32(&core_if->core_global_regs->gusbcfg,
00747                                  0, gusbcfg.d32);
00748         }
00749 
00750         /* Enable common interrupts */
00751         dwc_otg_enable_common_interrupts(core_if);
00752 
00753         /* Do device or host intialization based on mode during PCD
00754          * and HCD initialization  */
00755         if (dwc_otg_is_host_mode(core_if)) {
00756                 DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
00757                 core_if->op_state = A_HOST;
00758         } else {
00759                 DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
00760                 core_if->op_state = B_PERIPHERAL;
00761 #ifdef DWC_DEVICE_ONLY
00762                 dwc_otg_core_dev_init(core_if);
00763 #endif
00764         }
00765 }
00766 
00772 void dwc_otg_enable_device_interrupts(dwc_otg_core_if_t * core_if)
00773 {
00774         gintmsk_data_t intr_mask = {.d32 = 0 };
00775         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00776 
00777         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
00778 
00779         /* Disable all interrupts. */
00780         dwc_write_reg32(&global_regs->gintmsk, 0);
00781 
00782         /* Clear any pending interrupts */
00783         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
00784 
00785         /* Enable the common interrupts */
00786         dwc_otg_enable_common_interrupts(core_if);
00787 
00788         /* Enable interrupts */
00789         intr_mask.b.usbreset = 1;
00790         intr_mask.b.enumdone = 1;
00791 
00792         if (!core_if->multiproc_int_enable) {
00793                 intr_mask.b.inepintr = 1;
00794                 intr_mask.b.outepintr = 1;
00795         }
00796 
00797         intr_mask.b.erlysuspend = 1;
00798 
00799         if (core_if->en_multiple_tx_fifo == 0) {
00800                 intr_mask.b.epmismatch = 1;
00801         }
00802 #ifdef DWC_EN_ISOC
00803         if (core_if->dma_enable) {
00804                 if (core_if->dma_desc_enable == 0) {
00805                         if (core_if->pti_enh_enable) {
00806                                 dctl_data_t dctl = {.d32 = 0 };
00807                                 dctl.b.ifrmnum = 1;
00808                                 dwc_modify_reg32(&core_if->dev_if->
00809                                                  dev_global_regs->dctl, 0,
00810                                                  dctl.d32);
00811                         } else {
00812                                 intr_mask.b.incomplisoin = 1;
00813                                 intr_mask.b.incomplisoout = 1;
00814                         }
00815                 }
00816         } else {
00817                 intr_mask.b.incomplisoin = 1;
00818                 intr_mask.b.incomplisoout = 1;
00819         }
00820 #endif                          /* DWC_EN_ISOC */
00821 
00823 #ifdef USE_PERIODIC_EP
00824         intr_mask.b.isooutdrop = 1;
00825         intr_mask.b.eopframe = 1;
00826         intr_mask.b.incomplisoin = 1;
00827         intr_mask.b.incomplisoout = 1;
00828 #endif
00829 
00830         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
00831 
00832         DWC_DEBUGPL(DBG_CIL, "%s() gintmsk=%0x\n", __func__,
00833                     dwc_read_reg32(&global_regs->gintmsk));
00834 }
00835 
00843 void dwc_otg_core_dev_init(dwc_otg_core_if_t * core_if)
00844 {
00845         int i;
00846         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
00847         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
00848         dwc_otg_core_params_t *params = core_if->core_params;
00849         dcfg_data_t dcfg = {.d32 = 0 };
00850         grstctl_t resetctl = {.d32 = 0 };
00851         uint32_t rx_fifo_size;
00852         fifosize_data_t nptxfifosize;
00853         fifosize_data_t txfifosize;
00854         dthrctl_data_t dthrctl;
00855         fifosize_data_t ptxfifosize;
00856 
00857         /* Restart the Phy Clock */
00858         dwc_write_reg32(core_if->pcgcctl, 0);
00859 
00860         /* Device configuration register */
00861         init_devspd(core_if);
00862         dcfg.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dcfg);
00863         dcfg.b.descdma = (core_if->dma_desc_enable) ? 1 : 0;
00864         dcfg.b.perfrint = DWC_DCFG_FRAME_INTERVAL_80;
00865 
00866         dwc_write_reg32(&dev_if->dev_global_regs->dcfg, dcfg.d32);
00867 
00868         /* Configure data FIFO sizes */
00869         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
00870                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
00871                             core_if->total_fifo_size);
00872                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
00873                             params->dev_rx_fifo_size);
00874                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
00875                             params->dev_nperio_tx_fifo_size);
00876 
00877                 /* Rx FIFO */
00878                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
00879                             dwc_read_reg32(&global_regs->grxfsiz));
00880 
00881 #ifdef DWC_UTE_CFI
00882                 core_if->pwron_rxfsiz = dwc_read_reg32(&global_regs->grxfsiz);
00883                 core_if->init_rxfsiz = params->dev_rx_fifo_size;
00884 #endif
00885                 rx_fifo_size = params->dev_rx_fifo_size;
00886                 dwc_write_reg32(&global_regs->grxfsiz, rx_fifo_size);
00887 
00888                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
00889                             dwc_read_reg32(&global_regs->grxfsiz));
00890 
00892                 core_if->p_tx_msk = 0;
00893 
00895                 core_if->tx_msk = 0;
00896 
00897                 if (core_if->en_multiple_tx_fifo == 0) {
00898                         /* Non-periodic Tx FIFO */
00899                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
00900                                     dwc_read_reg32(&global_regs->gnptxfsiz));
00901 
00902                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
00903                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
00904 
00905                         dwc_write_reg32(&global_regs->gnptxfsiz,
00906                                         nptxfifosize.d32);
00907 
00908                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
00909                                     dwc_read_reg32(&global_regs->gnptxfsiz));
00910 
00912                         /*
00913                          * Periodic Tx FIFOs These FIFOs are numbered from 1 to 15.
00914                          * Indexes of the FIFO size module parameters in the
00915                          * dev_perio_tx_fifo_size array and the FIFO size registers in
00916                          * the dptxfsiz array run from 0 to 14.
00917                          */
00919                         ptxfifosize.b.startaddr =
00920                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
00921                         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep;
00922                              i++) {
00923                                 ptxfifosize.b.depth =
00924                                     params->dev_perio_tx_fifo_size[i];
00925                                 DWC_DEBUGPL(DBG_CIL,
00926                                             "initial dptxfsiz_dieptxf[%d]=%08x\n",
00927                                             i,
00928                                             dwc_read_reg32(&global_regs->
00929                                                            dptxfsiz_dieptxf
00930                                                            [i]));
00931                                 dwc_write_reg32(&global_regs->
00932                                                 dptxfsiz_dieptxf[i],
00933                                                 ptxfifosize.d32);
00934                                 DWC_DEBUGPL(DBG_CIL,
00935                                             "new dptxfsiz_dieptxf[%d]=%08x\n",
00936                                             i,
00937                                             dwc_read_reg32(&global_regs->
00938                                                            dptxfsiz_dieptxf
00939                                                            [i]));
00940                                 ptxfifosize.b.startaddr += ptxfifosize.b.depth;
00941                         }
00942                 } else {
00943                         /*
00944                          * Tx FIFOs These FIFOs are numbered from 1 to 15.
00945                          * Indexes of the FIFO size module parameters in the
00946                          * dev_tx_fifo_size array and the FIFO size registers in
00947                          * the dptxfsiz_dieptxf array run from 0 to 14.
00948                          */
00949 
00950                         /* Non-periodic Tx FIFO */
00951                         DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
00952                                     dwc_read_reg32(&global_regs->gnptxfsiz));
00953 
00954 #ifdef DWC_UTE_CFI
00955                         core_if->pwron_gnptxfsiz =
00956                             (dwc_read_reg32(&global_regs->gnptxfsiz) >> 16);
00957                         core_if->init_gnptxfsiz =
00958                             params->dev_nperio_tx_fifo_size;
00959 #endif
00960                         nptxfifosize.b.depth = params->dev_nperio_tx_fifo_size;
00961                         nptxfifosize.b.startaddr = params->dev_rx_fifo_size;
00962 
00963                         dwc_write_reg32(&global_regs->gnptxfsiz,
00964                                         nptxfifosize.d32);
00965 
00966                         DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
00967                                     dwc_read_reg32(&global_regs->gnptxfsiz));
00968 
00969                         txfifosize.b.startaddr =
00970                             nptxfifosize.b.startaddr + nptxfifosize.b.depth;
00971 
00972                         for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
00973 
00974                                 txfifosize.b.depth =
00975                                     params->dev_tx_fifo_size[i];
00976 
00977                                 DWC_DEBUGPL(DBG_CIL,
00978                                             "initial dptxfsiz_dieptxf[%d]=%08x\n",
00979                                             i,
00980                                             dwc_read_reg32(&global_regs->
00981                                                            dptxfsiz_dieptxf
00982                                                            [i]));
00983 
00984 #ifdef DWC_UTE_CFI
00985                                 core_if->pwron_txfsiz[i] =
00986                                     (dwc_read_reg32
00987                                      (&global_regs->dptxfsiz_dieptxf[i]) >> 16);
00988                                 core_if->init_txfsiz[i] =
00989                                     params->dev_tx_fifo_size[i];
00990 #endif
00991                                 dwc_write_reg32(&global_regs->
00992                                                 dptxfsiz_dieptxf[i],
00993                                                 txfifosize.d32);
00994 
00995                                 DWC_DEBUGPL(DBG_CIL,
00996                                             "new dptxfsiz_dieptxf[%d]=%08x\n",
00997                                             i,
00998                                             dwc_read_reg32(&global_regs->
00999                                                            dptxfsiz_dieptxf
01000                                                            [i]));
01001 
01002                                 txfifosize.b.startaddr += txfifosize.b.depth;
01003                         }
01004                 }
01005         }
01006         /* Flush the FIFOs */
01007         dwc_otg_flush_tx_fifo(core_if, 0x10);   /* all Tx FIFOs */
01008         dwc_otg_flush_rx_fifo(core_if);
01009 
01010         /* Flush the Learning Queue. */
01011         resetctl.b.intknqflsh = 1;
01012         dwc_write_reg32(&core_if->core_global_regs->grstctl, resetctl.d32);
01013 
01014         /* Clear all pending Device Interrupts */
01018         if (core_if->multiproc_int_enable) {
01019                 for (i = 0; i < core_if->dev_if->num_in_eps; ++i) {
01020                         dwc_write_reg32(&dev_if->dev_global_regs->
01021                                         diepeachintmsk[i], 0);
01022                 }
01023 
01024                 for (i = 0; i < core_if->dev_if->num_out_eps; ++i) {
01025                         dwc_write_reg32(&dev_if->dev_global_regs->
01026                                         doepeachintmsk[i], 0);
01027                 }
01028 
01029                 dwc_write_reg32(&dev_if->dev_global_regs->deachint, 0xFFFFFFFF);
01030                 dwc_write_reg32(&dev_if->dev_global_regs->deachintmsk, 0);
01031         } else {
01032                 dwc_write_reg32(&dev_if->dev_global_regs->diepmsk, 0);
01033                 dwc_write_reg32(&dev_if->dev_global_regs->doepmsk, 0);
01034                 dwc_write_reg32(&dev_if->dev_global_regs->daint, 0xFFFFFFFF);
01035                 dwc_write_reg32(&dev_if->dev_global_regs->daintmsk, 0);
01036         }
01037 
01038         for (i = 0; i <= dev_if->num_in_eps; i++) {
01039                 depctl_data_t depctl;
01040                 depctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[i]->diepctl);
01041                 if (depctl.b.epena) {
01042                         depctl.d32 = 0;
01043                         depctl.b.epdis = 1;
01044                         depctl.b.snak = 1;
01045                 } else {
01046                         depctl.d32 = 0;
01047                 }
01048 
01049                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepctl, depctl.d32);
01050 
01051                 dwc_write_reg32(&dev_if->in_ep_regs[i]->dieptsiz, 0);
01052                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepdma, 0);
01053                 dwc_write_reg32(&dev_if->in_ep_regs[i]->diepint, 0xFF);
01054         }
01055 
01056         for (i = 0; i <= dev_if->num_out_eps; i++) {
01057                 depctl_data_t depctl;
01058                 depctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[i]->doepctl);
01059                 if (depctl.b.epena) {
01060                         depctl.d32 = 0;
01061                         depctl.b.epdis = 1;
01062                         depctl.b.snak = 1;
01063                 } else {
01064                         depctl.d32 = 0;
01065                 }
01066 
01067                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepctl, depctl.d32);
01068 
01069                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doeptsiz, 0);
01070                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepdma, 0);
01071                 dwc_write_reg32(&dev_if->out_ep_regs[i]->doepint, 0xFF);
01072         }
01073 
01074         if (core_if->en_multiple_tx_fifo && core_if->dma_enable) {
01075                 dev_if->non_iso_tx_thr_en = params->thr_ctl & 0x1;
01076                 dev_if->iso_tx_thr_en = (params->thr_ctl >> 1) & 0x1;
01077                 dev_if->rx_thr_en = (params->thr_ctl >> 2) & 0x1;
01078 
01079                 dev_if->rx_thr_length = params->rx_thr_length;
01080                 dev_if->tx_thr_length = params->tx_thr_length;
01081 
01082                 dev_if->setup_desc_index = 0;
01083 
01084                 dthrctl.d32 = 0;
01085                 dthrctl.b.non_iso_thr_en = dev_if->non_iso_tx_thr_en;
01086                 dthrctl.b.iso_thr_en = dev_if->iso_tx_thr_en;
01087                 dthrctl.b.tx_thr_len = dev_if->tx_thr_length;
01088                 dthrctl.b.rx_thr_en = dev_if->rx_thr_en;
01089                 dthrctl.b.rx_thr_len = dev_if->rx_thr_length;
01090                 dthrctl.b.ahb_thr_ratio = params->ahb_thr_ratio;
01091 
01092                 dwc_write_reg32(&dev_if->dev_global_regs->dtknqr3_dthrctl,
01093                                 dthrctl.d32);
01094 
01095                 DWC_DEBUGPL(DBG_CIL,
01096                             "Non ISO Tx Thr - %d\nISO Tx Thr - %d\nRx Thr - %d\nTx Thr Len - %d\nRx Thr Len - %d\n",
01097                             dthrctl.b.non_iso_thr_en, dthrctl.b.iso_thr_en,
01098                             dthrctl.b.rx_thr_en, dthrctl.b.tx_thr_len,
01099                             dthrctl.b.rx_thr_len);
01100 
01101         }
01102 
01103         dwc_otg_enable_device_interrupts(core_if);
01104 
01105         {
01106                 diepmsk_data_t msk = {.d32 = 0 };
01107                 msk.b.txfifoundrn = 1;
01108                 if (core_if->multiproc_int_enable) {
01109                         dwc_modify_reg32(&dev_if->dev_global_regs->
01110                                          diepeachintmsk[0], msk.d32, msk.d32);
01111                 } else {
01112                         dwc_modify_reg32(&dev_if->dev_global_regs->diepmsk,
01113                                          msk.d32, msk.d32);
01114                 }
01115         }
01116 
01117         if (core_if->multiproc_int_enable) {
01118                 /* Set NAK on Babble */
01119                 dctl_data_t dctl = {.d32 = 0 };
01120                 dctl.b.nakonbble = 1;
01121                 dwc_modify_reg32(&dev_if->dev_global_regs->dctl, 0, dctl.d32);
01122         }
01123 }
01124 
01130 void dwc_otg_enable_host_interrupts(dwc_otg_core_if_t * core_if)
01131 {
01132         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01133         gintmsk_data_t intr_mask = {.d32 = 0 };
01134 
01135         DWC_DEBUGPL(DBG_CIL, "%s()\n", __func__);
01136 
01137         /* Disable all interrupts. */
01138         dwc_write_reg32(&global_regs->gintmsk, 0);
01139 
01140         /* Clear any pending interrupts. */
01141         dwc_write_reg32(&global_regs->gintsts, 0xFFFFFFFF);
01142 
01143         /* Enable the common interrupts */
01144         dwc_otg_enable_common_interrupts(core_if);
01145 
01146         /*
01147          * Enable host mode interrupts without disturbing common
01148          * interrupts.
01149          */
01150          
01151         /* Do not need sof interrupt for Descriptor DMA*/ 
01152         if (!core_if->dma_desc_enable) 
01153         intr_mask.b.sofintr = 1;
01154         intr_mask.b.portintr = 1;
01155         intr_mask.b.hcintr = 1;
01156 
01157         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, intr_mask.d32);
01158 }
01159 
01165 void dwc_otg_disable_host_interrupts(dwc_otg_core_if_t * core_if)
01166 {
01167         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01168         gintmsk_data_t intr_mask = {.d32 = 0 };
01169 
01170         DWC_DEBUGPL(DBG_CILV, "%s()\n", __func__);
01171 
01172         /*
01173          * Disable host mode interrupts without disturbing common
01174          * interrupts.
01175          */
01176         intr_mask.b.sofintr = 1;
01177         intr_mask.b.portintr = 1;
01178         intr_mask.b.hcintr = 1;
01179         intr_mask.b.ptxfempty = 1;
01180         intr_mask.b.nptxfempty = 1;
01181 
01182         dwc_modify_reg32(&global_regs->gintmsk, intr_mask.d32, 0);
01183 }
01184 
01196 void dwc_otg_core_host_init(dwc_otg_core_if_t * core_if)
01197 {
01198         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
01199         dwc_otg_host_if_t *host_if = core_if->host_if;
01200         dwc_otg_core_params_t *params = core_if->core_params;
01201         hprt0_data_t hprt0 = {.d32 = 0 };
01202         fifosize_data_t nptxfifosize;
01203         fifosize_data_t ptxfifosize;
01204         int i;
01205         hcchar_data_t hcchar;
01206         hcfg_data_t hcfg;
01207         dwc_otg_hc_regs_t *hc_regs;
01208         int num_channels;
01209         gotgctl_data_t gotgctl = {.d32 = 0 };
01210 
01211         DWC_DEBUGPL(DBG_CILV, "%s(%p)\n", __func__, core_if);
01212 
01213         /* Restart the Phy Clock */
01214         dwc_write_reg32(core_if->pcgcctl, 0);
01215 
01216         /* Initialize Host Configuration Register */
01217         init_fslspclksel(core_if);
01218         if (core_if->core_params->speed == DWC_SPEED_PARAM_FULL) {
01219                 hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
01220                 hcfg.b.fslssupp = 1;
01221                 dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
01222                 
01223         }
01224 
01225         if (core_if->core_params->dma_desc_enable) {
01226                 uint8_t op_mode = core_if->hwcfg2.b.op_mode;    
01227                 if (!(core_if->hwcfg4.b.desc_dma && (core_if->snpsid >= OTG_CORE_REV_2_90a) &&
01228                                 ((op_mode == DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG) ||
01229                                 (op_mode == DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG) || 
01230                                 (op_mode == DWC_HWCFG2_OP_MODE_NO_HNP_SRP_CAPABLE_OTG) ||
01231                                 (op_mode == DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST) ||
01232                                 (op_mode == DWC_HWCFG2_OP_MODE_NO_SRP_CAPABLE_HOST)))) {
01233                                 
01234                                 DWC_ERROR("Host can't operate in Descriptor DMA mode.\n"
01235                                           "Either core version is below 2.90a or "
01236                                           "GHWCFG2, GHWCFG4 registers' values do not allow Descriptor DMA in host mode.\n"
01237                                           "To run the driver in Buffer DMA host mode set dma_desc_enable "
01238                                           "module parameter to 0.\n");
01239                                 return;
01240                 }               
01241                 hcfg.d32 = dwc_read_reg32(&host_if->host_global_regs->hcfg);
01242                 hcfg.b.descdma = 1;
01243                 dwc_write_reg32(&host_if->host_global_regs->hcfg, hcfg.d32);
01244         }
01245         
01246         /* Configure data FIFO sizes */
01247         if (core_if->hwcfg2.b.dynamic_fifo && params->enable_dynamic_fifo) {
01248                 DWC_DEBUGPL(DBG_CIL, "Total FIFO Size=%d\n",
01249                             core_if->total_fifo_size);
01250                 DWC_DEBUGPL(DBG_CIL, "Rx FIFO Size=%d\n",
01251                             params->host_rx_fifo_size);
01252                 DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO Size=%d\n",
01253                             params->host_nperio_tx_fifo_size);
01254                 DWC_DEBUGPL(DBG_CIL, "P Tx FIFO Size=%d\n",
01255                             params->host_perio_tx_fifo_size);
01256 
01257                 /* Rx FIFO */
01258                 DWC_DEBUGPL(DBG_CIL, "initial grxfsiz=%08x\n",
01259                             dwc_read_reg32(&global_regs->grxfsiz));
01260                 dwc_write_reg32(&global_regs->grxfsiz,
01261                                 params->host_rx_fifo_size);
01262                 DWC_DEBUGPL(DBG_CIL, "new grxfsiz=%08x\n",
01263                             dwc_read_reg32(&global_regs->grxfsiz));
01264 
01265                 /* Non-periodic Tx FIFO */
01266                 DWC_DEBUGPL(DBG_CIL, "initial gnptxfsiz=%08x\n",
01267                             dwc_read_reg32(&global_regs->gnptxfsiz));
01268                 nptxfifosize.b.depth = params->host_nperio_tx_fifo_size;
01269                 nptxfifosize.b.startaddr = params->host_rx_fifo_size;
01270                 dwc_write_reg32(&global_regs->gnptxfsiz, nptxfifosize.d32);
01271                 DWC_DEBUGPL(DBG_CIL, "new gnptxfsiz=%08x\n",
01272                             dwc_read_reg32(&global_regs->gnptxfsiz));
01273 
01274                 /* Periodic Tx FIFO */
01275                 DWC_DEBUGPL(DBG_CIL, "initial hptxfsiz=%08x\n",
01276                             dwc_read_reg32(&global_regs->hptxfsiz));
01277                 ptxfifosize.b.depth = params->host_perio_tx_fifo_size;
01278                 ptxfifosize.b.startaddr =
01279                     nptxfifosize.b.startaddr + nptxfifosize.b.depth;
01280                 dwc_write_reg32(&global_regs->hptxfsiz, ptxfifosize.d32);
01281                 DWC_DEBUGPL(DBG_CIL, "new hptxfsiz=%08x\n",
01282                             dwc_read_reg32(&global_regs->hptxfsiz));
01283         }
01284 
01285         /* Clear Host Set HNP Enable in the OTG Control Register */
01286         gotgctl.b.hstsethnpen = 1;
01287         dwc_modify_reg32(&global_regs->gotgctl, gotgctl.d32, 0);
01288 
01289         /* Make sure the FIFOs are flushed. */
01290         dwc_otg_flush_tx_fifo(core_if, 0x10 /* all Tx FIFOs */ );
01291         dwc_otg_flush_rx_fifo(core_if);
01292 
01293         if(!core_if->core_params->dma_desc_enable) {
01294                 /* Flush out any leftover queued requests. */
01295                 num_channels = core_if->core_params->host_channels;
01296         
01297                 for (i = 0; i < num_channels; i++) {
01298                         hc_regs = core_if->host_if->hc_regs[i];
01299                         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01300                         hcchar.b.chen = 0;
01301                         hcchar.b.chdis = 1;
01302                         hcchar.b.epdir = 0;
01303                         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
01304                 }
01305 
01306                 /* Halt all channels to put them into a known state. */
01307                 for (i = 0; i < num_channels; i++) {
01308                         int count = 0;
01309                         hc_regs = core_if->host_if->hc_regs[i];
01310                         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01311                         hcchar.b.chen = 1;
01312                         hcchar.b.chdis = 1;
01313                         hcchar.b.epdir = 0;
01314                         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
01315                         DWC_DEBUGPL(DBG_HCDV, "%s: Halt channel %d\n", __func__, i);
01316                         do {
01317                                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01318                                 if (++count > 1000) {
01319                                         DWC_ERROR
01320                                             ("%s: Unable to clear halt on channel %d\n",
01321                                              __func__, i);
01322                                         break;
01323                                 }
01324                                 dwc_udelay(1);
01325                         } while (hcchar.b.chen);
01326                 }
01327         }
01328         
01329         /* Turn on the vbus power. */
01330         DWC_PRINTF("Init: Port Power? op_state=%d\n", core_if->op_state);
01331         if (core_if->op_state == A_HOST) {
01332                 hprt0.d32 = dwc_otg_read_hprt0(core_if);
01333                 DWC_PRINTF("Init: Power Port (%d)\n", hprt0.b.prtpwr);
01334                 if (hprt0.b.prtpwr == 0) {
01335                         hprt0.b.prtpwr = 1;
01336                         dwc_write_reg32(host_if->hprt0, hprt0.d32);
01337                 }
01338         }
01339 
01340         dwc_otg_enable_host_interrupts(core_if);
01341 }
01342 
01352 void dwc_otg_hc_init(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
01353 {
01354         uint32_t intr_enable;
01355         hcintmsk_data_t hc_intr_mask;
01356         gintmsk_data_t gintmsk = {.d32 = 0 };
01357         hcchar_data_t hcchar;
01358         hcsplt_data_t hcsplt;
01359 
01360         uint8_t hc_num = hc->hc_num;
01361         dwc_otg_host_if_t *host_if = core_if->host_if;
01362         dwc_otg_hc_regs_t *hc_regs = host_if->hc_regs[hc_num];
01363 
01364         /* Clear old interrupt conditions for this host channel. */
01365         hc_intr_mask.d32 = 0xFFFFFFFF;
01366         hc_intr_mask.b.reserved14_31 = 0;
01367         dwc_write_reg32(&hc_regs->hcint, hc_intr_mask.d32);
01368 
01369         /* Enable channel interrupts required for this transfer. */
01370         hc_intr_mask.d32 = 0;
01371         hc_intr_mask.b.chhltd = 1;
01372         if (core_if->dma_enable) {
01373                 /* For Descriptor DMA mode core halts the channel on AHB error. Interrupt is not required */
01374                 if (!core_if->dma_desc_enable)
01375                         hc_intr_mask.b.ahberr = 1;
01376                 else {
01377                         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC) 
01378                                 hc_intr_mask.b.xfercompl = 1;
01379                 }
01380                 
01381                 if (hc->error_state && !hc->do_split &&
01382                     hc->ep_type != DWC_OTG_EP_TYPE_ISOC) {
01383                         hc_intr_mask.b.ack = 1;
01384                         if (hc->ep_is_in) {
01385                                 hc_intr_mask.b.datatglerr = 1;
01386                                 if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
01387                                         hc_intr_mask.b.nak = 1;
01388                                 }
01389                         }
01390                 }
01391         } else {
01392                 switch (hc->ep_type) {
01393                 case DWC_OTG_EP_TYPE_CONTROL:
01394                 case DWC_OTG_EP_TYPE_BULK:
01395                         hc_intr_mask.b.xfercompl = 1;
01396                         hc_intr_mask.b.stall = 1;
01397                         hc_intr_mask.b.xacterr = 1;
01398                         hc_intr_mask.b.datatglerr = 1;
01399                         if (hc->ep_is_in) {
01400                                 hc_intr_mask.b.bblerr = 1;
01401                         } else {
01402                                 hc_intr_mask.b.nak = 1;
01403                                 hc_intr_mask.b.nyet = 1;
01404                                 if (hc->do_ping) {
01405                                         hc_intr_mask.b.ack = 1;
01406                                 }
01407                         }
01408 
01409                         if (hc->do_split) {
01410                                 hc_intr_mask.b.nak = 1;
01411                                 if (hc->complete_split) {
01412                                         hc_intr_mask.b.nyet = 1;
01413                                 } else {
01414                                         hc_intr_mask.b.ack = 1;
01415                                 }
01416                         }
01417 
01418                         if (hc->error_state) {
01419                                 hc_intr_mask.b.ack = 1;
01420                         }
01421                         break;
01422                 case DWC_OTG_EP_TYPE_INTR:
01423                         hc_intr_mask.b.xfercompl = 1;
01424                         hc_intr_mask.b.nak = 1;
01425                         hc_intr_mask.b.stall = 1;
01426                         hc_intr_mask.b.xacterr = 1;
01427                         hc_intr_mask.b.datatglerr = 1;
01428                         hc_intr_mask.b.frmovrun = 1;
01429 
01430                         if (hc->ep_is_in) {
01431                                 hc_intr_mask.b.bblerr = 1;
01432                         }
01433                         if (hc->error_state) {
01434                                 hc_intr_mask.b.ack = 1;
01435                         }
01436                         if (hc->do_split) {
01437                                 if (hc->complete_split) {
01438                                         hc_intr_mask.b.nyet = 1;
01439                                 } else {
01440                                         hc_intr_mask.b.ack = 1;
01441                                 }
01442                         }
01443                         break;
01444                 case DWC_OTG_EP_TYPE_ISOC:
01445                         hc_intr_mask.b.xfercompl = 1;
01446                         hc_intr_mask.b.frmovrun = 1;
01447                         hc_intr_mask.b.ack = 1;
01448 
01449                         if (hc->ep_is_in) {
01450                                 hc_intr_mask.b.xacterr = 1;
01451                                 hc_intr_mask.b.bblerr = 1;
01452                         }
01453                         break;
01454                 }
01455         }
01456         dwc_write_reg32(&hc_regs->hcintmsk, hc_intr_mask.d32);
01457 
01458         /* Enable the top level host channel interrupt. */
01459         intr_enable = (1 << hc_num);
01460         dwc_modify_reg32(&host_if->host_global_regs->haintmsk, 0, intr_enable);
01461 
01462         /* Make sure host channel interrupts are enabled. */
01463         gintmsk.b.hcintr = 1;
01464         dwc_modify_reg32(&core_if->core_global_regs->gintmsk, 0, gintmsk.d32);
01465 
01466         /*
01467          * Program the HCCHARn register with the endpoint characteristics for
01468          * the current transfer.
01469          */
01470         hcchar.d32 = 0;
01471         hcchar.b.devaddr = hc->dev_addr;
01472         hcchar.b.epnum = hc->ep_num;
01473         hcchar.b.epdir = hc->ep_is_in;
01474         hcchar.b.lspddev = (hc->speed == DWC_OTG_EP_SPEED_LOW);
01475         hcchar.b.eptype = hc->ep_type;
01476         hcchar.b.mps = hc->max_packet;
01477 
01478         dwc_write_reg32(&host_if->hc_regs[hc_num]->hcchar, hcchar.d32);
01479 
01480         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
01481         DWC_DEBUGPL(DBG_HCDV, "  Dev Addr: %d\n", hcchar.b.devaddr);
01482         DWC_DEBUGPL(DBG_HCDV, "  Ep Num: %d\n", hcchar.b.epnum);
01483         DWC_DEBUGPL(DBG_HCDV, "  Is In: %d\n", hcchar.b.epdir);
01484         DWC_DEBUGPL(DBG_HCDV, "  Is Low Speed: %d\n", hcchar.b.lspddev);
01485         DWC_DEBUGPL(DBG_HCDV, "  Ep Type: %d\n", hcchar.b.eptype);
01486         DWC_DEBUGPL(DBG_HCDV, "  Max Pkt: %d\n", hcchar.b.mps);
01487         DWC_DEBUGPL(DBG_HCDV, "  Multi Cnt: %d\n", hcchar.b.multicnt);
01488 
01489         /*
01490          * Program the HCSPLIT register for SPLITs
01491          */
01492         hcsplt.d32 = 0;
01493         if (hc->do_split) {
01494                 DWC_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n",
01495                             hc->hc_num,
01496                             hc->complete_split ? "CSPLIT" : "SSPLIT");
01497                 hcsplt.b.compsplt = hc->complete_split;
01498                 hcsplt.b.xactpos = hc->xact_pos;
01499                 hcsplt.b.hubaddr = hc->hub_addr;
01500                 hcsplt.b.prtaddr = hc->port_addr;
01501                 DWC_DEBUGPL(DBG_HCDV, "   comp split %d\n", hc->complete_split);
01502                 DWC_DEBUGPL(DBG_HCDV, "   xact pos %d\n", hc->xact_pos);
01503                 DWC_DEBUGPL(DBG_HCDV, "   hub addr %d\n", hc->hub_addr);
01504                 DWC_DEBUGPL(DBG_HCDV, "   port addr %d\n", hc->port_addr);
01505                 DWC_DEBUGPL(DBG_HCDV, "   is_in %d\n", hc->ep_is_in);
01506                 DWC_DEBUGPL(DBG_HCDV, "   Max Pkt: %d\n", hcchar.b.mps);
01507                 DWC_DEBUGPL(DBG_HCDV, "   xferlen: %d\n", hc->xfer_len);
01508         }
01509         dwc_write_reg32(&host_if->hc_regs[hc_num]->hcsplt, hcsplt.d32);
01510 
01511 }
01512 
01540 void dwc_otg_hc_halt(dwc_otg_core_if_t * core_if,
01541                      dwc_hc_t * hc, dwc_otg_halt_status_e halt_status)
01542 {
01543         gnptxsts_data_t nptxsts;
01544         hptxsts_data_t hptxsts;
01545         hcchar_data_t hcchar;
01546         dwc_otg_hc_regs_t *hc_regs;
01547         dwc_otg_core_global_regs_t *global_regs;
01548         dwc_otg_host_global_regs_t *host_global_regs;
01549 
01550         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
01551         global_regs = core_if->core_global_regs;
01552         host_global_regs = core_if->host_if->host_global_regs;
01553 
01554         DWC_ASSERT(!(halt_status == DWC_OTG_HC_XFER_NO_HALT_STATUS),
01555                    "halt_status = %d\n", halt_status);
01556 
01557         if (halt_status == DWC_OTG_HC_XFER_URB_DEQUEUE ||
01558             halt_status == DWC_OTG_HC_XFER_AHB_ERR) {
01559                 /*
01560                  * Disable all channel interrupts except Ch Halted. The QTD
01561                  * and QH state associated with this transfer has been cleared
01562                  * (in the case of URB_DEQUEUE), so the channel needs to be
01563                  * shut down carefully to prevent crashes.
01564                  */
01565                 hcintmsk_data_t hcintmsk;
01566                 hcintmsk.d32 = 0;
01567                 hcintmsk.b.chhltd = 1;
01568                 dwc_write_reg32(&hc_regs->hcintmsk, hcintmsk.d32);
01569 
01570                 /*
01571                  * Make sure no other interrupts besides halt are currently
01572                  * pending. Handling another interrupt could cause a crash due
01573                  * to the QTD and QH state.
01574                  */
01575                 dwc_write_reg32(&hc_regs->hcint, ~hcintmsk.d32);
01576 
01577                 /*
01578                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
01579                  * even if the channel was already halted for some other
01580                  * reason.
01581                  */
01582                 hc->halt_status = halt_status;
01583 
01584                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01585                 if (hcchar.b.chen == 0) {
01586                         /*
01587                          * The channel is either already halted or it hasn't
01588                          * started yet. In DMA mode, the transfer may halt if
01589                          * it finishes normally or a condition occurs that
01590                          * requires driver intervention. Don't want to halt
01591                          * the channel again. In either Slave or DMA mode,
01592                          * it's possible that the transfer has been assigned
01593                          * to a channel, but not started yet when an URB is
01594                          * dequeued. Don't want to halt a channel that hasn't
01595                          * started yet.
01596                          */
01597                         return;
01598                 }
01599         }
01600         if (hc->halt_pending) {
01601                 /*
01602                  * A halt has already been issued for this channel. This might
01603                  * happen when a transfer is aborted by a higher level in
01604                  * the stack.
01605                  */
01606 #ifdef DEBUG
01607                 DWC_PRINTF
01608                     ("*** %s: Channel %d, _hc->halt_pending already set ***\n",
01609                      __func__, hc->hc_num);
01610 
01611 #endif
01612                 return;
01613         }
01614 
01615         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01616         
01617         /* No need to set the bit in DDMA for disabling the channel */
01618         //TODO check it everywhere channel is disabled          
01619         if(!core_if->core_params->dma_desc_enable)
01620                 hcchar.b.chen = 1;
01621         hcchar.b.chdis = 1;
01622         
01623         if (!core_if->dma_enable) {
01624                 /* Check for space in the request queue to issue the halt. */
01625                 if (hc->ep_type == DWC_OTG_EP_TYPE_CONTROL ||
01626                     hc->ep_type == DWC_OTG_EP_TYPE_BULK) {
01627                         nptxsts.d32 = dwc_read_reg32(&global_regs->gnptxsts);
01628                         if (nptxsts.b.nptxqspcavail == 0) {
01629                                 hcchar.b.chen = 0;
01630                         }
01631                 } else {
01632                         hptxsts.d32 =
01633                             dwc_read_reg32(&host_global_regs->hptxsts);
01634                         if ((hptxsts.b.ptxqspcavail == 0)
01635                             || (core_if->queuing_high_bandwidth)) {
01636                                 hcchar.b.chen = 0;
01637                         }
01638                 }
01639         }
01640         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
01641 
01642         hc->halt_status = halt_status;
01643 
01644         if (hcchar.b.chen) {
01645                 hc->halt_pending = 1;
01646                 hc->halt_on_queue = 0;
01647         } else {
01648                 hc->halt_on_queue = 1;
01649         }
01650 
01651         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
01652         DWC_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n", hcchar.d32);
01653         DWC_DEBUGPL(DBG_HCDV, "  halt_pending: %d\n", hc->halt_pending);
01654         DWC_DEBUGPL(DBG_HCDV, "  halt_on_queue: %d\n", hc->halt_on_queue);
01655         DWC_DEBUGPL(DBG_HCDV, "  halt_status: %d\n", hc->halt_status);
01656 
01657         return;
01658 }
01659 
01667 void dwc_otg_hc_cleanup(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
01668 {
01669         dwc_otg_hc_regs_t *hc_regs;
01670 
01671         hc->xfer_started = 0;
01672 
01673         /*
01674          * Clear channel interrupt enables and any unhandled channel interrupt
01675          * conditions.
01676          */
01677         hc_regs = core_if->host_if->hc_regs[hc->hc_num];
01678         dwc_write_reg32(&hc_regs->hcintmsk, 0);
01679         dwc_write_reg32(&hc_regs->hcint, 0xFFFFFFFF);
01680 #ifdef DEBUG
01681         DWC_TIMER_CANCEL(core_if->hc_xfer_timer[hc->hc_num]);
01682 #endif
01683 }
01684 
01695 static inline void hc_set_even_odd_frame(dwc_otg_core_if_t * core_if,
01696                                          dwc_hc_t * hc, hcchar_data_t * hcchar)
01697 {
01698         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01699             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01700                 hfnum_data_t hfnum;
01701                 hfnum.d32 =
01702                     dwc_read_reg32(&core_if->host_if->host_global_regs->hfnum);
01703 
01704                 /* 1 if _next_ frame is odd, 0 if it's even */
01705                 hcchar->b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
01706 #ifdef DEBUG
01707                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR && hc->do_split
01708                     && !hc->complete_split) {
01709                         switch (hfnum.b.frnum & 0x7) {
01710                         case 7:
01711                                 core_if->hfnum_7_samples++;
01712                                 core_if->hfnum_7_frrem_accum += hfnum.b.frrem;
01713                                 break;
01714                         case 0:
01715                                 core_if->hfnum_0_samples++;
01716                                 core_if->hfnum_0_frrem_accum += hfnum.b.frrem;
01717                                 break;
01718                         default:
01719                                 core_if->hfnum_other_samples++;
01720                                 core_if->hfnum_other_frrem_accum +=
01721                                     hfnum.b.frrem;
01722                                 break;
01723                         }
01724                 }
01725 #endif
01726         }
01727 }
01728 
01729 #ifdef DEBUG
01730 void hc_xfer_timeout(void *ptr)
01731 {
01732         hc_xfer_info_t *xfer_info = (hc_xfer_info_t *) ptr;
01733         int hc_num = xfer_info->hc->hc_num;
01734         DWC_WARN("%s: timeout on channel %d\n", __func__, hc_num);
01735         DWC_WARN("      start_hcchar_val 0x%08x\n",
01736                  xfer_info->core_if->start_hcchar_val[hc_num]);
01737 }
01738 #endif
01739 
01740 void set_pid_isoc(dwc_hc_t * hc)
01741 {
01742         /* Set up the initial PID for the transfer. */
01743         if (hc->speed == DWC_OTG_EP_SPEED_HIGH) {
01744                 if (hc->ep_is_in) {
01745                         if (hc->multi_count == 1) {
01746                                 hc->data_pid_start =
01747                                     DWC_OTG_HC_PID_DATA0;
01748                         } else if (hc->multi_count == 2) {
01749                                 hc->data_pid_start =
01750                                     DWC_OTG_HC_PID_DATA1;
01751                         } else {
01752                                 hc->data_pid_start =
01753                                     DWC_OTG_HC_PID_DATA2;
01754                         }
01755                 } else {
01756                         if (hc->multi_count == 1) {
01757                                 hc->data_pid_start =
01758                                     DWC_OTG_HC_PID_DATA0;
01759                         } else {
01760                                 hc->data_pid_start =
01761                                     DWC_OTG_HC_PID_MDATA;
01762                         }
01763                 }
01764         } else {
01765                 hc->data_pid_start = DWC_OTG_HC_PID_DATA0;
01766         }
01767 }
01768 
01800 void dwc_otg_hc_start_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
01801 {
01802         hcchar_data_t hcchar;
01803         hctsiz_data_t hctsiz;
01804         uint16_t num_packets;
01805         uint32_t max_hc_xfer_size = core_if->core_params->max_transfer_size;
01806         uint16_t max_hc_pkt_count = core_if->core_params->max_packet_count;
01807         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
01808 
01809         hctsiz.d32 = 0;
01810 
01811         if (hc->do_ping) {
01812                 if (!core_if->dma_enable) {
01813                         dwc_otg_hc_do_ping(core_if, hc);
01814                         hc->xfer_started = 1;
01815                         return;
01816                 } else {
01817                         hctsiz.b.dopng = 1;
01818                 }
01819         }
01820 
01821         if (hc->do_split) {
01822                 num_packets = 1;
01823 
01824                 if (hc->complete_split && !hc->ep_is_in) {
01825                         /* For CSPLIT OUT Transfer, set the size to 0 so the
01826                          * core doesn't expect any data written to the FIFO */
01827                         hc->xfer_len = 0;
01828                 } else if (hc->ep_is_in || (hc->xfer_len > hc->max_packet)) {
01829                         hc->xfer_len = hc->max_packet;
01830                 } else if (!hc->ep_is_in && (hc->xfer_len > 188)) {
01831                         hc->xfer_len = 188;
01832                 }
01833 
01834                 hctsiz.b.xfersize = hc->xfer_len;
01835         } else {
01836                 /*
01837                  * Ensure that the transfer length and packet count will fit
01838                  * in the widths allocated for them in the HCTSIZn register.
01839                  */
01840                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01841                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01842                         /*
01843                          * Make sure the transfer size is no larger than one
01844                          * (micro)frame's worth of data. (A check was done
01845                          * when the periodic transfer was accepted to ensure
01846                          * that a (micro)frame's worth of data can be
01847                          * programmed into a channel.)
01848                          */
01849                         uint32_t max_periodic_len =
01850                             hc->multi_count * hc->max_packet;
01851                         if (hc->xfer_len > max_periodic_len) {
01852                                 hc->xfer_len = max_periodic_len;
01853                         } else {
01854                         }
01855                 } else if (hc->xfer_len > max_hc_xfer_size) {
01856                         /* Make sure that xfer_len is a multiple of max packet size. */
01857                         hc->xfer_len = max_hc_xfer_size - hc->max_packet + 1;
01858                 }
01859 
01860                 if (hc->xfer_len > 0) {
01861                         num_packets =
01862                             (hc->xfer_len + hc->max_packet -
01863                              1) / hc->max_packet;
01864                         if (num_packets > max_hc_pkt_count) {
01865                                 num_packets = max_hc_pkt_count;
01866                                 hc->xfer_len = num_packets * hc->max_packet;
01867                         }
01868                 } else {
01869                         /* Need 1 packet for transfer length of 0. */
01870                         num_packets = 1;
01871                 }
01872 
01873                 if (hc->ep_is_in) {
01874                         /* Always program an integral # of max packets for IN transfers. */
01875                         hc->xfer_len = num_packets * hc->max_packet;
01876                 }
01877 
01878                 if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
01879                     hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
01880                         /*
01881                          * Make sure that the multi_count field matches the
01882                          * actual transfer length.
01883                          */
01884                         hc->multi_count = num_packets;
01885                 }
01886 
01887                 if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
01888                         set_pid_isoc(hc);
01889 
01890                 hctsiz.b.xfersize = hc->xfer_len;
01891         }
01892 
01893         hc->start_pkt_count = num_packets;
01894         hctsiz.b.pktcnt = num_packets;
01895         hctsiz.b.pid = hc->data_pid_start;
01896         dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
01897 
01898         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
01899         DWC_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
01900         DWC_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n", hctsiz.b.pktcnt);
01901         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
01902 
01903         if (core_if->dma_enable) {
01904                 dwc_dma_t dma_addr;
01905                 if (hc->align_buff) {
01906                         dma_addr = hc->align_buff;
01907                 } else {
01908                         dma_addr = (uint32_t)hc->xfer_buff;
01909                 }
01910                 dwc_write_reg32(&hc_regs->hcdma, dma_addr);
01911         }
01912 
01913         /* Start the split */
01914         if (hc->do_split) {
01915                 hcsplt_data_t hcsplt;
01916                 hcsplt.d32 = dwc_read_reg32(&hc_regs->hcsplt);
01917                 hcsplt.b.spltena = 1;
01918                 dwc_write_reg32(&hc_regs->hcsplt, hcsplt.d32);
01919         }
01920 
01921         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
01922         hcchar.b.multicnt = hc->multi_count;
01923         hc_set_even_odd_frame(core_if, hc, &hcchar);
01924 #ifdef DEBUG
01925         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
01926         if (hcchar.b.chdis) {
01927                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
01928                          __func__, hc->hc_num, hcchar.d32);
01929         }
01930 #endif
01931 
01932         /* Set host channel enable after all other setup is complete. */
01933         hcchar.b.chen = 1;
01934         hcchar.b.chdis = 0;
01935         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
01936 
01937         hc->xfer_started = 1;
01938         hc->requests++;
01939 
01940         if (!core_if->dma_enable && !hc->ep_is_in && hc->xfer_len > 0) {
01941                 /* Load OUT packet into the appropriate Tx FIFO. */
01942                 dwc_otg_hc_write_packet(core_if, hc);
01943         }
01944 #ifdef DEBUG
01945         if (hc->ep_type != DWC_OTG_EP_TYPE_INTR) {
01946                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
01947                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
01948                 /* Start a timer for this transfer. */
01949                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
01950         }
01951 #endif
01952 }
01953 
01968 void dwc_otg_hc_start_transfer_ddma(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
01969 {
01970         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];     
01971         hcchar_data_t hcchar;
01972         hctsiz_data_t hctsiz;
01973         hcdma_data_t  hcdma;
01974         
01975         hctsiz.d32 = 0;
01976 
01977         if (hc->do_ping && !hc->ep_is_in)
01978                 hctsiz.b_ddma.dopng = 1;
01979 
01980         if (hc->ep_type == DWC_OTG_EP_TYPE_ISOC)
01981                 set_pid_isoc(hc);
01982         
01983         /* Packet Count and Xfer Size are not used in Descriptor DMA mode */
01984         hctsiz.b_ddma.pid = hc->data_pid_start;
01985         hctsiz.b_ddma.ntd = hc->ntd - 1; /* 0 - 1 descriptor, 1 - 2 descriptors, etc. */
01986         hctsiz.b_ddma.schinfo = hc->schinfo; /* Non-zero only for high-speed interrupt endpoints */
01987         
01988         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
01989         DWC_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
01990         DWC_DEBUGPL(DBG_HCDV, "  NTD: %d\n", hctsiz.b_ddma.ntd);        
01991 
01992         dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
01993 
01994         hcdma.d32 = 0;
01995         hcdma.b.dma_addr = ((uint32_t)hc->desc_list_addr) >> 11;
01996                 
01997         /* Always start from first descriptor. */
01998         hcdma.b.ctd = 0;
01999         dwc_write_reg32(&hc_regs->hcdma, hcdma.d32);
02000 
02001         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
02002         hcchar.b.multicnt = hc->multi_count;
02003         
02004 #ifdef DEBUG
02005         core_if->start_hcchar_val[hc->hc_num] = hcchar.d32;
02006         if (hcchar.b.chdis) {
02007                 DWC_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
02008                          __func__, hc->hc_num, hcchar.d32);
02009         }
02010 #endif
02011 
02012         /* Set host channel enable after all other setup is complete. */
02013         hcchar.b.chen = 1;
02014         hcchar.b.chdis = 0;
02015         
02016         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
02017 
02018         hc->xfer_started = 1;
02019         hc->requests++;
02020         
02021 #ifdef DEBUG
02022         if ((hc->ep_type != DWC_OTG_EP_TYPE_INTR) && (hc->ep_type != DWC_OTG_EP_TYPE_ISOC)) {
02023                 core_if->hc_xfer_info[hc->hc_num].core_if = core_if;
02024                 core_if->hc_xfer_info[hc->hc_num].hc = hc;
02025                 /* Start a timer for this transfer. */
02026                 DWC_TIMER_SCHEDULE(core_if->hc_xfer_timer[hc->hc_num], 10000);
02027         }
02028 
02029 #endif
02030         
02031 }
02032         
02048 int dwc_otg_hc_continue_transfer(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02049 {
02050         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02051 
02052         if (hc->do_split) {
02053                 /* SPLITs always queue just once per channel */
02054                 return 0;
02055         } else if (hc->data_pid_start == DWC_OTG_HC_PID_SETUP) {
02056                 /* SETUPs are queued only once since they can't be NAKed. */
02057                 return 0;
02058         } else if (hc->ep_is_in) {
02059                 /*
02060                  * Always queue another request for other IN transfers. If
02061                  * back-to-back INs are issued and NAKs are received for both,
02062                  * the driver may still be processing the first NAK when the
02063                  * second NAK is received. When the interrupt handler clears
02064                  * the NAK interrupt for the first NAK, the second NAK will
02065                  * not be seen. So we can't depend on the NAK interrupt
02066                  * handler to requeue a NAKed request. Instead, IN requests
02067                  * are issued each time this function is called. When the
02068                  * transfer completes, the extra requests for the channel will
02069                  * be flushed.
02070                  */
02071                 hcchar_data_t hcchar;
02072                 dwc_otg_hc_regs_t *hc_regs =
02073                     core_if->host_if->hc_regs[hc->hc_num];
02074 
02075                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
02076                 hc_set_even_odd_frame(core_if, hc, &hcchar);
02077                 hcchar.b.chen = 1;
02078                 hcchar.b.chdis = 0;
02079                 DWC_DEBUGPL(DBG_HCDV, "  IN xfer: hcchar = 0x%08x\n",
02080                             hcchar.d32);
02081                 dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
02082                 hc->requests++;
02083                 return 1;
02084         } else {
02085                 /* OUT transfers. */
02086                 if (hc->xfer_count < hc->xfer_len) {
02087                         if (hc->ep_type == DWC_OTG_EP_TYPE_INTR ||
02088                             hc->ep_type == DWC_OTG_EP_TYPE_ISOC) {
02089                                 hcchar_data_t hcchar;
02090                                 dwc_otg_hc_regs_t *hc_regs;
02091                                 hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02092                                 hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
02093                                 hc_set_even_odd_frame(core_if, hc, &hcchar);
02094                         }
02095 
02096                         /* Load OUT packet into the appropriate Tx FIFO. */
02097                         dwc_otg_hc_write_packet(core_if, hc);
02098                         hc->requests++;
02099                         return 1;
02100                 } else {
02101                         return 0;
02102                 }
02103         }
02104 }
02105 
02110 void dwc_otg_hc_do_ping(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02111 {
02112         hcchar_data_t hcchar;
02113         hctsiz_data_t hctsiz;
02114         dwc_otg_hc_regs_t *hc_regs = core_if->host_if->hc_regs[hc->hc_num];
02115 
02116         DWC_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, hc->hc_num);
02117 
02118         hctsiz.d32 = 0;
02119         hctsiz.b.dopng = 1;
02120         hctsiz.b.pktcnt = 1;
02121         dwc_write_reg32(&hc_regs->hctsiz, hctsiz.d32);
02122 
02123         hcchar.d32 = dwc_read_reg32(&hc_regs->hcchar);
02124         hcchar.b.chen = 1;
02125         hcchar.b.chdis = 0;
02126         dwc_write_reg32(&hc_regs->hcchar, hcchar.d32);
02127 }
02128 
02129 /*
02130  * This function writes a packet into the Tx FIFO associated with the Host
02131  * Channel. For a channel associated with a non-periodic EP, the non-periodic
02132  * Tx FIFO is written. For a channel associated with a periodic EP, the
02133  * periodic Tx FIFO is written. This function should only be called in Slave
02134  * mode.
02135  *
02136  * Upon return the xfer_buff and xfer_count fields in _hc are incremented by
02137  * then number of bytes written to the Tx FIFO.
02138  */
02139 void dwc_otg_hc_write_packet(dwc_otg_core_if_t * core_if, dwc_hc_t * hc)
02140 {
02141         uint32_t i;
02142         uint32_t remaining_count;
02143         uint32_t byte_count;
02144         uint32_t dword_count;
02145 
02146         uint32_t *data_buff = (uint32_t *) (hc->xfer_buff);
02147         uint32_t *data_fifo = core_if->data_fifo[hc->hc_num];
02148 
02149         remaining_count = hc->xfer_len - hc->xfer_count;
02150         if (remaining_count > hc->max_packet) {
02151                 byte_count = hc->max_packet;
02152         } else {
02153                 byte_count = remaining_count;
02154         }
02155 
02156         dword_count = (byte_count + 3) / 4;
02157 
02158         if ((((unsigned long)data_buff) & 0x3) == 0) {
02159                 /* xfer_buff is DWORD aligned. */
02160                 for (i = 0; i < dword_count; i++, data_buff++) {
02161                         dwc_write_reg32(data_fifo, *data_buff);
02162                 }
02163         } else {
02164                 /* xfer_buff is not DWORD aligned. */
02165                 for (i = 0; i < dword_count; i++, data_buff++) {
02166                         uint32_t data;
02167                         data =
02168                             (data_buff[0] | data_buff[1] << 8 | data_buff[2] <<
02169                              16 | data_buff[3] << 24);
02170                         dwc_write_reg32(data_fifo, data);
02171                 }
02172         }
02173 
02174         hc->xfer_count += byte_count;
02175         hc->xfer_buff += byte_count;
02176 }
02177 
02182 uint32_t dwc_otg_get_frame_number(dwc_otg_core_if_t * core_if)
02183 {
02184         dsts_data_t dsts;
02185         dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
02186 
02187         /* read current frame/microframe number from DSTS register */
02188         return dsts.b.soffn;
02189 }
02190 
02199 void dwc_otg_read_setup_packet(dwc_otg_core_if_t * core_if, uint32_t * dest)
02200 {
02201         /* Get the 8 bytes of a setup transaction data */
02202 
02203         /* Pop 2 DWORDS off the receive data FIFO into memory */
02204         dest[0] = dwc_read_reg32(core_if->data_fifo[0]);
02205         dest[1] = dwc_read_reg32(core_if->data_fifo[0]);
02206 }
02207 
02216 void dwc_otg_ep0_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02217 {
02218         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
02219         dsts_data_t dsts;
02220         depctl_data_t diepctl;
02221         depctl_data_t doepctl;
02222         dctl_data_t dctl = {.d32 = 0 };
02223 
02224         /* Read the Device Status and Endpoint 0 Control registers */
02225         dsts.d32 = dwc_read_reg32(&dev_if->dev_global_regs->dsts);
02226         diepctl.d32 = dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl);
02227         doepctl.d32 = dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl);
02228 
02229         /* Set the MPS of the IN EP based on the enumeration speed */
02230         switch (dsts.b.enumspd) {
02231         case DWC_DSTS_ENUMSPD_HS_PHY_30MHZ_OR_60MHZ:
02232         case DWC_DSTS_ENUMSPD_FS_PHY_30MHZ_OR_60MHZ:
02233         case DWC_DSTS_ENUMSPD_FS_PHY_48MHZ:
02234                 diepctl.b.mps = DWC_DEP0CTL_MPS_64;
02235                 break;
02236         case DWC_DSTS_ENUMSPD_LS_PHY_6MHZ:
02237                 diepctl.b.mps = DWC_DEP0CTL_MPS_8;
02238                 break;
02239         }
02240 
02241         dwc_write_reg32(&dev_if->in_ep_regs[0]->diepctl, diepctl.d32);
02242 
02243         /* Enable OUT EP for receive */
02244         doepctl.b.epena = 1;
02245         dwc_write_reg32(&dev_if->out_ep_regs[0]->doepctl, doepctl.d32);
02246 
02247 #ifdef VERBOSE
02248         DWC_DEBUGPL(DBG_PCDV, "doepctl0=%0x\n",
02249                     dwc_read_reg32(&dev_if->out_ep_regs[0]->doepctl));
02250         DWC_DEBUGPL(DBG_PCDV, "diepctl0=%0x\n",
02251                     dwc_read_reg32(&dev_if->in_ep_regs[0]->diepctl));
02252 #endif
02253         dctl.b.cgnpinnak = 1;
02254 
02255         dwc_modify_reg32(&dev_if->dev_global_regs->dctl, dctl.d32, dctl.d32);
02256         DWC_DEBUGPL(DBG_PCDV, "dctl=%0x\n",
02257                     dwc_read_reg32(&dev_if->dev_global_regs->dctl));
02258 }
02259 
02268 void dwc_otg_ep_activate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02269 {
02270         dwc_otg_dev_if_t *dev_if = core_if->dev_if;
02271         depctl_data_t depctl;
02272         volatile uint32_t *addr;
02273         daint_data_t daintmsk = {.d32 = 0 };
02274 
02275         DWC_DEBUGPL(DBG_PCDV, "%s() EP%d-%s\n", __func__, ep->num,
02276                     (ep->is_in ? "IN" : "OUT"));
02277 
02278         /* Read DEPCTLn register */
02279         if (ep->is_in == 1) {
02280                 addr = &dev_if->in_ep_regs[ep->num]->diepctl;
02281                 daintmsk.ep.in = 1 << ep->num;
02282         } else {
02283                 addr = &dev_if->out_ep_regs[ep->num]->doepctl;
02284                 daintmsk.ep.out = 1 << ep->num;
02285         }
02286 
02287         /* If the EP is already active don't change the EP Control
02288          * register. */
02289         depctl.d32 = dwc_read_reg32(addr);
02290         if (!depctl.b.usbactep) {
02291                 depctl.b.mps = ep->maxpacket;
02292                 depctl.b.eptype = ep->type;
02293                 depctl.b.txfnum = ep->tx_fifo_num;
02294 
02295                 if (ep->type == DWC_OTG_EP_TYPE_ISOC) {
02296                         depctl.b.setd0pid = 1;  // ??? 
02297                 } else {
02298                         depctl.b.setd0pid = 1;
02299                 }
02300                 depctl.b.usbactep = 1;
02301 
02302                 dwc_write_reg32(addr, depctl.d32);
02303                 DWC_DEBUGPL(DBG_PCDV, "DEPCTL=%08x\n", dwc_read_reg32(addr));
02304         }
02305 
02306         /* Enable the Interrupt for this EP */
02307         if (core_if->multiproc_int_enable) {
02308                 if (ep->is_in == 1) {
02309                         diepmsk_data_t diepmsk = {.d32 = 0 };
02310                         diepmsk.b.xfercompl = 1;
02311                         diepmsk.b.timeout = 1;
02312                         diepmsk.b.epdisabled = 1;
02313                         diepmsk.b.ahberr = 1;
02314                         diepmsk.b.intknepmis = 1;
02315                         diepmsk.b.txfifoundrn = 1;      //?????
02316 
02317                         if (core_if->dma_desc_enable) {
02318                                 diepmsk.b.bna = 1;
02319                         }
02320 /*                      
02321                         if(core_if->dma_enable) {
02322                                 doepmsk.b.nak = 1;
02323                         }
02324 */
02325                         dwc_write_reg32(&dev_if->dev_global_regs->
02326                                         diepeachintmsk[ep->num], diepmsk.d32);
02327 
02328                 } else {
02329                         doepmsk_data_t doepmsk = {.d32 = 0 };
02330                         doepmsk.b.xfercompl = 1;
02331                         doepmsk.b.ahberr = 1;
02332                         doepmsk.b.epdisabled = 1;
02333 
02334                         if (core_if->dma_desc_enable) {
02335                                 doepmsk.b.bna = 1;
02336                         }
02337 /*                      
02338                         doepmsk.b.babble = 1;
02339                         doepmsk.b.nyet = 1;
02340                         doepmsk.b.nak = 1;
02341 */
02342                         dwc_write_reg32(&dev_if->dev_global_regs->
02343                                         doepeachintmsk[ep->num], doepmsk.d32);
02344                 }
02345                 dwc_modify_reg32(&dev_if->dev_global_regs->deachintmsk,
02346                                  0, daintmsk.d32);
02347         } else {
02348                 dwc_modify_reg32(&dev_if->dev_global_regs->daintmsk,
02349                                  0, daintmsk.d32);
02350         }
02351 
02352         DWC_DEBUGPL(DBG_PCDV, "DAINTMSK=%0x\n",
02353                     dwc_read_reg32(&dev_if->dev_global_regs->daintmsk));
02354 
02355         ep->stall_clear_flag = 0;
02356         return;
02357 }
02358 
02367 void dwc_otg_ep_deactivate(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02368 {
02369         depctl_data_t depctl = {.d32 = 0 };
02370         volatile uint32_t *addr;
02371         daint_data_t daintmsk = {.d32 = 0 };
02372 
02373         /* Read DEPCTLn register */
02374         if (ep->is_in == 1) {
02375                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
02376                 daintmsk.ep.in = 1 << ep->num;
02377         } else {
02378                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
02379                 daintmsk.ep.out = 1 << ep->num;
02380         }
02381 
02382         depctl.d32 = dwc_read_reg32(addr);
02383 
02384         depctl.b.usbactep = 0;
02385 
02386         if (core_if->dma_desc_enable)
02387                 depctl.b.epdis = 1;
02388 
02389         dwc_write_reg32(addr, depctl.d32);
02390 
02391         /* Disable the Interrupt for this EP */
02392         if (core_if->multiproc_int_enable) {
02393                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->deachintmsk,
02394                                  daintmsk.d32, 0);
02395 
02396                 if (ep->is_in == 1) {
02397                         dwc_write_reg32(&core_if->dev_if->dev_global_regs->
02398                                         diepeachintmsk[ep->num], 0);
02399                 } else {
02400                         dwc_write_reg32(&core_if->dev_if->dev_global_regs->
02401                                         doepeachintmsk[ep->num], 0);
02402                 }
02403         } else {
02404                 dwc_modify_reg32(&core_if->dev_if->dev_global_regs->daintmsk,
02405                                  daintmsk.d32, 0);
02406         }
02407 }
02408 
02415 static void init_dma_desc_chain(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02416 {
02417         dwc_otg_dev_dma_desc_t *dma_desc;
02418         uint32_t offset;
02419         uint32_t xfer_est;
02420         int i;
02421 
02422         ep->desc_cnt = (ep->total_len / ep->maxxfer) +
02423             ((ep->total_len % ep->maxxfer) ? 1 : 0);
02424         if (!ep->desc_cnt)
02425                 ep->desc_cnt = 1;
02426 
02427         dma_desc = ep->desc_addr;
02428         xfer_est = ep->total_len;
02429         offset = 0;
02430         for (i = 0; i < ep->desc_cnt; ++i) {
02432                 if (xfer_est > ep->maxxfer) {
02433                         dma_desc->status.b.bs = BS_HOST_BUSY;
02434                         dma_desc->status.b.l = 0;
02435                         dma_desc->status.b.ioc = 0;
02436                         dma_desc->status.b.sp = 0;
02437                         dma_desc->status.b.bytes = ep->maxxfer;
02438                         dma_desc->buf = ep->dma_addr + offset;
02439                         dma_desc->status.b.bs = BS_HOST_READY;
02440 
02441                         xfer_est -= ep->maxxfer;
02442                         offset += ep->maxxfer;
02443                 } else {
02444                         dma_desc->status.b.bs = BS_HOST_BUSY;
02445                         dma_desc->status.b.l = 1;
02446                         dma_desc->status.b.ioc = 1;
02447                         if (ep->is_in) {
02448                                 dma_desc->status.b.sp =
02449                                     (xfer_est %
02450                                      ep->maxpacket) ? 1 : ((ep->
02451                                                             sent_zlp) ? 1 : 0);
02452                                 dma_desc->status.b.bytes = xfer_est;
02453                         } else {
02454                                 dma_desc->status.b.bytes =
02455                                     xfer_est + ((4 - (xfer_est & 0x3)) & 0x3);
02456                         }
02457 
02458                         dma_desc->buf = ep->dma_addr + offset;
02459                         dma_desc->status.b.bs = BS_HOST_READY;
02460                 }
02461                 dma_desc++;
02462         }
02463 }
02464 
02475 void dwc_otg_ep_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02476 {
02477         depctl_data_t depctl;
02478         deptsiz_data_t deptsiz;
02479         gintmsk_data_t intr_mask = {.d32 = 0 };
02480 
02481         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
02482         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
02483                     "xfer_buff=%p start_xfer_buff=%p, total_len = %d\n",
02484                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
02485                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff,
02486                     ep->total_len);
02487         /* IN endpoint */
02488         if (ep->is_in == 1) {
02489                 dwc_otg_dev_in_ep_regs_t *in_regs =
02490                     core_if->dev_if->in_ep_regs[ep->num];
02491 
02492                 gnptxsts_data_t gtxstatus;
02493 
02494                 gtxstatus.d32 =
02495                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
02496 
02497                 if (core_if->en_multiple_tx_fifo == 0
02498                     && gtxstatus.b.nptxqspcavail == 0) {
02499 #ifdef DEBUG
02500                         DWC_PRINTF("TX Queue Full (0x%0x)\n", gtxstatus.d32);
02501 #endif
02502                         return;
02503                 }
02504 
02505                 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
02506                 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
02507 
02508                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
02509                     ep->maxxfer : (ep->total_len - ep->xfer_len);
02510 
02511                 /* Zero Length Packet? */
02512                 if ((ep->xfer_len - ep->xfer_count) == 0) {
02513                         deptsiz.b.xfersize = 0;
02514                         deptsiz.b.pktcnt = 1;
02515                 } else {
02516                         /* Program the transfer size and packet count
02517                          *      as follows: xfersize = N * maxpacket +
02518                          *      short_packet pktcnt = N + (short_packet
02519                          *      exist ? 1 : 0)  
02520                          */
02521                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
02522                         deptsiz.b.pktcnt =
02523                             (ep->xfer_len - ep->xfer_count - 1 +
02524                              ep->maxpacket) / ep->maxpacket;
02525                 }
02526 
02527                 /* Write the DMA register */
02528                 if (core_if->dma_enable) {
02529                         if (core_if->dma_desc_enable == 0) {
02530                                 dwc_write_reg32(&in_regs->dieptsiz,
02531                                                 deptsiz.d32);
02532                                 dwc_write_reg32(&(in_regs->diepdma),
02533                                                 (uint32_t) ep->dma_addr);
02534                         } else {
02535 #ifdef DWC_UTE_CFI
02536                                 /* The descriptor chain should be already initialized by now */
02537                                 if (ep->buff_mode != BM_STANDARD) {
02538                                         dwc_write_reg32(&in_regs->diepdma,
02539                                                         ep->descs_dma_addr);
02540                                 } else {
02541 #endif
02542                                 init_dma_desc_chain(core_if, ep);
02544                                 dwc_write_reg32(&in_regs->diepdma,
02545                                                 ep->dma_desc_addr);
02546 #ifdef DWC_UTE_CFI
02547                         }
02548 #endif
02549                         }
02550                 } else {
02551                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
02552                         if (ep->type != DWC_OTG_EP_TYPE_ISOC) {
02558                                 if (core_if->en_multiple_tx_fifo == 0) {
02559                                         intr_mask.b.nptxfempty = 1;
02560                                         dwc_modify_reg32(&core_if->
02561                                                          core_global_regs->
02562                                                          gintmsk, intr_mask.d32,
02563                                                          intr_mask.d32);
02564                                 } else {
02565                                         /* Enable the Tx FIFO Empty Interrupt for this EP */
02566                                         if (ep->xfer_len > 0) {
02567                                                 uint32_t fifoemptymsk = 0;
02568                                                 fifoemptymsk = 1 << ep->num;
02569                                                 dwc_modify_reg32(&core_if->
02570                                                                  dev_if->
02571                                                                  dev_global_regs->
02572                                                                  dtknqr4_fifoemptymsk,
02573                                                                  0,
02574                                                                  fifoemptymsk);
02575 
02576                                         }
02577                                 }
02578                         }
02579                 }
02580 
02581                 /* EP enable, IN data in FIFO */
02582                 depctl.b.cnak = 1;
02583                 depctl.b.epena = 1;
02584                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
02585 
02586                 depctl.d32 =
02587                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
02588                 depctl.b.nextep = ep->num;
02589                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
02590                                 depctl.d32);
02591 
02592         } else {
02593                 /* OUT endpoint */
02594                 dwc_otg_dev_out_ep_regs_t *out_regs =
02595                     core_if->dev_if->out_ep_regs[ep->num];
02596 
02597                 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
02598                 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
02599 
02600                 ep->xfer_len += (ep->maxxfer < (ep->total_len - ep->xfer_len)) ?
02601                     ep->maxxfer : (ep->total_len - ep->xfer_len);
02602 
02603                 /* Program the transfer size and packet count as follows:
02604                  * 
02605                  *      pktcnt = N                                                                                 
02606                  *      xfersize = N * maxpacket
02607                  */
02608                 if ((ep->xfer_len - ep->xfer_count) == 0) {
02609                         /* Zero Length Packet */
02610                         deptsiz.b.xfersize = ep->maxpacket;
02611                         deptsiz.b.pktcnt = 1;
02612                 } else {
02613                         deptsiz.b.pktcnt =
02614                             (ep->xfer_len - ep->xfer_count +
02615                              (ep->maxpacket - 1)) / ep->maxpacket;
02616                         ep->xfer_len =
02617                             deptsiz.b.pktcnt * ep->maxpacket + ep->xfer_count;
02618                         deptsiz.b.xfersize = ep->xfer_len - ep->xfer_count;
02619                 }
02620 
02621                 DWC_DEBUGPL(DBG_PCDV, "ep%d xfersize=%d pktcnt=%d\n",
02622                             ep->num, deptsiz.b.xfersize, deptsiz.b.pktcnt);
02623 
02624                 if (core_if->dma_enable) {
02625                         if (!core_if->dma_desc_enable) {
02626                                 dwc_write_reg32(&out_regs->doeptsiz,
02627                                                 deptsiz.d32);
02628 
02629                                 dwc_write_reg32(&(out_regs->doepdma),
02630                                                 (uint32_t) ep->dma_addr);
02631                         } else {
02632 #ifdef DWC_UTE_CFI
02633                                 /* The descriptor chain should be already initialized by now */
02634                                 if (ep->buff_mode != BM_STANDARD) {
02635                                         dwc_write_reg32(&out_regs->doepdma,
02636                                                         ep->descs_dma_addr);
02637                                 } else {
02638 #endif
02639 
02640                                 init_dma_desc_chain(core_if, ep);
02641 
02643                                 dwc_write_reg32(&out_regs->doepdma,
02644                                                 ep->dma_desc_addr);
02645 #ifdef DWC_UTE_CFI
02646                                 }
02647 #endif
02648                         }
02649                 } else {
02650                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
02651                 }
02652 
02653                 /* EP enable */
02654                 depctl.b.cnak = 1;
02655                 depctl.b.epena = 1;
02656 
02657                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
02658 
02659                 DWC_DEBUGPL(DBG_PCD, "DOEPCTL=%08x DOEPTSIZ=%08x\n",
02660                             dwc_read_reg32(&out_regs->doepctl),
02661                             dwc_read_reg32(&out_regs->doeptsiz));
02662                 DWC_DEBUGPL(DBG_PCD, "DAINTMSK=%08x GINTMSK=%08x\n",
02663                             dwc_read_reg32(&core_if->dev_if->dev_global_regs->
02664                                            daintmsk),
02665                             dwc_read_reg32(&core_if->core_global_regs->
02666                                            gintmsk));
02667         }
02668 }
02669 
02678 void dwc_otg_ep_start_zl_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02679 {
02680 
02681         depctl_data_t depctl;
02682         deptsiz_data_t deptsiz;
02683         gintmsk_data_t intr_mask = {.d32 = 0 };
02684 
02685         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s()\n", __func__);
02686         DWC_PRINTF("zero length transfer is called\n");
02687 
02688         /* IN endpoint */
02689         if (ep->is_in == 1) {
02690                 dwc_otg_dev_in_ep_regs_t *in_regs =
02691                     core_if->dev_if->in_ep_regs[ep->num];
02692 
02693                 depctl.d32 = dwc_read_reg32(&(in_regs->diepctl));
02694                 deptsiz.d32 = dwc_read_reg32(&(in_regs->dieptsiz));
02695 
02696                 deptsiz.b.xfersize = 0;
02697                 deptsiz.b.pktcnt = 1;
02698 
02699                 /* Write the DMA register */
02700                 if (core_if->dma_enable) {
02701                         if (core_if->dma_desc_enable == 0) {
02702                                 dwc_write_reg32(&in_regs->dieptsiz,
02703                                                 deptsiz.d32);
02704                                 dwc_write_reg32(&(in_regs->diepdma),
02705                                                 (uint32_t) ep->dma_addr);
02706                         }
02707                 } else {
02708                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
02714                         if (core_if->en_multiple_tx_fifo == 0) {
02715                                 intr_mask.b.nptxfempty = 1;
02716                                 dwc_modify_reg32(&core_if->core_global_regs->
02717                                                  gintmsk, intr_mask.d32,
02718                                                  intr_mask.d32);
02719                         } else {
02720                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
02721                                 if (ep->xfer_len > 0) {
02722                                         uint32_t fifoemptymsk = 0;
02723                                         fifoemptymsk = 1 << ep->num;
02724                                         dwc_modify_reg32(&core_if->dev_if->
02725                                                          dev_global_regs->
02726                                                          dtknqr4_fifoemptymsk,
02727                                                          0, fifoemptymsk);
02728                                 }
02729                         }
02730                 }
02731 
02732                 /* EP enable, IN data in FIFO */
02733                 depctl.b.cnak = 1;
02734                 depctl.b.epena = 1;
02735                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
02736 
02737                 depctl.d32 =
02738                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl);
02739                 depctl.b.nextep = ep->num;
02740                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[0]->diepctl,
02741                                 depctl.d32);
02742 
02743         } else {
02744                 /* OUT endpoint */
02745                 dwc_otg_dev_out_ep_regs_t *out_regs =
02746                     core_if->dev_if->out_ep_regs[ep->num];
02747 
02748                 depctl.d32 = dwc_read_reg32(&(out_regs->doepctl));
02749                 deptsiz.d32 = dwc_read_reg32(&(out_regs->doeptsiz));
02750 
02751                 /* Zero Length Packet */
02752                 deptsiz.b.xfersize = ep->maxpacket;
02753                 deptsiz.b.pktcnt = 1;
02754 
02755                 if (core_if->dma_enable) {
02756                         if (!core_if->dma_desc_enable) {
02757                                 dwc_write_reg32(&out_regs->doeptsiz,
02758                                                 deptsiz.d32);
02759 
02760                                 dwc_write_reg32(&(out_regs->doepdma),
02761                                                 (uint32_t) ep->dma_addr);
02762                         }
02763                 } else {
02764                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
02765                 }
02766 
02767                 /* EP enable */
02768                 depctl.b.cnak = 1;
02769                 depctl.b.epena = 1;
02770 
02771                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
02772 
02773         }
02774 }
02775 
02785 void dwc_otg_ep0_start_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02786 {
02787         depctl_data_t depctl;
02788         deptsiz0_data_t deptsiz;
02789         gintmsk_data_t intr_mask = {.d32 = 0 };
02790         dwc_otg_dev_dma_desc_t *dma_desc;
02791 
02792         DWC_DEBUGPL(DBG_PCD, "ep%d-%s xfer_len=%d xfer_cnt=%d "
02793                     "xfer_buff=%p start_xfer_buff=%p \n",
02794                     ep->num, (ep->is_in ? "IN" : "OUT"), ep->xfer_len,
02795                     ep->xfer_count, ep->xfer_buff, ep->start_xfer_buff);
02796 
02797         ep->total_len = ep->xfer_len;
02798 
02799         /* IN endpoint */
02800         if (ep->is_in == 1) {
02801                 dwc_otg_dev_in_ep_regs_t *in_regs =
02802                     core_if->dev_if->in_ep_regs[0];
02803 
02804                 gnptxsts_data_t gtxstatus;
02805 
02806                 gtxstatus.d32 =
02807                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
02808 
02809                 if (core_if->en_multiple_tx_fifo == 0
02810                     && gtxstatus.b.nptxqspcavail == 0) {
02811 #ifdef DEBUG
02812                         deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
02813                         DWC_DEBUGPL(DBG_PCD, "DIEPCTL0=%0x\n",
02814                                     dwc_read_reg32(&in_regs->diepctl));
02815                         DWC_DEBUGPL(DBG_PCD, "DIEPTSIZ0=%0x (sz=%d, pcnt=%d)\n",
02816                                     deptsiz.d32,
02817                                     deptsiz.b.xfersize, deptsiz.b.pktcnt);
02818                         DWC_PRINTF("TX Queue or FIFO Full (0x%0x)\n",
02819                                    gtxstatus.d32);
02820 #endif
02821                         return;
02822                 }
02823 
02824                 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
02825                 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
02826 
02827                 /* Zero Length Packet? */
02828                 if (ep->xfer_len == 0) {
02829                         deptsiz.b.xfersize = 0;
02830                         deptsiz.b.pktcnt = 1;
02831                 } else {
02832                         /* Program the transfer size and packet count
02833                          *      as follows: xfersize = N * maxpacket +
02834                          *      short_packet pktcnt = N + (short_packet
02835                          *      exist ? 1 : 0)  
02836                          */
02837                         if (ep->xfer_len > ep->maxpacket) {
02838                                 ep->xfer_len = ep->maxpacket;
02839                                 deptsiz.b.xfersize = ep->maxpacket;
02840                         } else {
02841                                 deptsiz.b.xfersize = ep->xfer_len;
02842                         }
02843                         deptsiz.b.pktcnt = 1;
02844 
02845                 }
02846                 DWC_DEBUGPL(DBG_PCDV,
02847                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
02848                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
02849                             deptsiz.d32);
02850 
02851                 /* Write the DMA register */
02852                 if (core_if->dma_enable) {
02853                         if (core_if->dma_desc_enable == 0) {
02854                                 dwc_write_reg32(&in_regs->dieptsiz,
02855                                                 deptsiz.d32);
02856 
02857                                 dwc_write_reg32(&(in_regs->diepdma),
02858                                                 (uint32_t) ep->dma_addr);
02859                         } else {
02860                                 dma_desc = core_if->dev_if->in_desc_addr;
02861 
02863                                 dma_desc->status.b.bs = BS_HOST_BUSY;
02864                                 dma_desc->status.b.l = 1;
02865                                 dma_desc->status.b.ioc = 1;
02866                                 dma_desc->status.b.sp =
02867                                     (ep->xfer_len == ep->maxpacket) ? 0 : 1;
02868                                 dma_desc->status.b.bytes = ep->xfer_len;
02869                                 dma_desc->buf = ep->dma_addr;
02870                                 dma_desc->status.b.bs = BS_HOST_READY;
02871 
02873                                 dwc_write_reg32(&in_regs->diepdma,
02874                                                 core_if->dev_if->
02875                                                 dma_in_desc_addr);
02876                         }
02877                 } else {
02878                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
02879                 }
02880 
02881                 /* EP enable, IN data in FIFO */
02882                 depctl.b.cnak = 1;
02883                 depctl.b.epena = 1;
02884                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
02885 
02890                 if (!core_if->dma_enable) {
02891                         if (core_if->en_multiple_tx_fifo == 0) {
02892                                 intr_mask.b.nptxfempty = 1;
02893                                 dwc_modify_reg32(&core_if->core_global_regs->
02894                                                  gintmsk, intr_mask.d32,
02895                                                  intr_mask.d32);
02896                         } else {
02897                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
02898                                 if (ep->xfer_len > 0) {
02899                                         uint32_t fifoemptymsk = 0;
02900                                         fifoemptymsk |= 1 << ep->num;
02901                                         dwc_modify_reg32(&core_if->dev_if->
02902                                                          dev_global_regs->
02903                                                          dtknqr4_fifoemptymsk,
02904                                                          0, fifoemptymsk);
02905                                 }
02906                         }
02907                 }
02908         } else {
02909                 /* OUT endpoint */
02910                 dwc_otg_dev_out_ep_regs_t *out_regs =
02911                     core_if->dev_if->out_ep_regs[0];
02912 
02913                 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
02914                 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
02915 
02916                 /* Program the transfer size and packet count as follows:
02917                  *      xfersize = N * (maxpacket + 4 - (maxpacket % 4))
02918                  *      pktcnt = N                                                                                      */
02919                 /* Zero Length Packet */
02920                 deptsiz.b.xfersize = ep->maxpacket;
02921                 deptsiz.b.pktcnt = 1;
02922 
02923                 DWC_DEBUGPL(DBG_PCDV, "len=%d  xfersize=%d pktcnt=%d\n",
02924                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt);
02925 
02926                 if (core_if->dma_enable) {
02927                         if (!core_if->dma_desc_enable) {
02928                                 dwc_write_reg32(&out_regs->doeptsiz,
02929                                                 deptsiz.d32);
02930 
02931                                 dwc_write_reg32(&(out_regs->doepdma),
02932                                                 (uint32_t) ep->dma_addr);
02933                         } else {
02934                                 dma_desc = core_if->dev_if->out_desc_addr;
02935 
02937                                 dma_desc->status.b.bs = BS_HOST_BUSY;
02938                                 dma_desc->status.b.l = 1;
02939                                 dma_desc->status.b.ioc = 1;
02940                                 dma_desc->status.b.bytes = ep->maxpacket;
02941                                 dma_desc->buf = ep->dma_addr;
02942                                 dma_desc->status.b.bs = BS_HOST_READY;
02943 
02945                                 dwc_write_reg32(&out_regs->doepdma,
02946                                                 core_if->dev_if->
02947                                                 dma_out_desc_addr);
02948                         }
02949                 } else {
02950                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
02951                 }
02952 
02953                 /* EP enable */
02954                 depctl.b.cnak = 1;
02955                 depctl.b.epena = 1;
02956                 dwc_write_reg32(&(out_regs->doepctl), depctl.d32);
02957         }
02958 }
02959 
02969 void dwc_otg_ep0_continue_transfer(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
02970 {
02971         depctl_data_t depctl;
02972         deptsiz0_data_t deptsiz;
02973         gintmsk_data_t intr_mask = {.d32 = 0 };
02974         dwc_otg_dev_dma_desc_t *dma_desc;
02975 
02976         if (ep->is_in == 1) {
02977                 dwc_otg_dev_in_ep_regs_t *in_regs =
02978                     core_if->dev_if->in_ep_regs[0];
02979                 gnptxsts_data_t tx_status = {.d32 = 0 };
02980 
02981                 tx_status.d32 =
02982                     dwc_read_reg32(&core_if->core_global_regs->gnptxsts);
02986                 depctl.d32 = dwc_read_reg32(&in_regs->diepctl);
02987                 deptsiz.d32 = dwc_read_reg32(&in_regs->dieptsiz);
02988 
02989                 /* Program the transfer size and packet count
02990                  *      as follows: xfersize = N * maxpacket +
02991                  *      short_packet pktcnt = N + (short_packet
02992                  *      exist ? 1 : 0)  
02993                  */
02994 
02995                 if (core_if->dma_desc_enable == 0) {
02996                         deptsiz.b.xfersize =
02997                             (ep->total_len - ep->xfer_count) >
02998                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
02999                                                              ep->xfer_count);
03000                         deptsiz.b.pktcnt = 1;
03001                         if (core_if->dma_enable == 0) {
03002                                 ep->xfer_len += deptsiz.b.xfersize;
03003                         } else {
03004                                 ep->xfer_len = deptsiz.b.xfersize;
03005                         }
03006                         dwc_write_reg32(&in_regs->dieptsiz, deptsiz.d32);
03007                 } else {
03008                         ep->xfer_len =
03009                             (ep->total_len - ep->xfer_count) >
03010                             ep->maxpacket ? ep->maxpacket : (ep->total_len -
03011                                                              ep->xfer_count);
03012 
03013                         dma_desc = core_if->dev_if->in_desc_addr;
03014 
03016                         dma_desc->status.b.bs = BS_HOST_BUSY;
03017                         dma_desc->status.b.l = 1;
03018                         dma_desc->status.b.ioc = 1;
03019                         dma_desc->status.b.sp =
03020                             (ep->xfer_len == ep->maxpacket) ? 0 : 1;
03021                         dma_desc->status.b.bytes = ep->xfer_len;
03022                         dma_desc->buf = ep->dma_addr;
03023                         dma_desc->status.b.bs = BS_HOST_READY;
03024 
03026                         dwc_write_reg32(&in_regs->diepdma,
03027                                         core_if->dev_if->dma_in_desc_addr);
03028                 }
03029 
03030                 DWC_DEBUGPL(DBG_PCDV,
03031                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
03032                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
03033                             deptsiz.d32);
03034 
03035                 /* Write the DMA register */
03036                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
03037                         if (core_if->dma_desc_enable == 0)
03038                                 dwc_write_reg32(&(in_regs->diepdma),
03039                                                 (uint32_t) ep->dma_addr);
03040                 }
03041 
03042                 /* EP enable, IN data in FIFO */
03043                 depctl.b.cnak = 1;
03044                 depctl.b.epena = 1;
03045                 dwc_write_reg32(&in_regs->diepctl, depctl.d32);
03046 
03051                 if (!core_if->dma_enable) {
03052                         if (core_if->en_multiple_tx_fifo == 0) {
03053                                 /* First clear it from GINTSTS */
03054                                 intr_mask.b.nptxfempty = 1;
03055                                 dwc_modify_reg32(&core_if->core_global_regs->
03056                                                  gintmsk, intr_mask.d32,
03057                                                  intr_mask.d32);
03058 
03059                         } else {
03060                                 /* Enable the Tx FIFO Empty Interrupt for this EP */
03061                                 if (ep->xfer_len > 0) {
03062                                         uint32_t fifoemptymsk = 0;
03063                                         fifoemptymsk |= 1 << ep->num;
03064                                         dwc_modify_reg32(&core_if->dev_if->
03065                                                          dev_global_regs->
03066                                                          dtknqr4_fifoemptymsk,
03067                                                          0, fifoemptymsk);
03068                                 }
03069                         }
03070                 }
03071         } else {
03072                 dwc_otg_dev_out_ep_regs_t *out_regs =
03073                     core_if->dev_if->out_ep_regs[0];
03074 
03075                 depctl.d32 = dwc_read_reg32(&out_regs->doepctl);
03076                 deptsiz.d32 = dwc_read_reg32(&out_regs->doeptsiz);
03077 
03078                 /* Program the transfer size and packet count
03079                  *      as follows: xfersize = N * maxpacket +
03080                  *      short_packet pktcnt = N + (short_packet
03081                  *      exist ? 1 : 0)  
03082                  */
03083                 deptsiz.b.xfersize = ep->maxpacket;
03084                 deptsiz.b.pktcnt = 1;
03085 
03086                 if (core_if->dma_desc_enable == 0) {
03087                         dwc_write_reg32(&out_regs->doeptsiz, deptsiz.d32);
03088                 } else {
03089                         dma_desc = core_if->dev_if->out_desc_addr;
03090 
03092                         dma_desc->status.b.bs = BS_HOST_BUSY;
03093                         dma_desc->status.b.l = 1;
03094                         dma_desc->status.b.ioc = 1;
03095                         dma_desc->status.b.bytes = ep->maxpacket;
03096                         dma_desc->buf = ep->dma_addr;
03097                         dma_desc->status.b.bs = BS_HOST_READY;
03098 
03100                         dwc_write_reg32(&out_regs->doepdma,
03101                                         core_if->dev_if->dma_out_desc_addr);
03102                 }
03103 
03104                 DWC_DEBUGPL(DBG_PCDV,
03105                             "IN len=%d  xfersize=%d pktcnt=%d [%08x]\n",
03106                             ep->xfer_len, deptsiz.b.xfersize, deptsiz.b.pktcnt,
03107                             deptsiz.d32);
03108 
03109                 /* Write the DMA register */
03110                 if (core_if->hwcfg2.b.architecture == DWC_INT_DMA_ARCH) {
03111                         if (core_if->dma_desc_enable == 0)
03112                                 dwc_write_reg32(&(out_regs->doepdma),
03113                                                 (uint32_t) ep->dma_addr);
03114                 }
03115 
03116                 /* EP enable, IN data in FIFO */
03117                 depctl.b.cnak = 1;
03118                 depctl.b.epena = 1;
03119                 dwc_write_reg32(&out_regs->doepctl, depctl.d32);
03120 
03121         }
03122 }
03123 
03124 #ifdef DEBUG
03125 void dump_msg(const u8 * buf, unsigned int length)
03126 {
03127         unsigned int start, num, i;
03128         char line[52], *p;
03129 
03130         if (length >= 512)
03131                 return;
03132         start = 0;
03133         while (length > 0) {
03134                 num = length < 16u ? length : 16u;
03135                 p = line;
03136                 for (i = 0; i < num; ++i) {
03137                         if (i == 8)
03138                                 *p++ = ' ';
03139                         DWC_SPRINTF(p, " %02x", buf[i]);
03140                         p += 3;
03141                 }
03142                 *p = 0;
03143                 DWC_PRINTF("%6x: %s\n", start, line);
03144                 buf += num;
03145                 start += num;
03146                 length -= num;
03147         }
03148 }
03149 #else
03150 static inline void dump_msg(const u8 * buf, unsigned int length)
03151 {
03152 }
03153 #endif
03154 
03165 void dwc_otg_ep_write_packet(dwc_otg_core_if_t * core_if, dwc_ep_t * ep,
03166                              int dma)
03167 {
03183         uint32_t i;
03184         uint32_t byte_count;
03185         uint32_t dword_count;
03186         uint32_t *fifo;
03187         uint32_t *data_buff = (uint32_t *) ep->xfer_buff;
03188 
03189         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p)\n", __func__, core_if,
03190                     ep);
03191         if (ep->xfer_count >= ep->xfer_len) {
03192                 DWC_WARN("%s() No data for EP%d!!!\n", __func__, ep->num);
03193                 return;
03194         }
03195 
03196         /* Find the byte length of the packet either short packet or MPS */
03197         if ((ep->xfer_len - ep->xfer_count) < ep->maxpacket) {
03198                 byte_count = ep->xfer_len - ep->xfer_count;
03199         } else {
03200                 byte_count = ep->maxpacket;
03201         }
03202 
03203         /* Find the DWORD length, padded by extra bytes as neccessary if MPS
03204          * is not a multiple of DWORD */
03205         dword_count = (byte_count + 3) / 4;
03206 
03207 #ifdef VERBOSE
03208         dump_msg(ep->xfer_buff, byte_count);
03209 #endif
03210 
03214         fifo = core_if->data_fifo[ep->num];
03215 
03216         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "fifo=%p buff=%p *p=%08x bc=%d\n",
03217                     fifo, data_buff, *data_buff, byte_count);
03218 
03219         if (!dma) {
03220                 for (i = 0; i < dword_count; i++, data_buff++) {
03221                         dwc_write_reg32(fifo, *data_buff);
03222                 }
03223         }
03224 
03225         ep->xfer_count += byte_count;
03226         ep->xfer_buff += byte_count;
03227         ep->dma_addr += byte_count;
03228 }
03229 
03236 void dwc_otg_ep_set_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03237 {
03238         depctl_data_t depctl;
03239         volatile uint32_t *depctl_addr;
03240 
03241         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
03242                     (ep->is_in ? "IN" : "OUT"));
03243 
03244         if (ep->is_in == 1) {
03245                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
03246                 depctl.d32 = dwc_read_reg32(depctl_addr);
03247 
03248                 /* set the disable and stall bits */
03249                 if (depctl.b.epena) {
03250                         depctl.b.epdis = 1;
03251                 }
03252                 depctl.b.stall = 1;
03253                 dwc_write_reg32(depctl_addr, depctl.d32);
03254         } else {
03255                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
03256                 depctl.d32 = dwc_read_reg32(depctl_addr);
03257 
03258                 /* set the stall bit */
03259                 depctl.b.stall = 1;
03260                 dwc_write_reg32(depctl_addr, depctl.d32);
03261         }
03262 
03263         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
03264 
03265         return;
03266 }
03267 
03274 void dwc_otg_ep_clear_stall(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03275 {
03276         depctl_data_t depctl;
03277         volatile uint32_t *depctl_addr;
03278 
03279         DWC_DEBUGPL(DBG_PCD, "%s ep%d-%s\n", __func__, ep->num,
03280                     (ep->is_in ? "IN" : "OUT"));
03281 
03282         if (ep->is_in == 1) {
03283                 depctl_addr = &(core_if->dev_if->in_ep_regs[ep->num]->diepctl);
03284         } else {
03285                 depctl_addr = &(core_if->dev_if->out_ep_regs[ep->num]->doepctl);
03286         }
03287 
03288         depctl.d32 = dwc_read_reg32(depctl_addr);
03289 
03290         /* clear the stall bits */
03291         depctl.b.stall = 0;
03292 
03293         /* 
03294          * USB Spec 9.4.5: For endpoints using data toggle, regardless
03295          * of whether an endpoint has the Halt feature set, a
03296          * ClearFeature(ENDPOINT_HALT) request always results in the
03297          * data toggle being reinitialized to DATA0.
03298          */
03299         if (ep->type == DWC_OTG_EP_TYPE_INTR ||
03300             ep->type == DWC_OTG_EP_TYPE_BULK) {
03301                 depctl.b.setd0pid = 1;  /* DATA0 */
03302         }
03303 
03304         dwc_write_reg32(depctl_addr, depctl.d32);
03305         DWC_DEBUGPL(DBG_PCD, "DEPCTL=%0x\n", dwc_read_reg32(depctl_addr));
03306         return;
03307 }
03308 
03317 void dwc_otg_read_packet(dwc_otg_core_if_t * core_if,
03318                          uint8_t * dest, uint16_t bytes)
03319 {
03320         int i;
03321         int word_count = (bytes + 3) / 4;
03322 
03323         volatile uint32_t *fifo = core_if->data_fifo[0];
03324         uint32_t *data_buff = (uint32_t *) dest;
03325 
03332         DWC_DEBUGPL((DBG_PCDV | DBG_CILV), "%s(%p,%p,%d)\n", __func__,
03333                     core_if, dest, bytes);
03334 
03335         for (i = 0; i < word_count; i++, data_buff++) {
03336                 *data_buff = dwc_read_reg32(fifo);
03337         }
03338 
03339         return;
03340 }
03341 
03347 void dwc_otg_dump_dev_registers(dwc_otg_core_if_t * core_if)
03348 {
03349         int i;
03350         volatile uint32_t *addr;
03351 
03352         DWC_PRINTF("Device Global Registers\n");
03353         addr = &core_if->dev_if->dev_global_regs->dcfg;
03354         DWC_PRINTF("DCFG                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03355                    dwc_read_reg32(addr));
03356         addr = &core_if->dev_if->dev_global_regs->dctl;
03357         DWC_PRINTF("DCTL                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03358                    dwc_read_reg32(addr));
03359         addr = &core_if->dev_if->dev_global_regs->dsts;
03360         DWC_PRINTF("DSTS                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03361                    dwc_read_reg32(addr));
03362         addr = &core_if->dev_if->dev_global_regs->diepmsk;
03363         DWC_PRINTF("DIEPMSK      @0x%08X : 0x%08X\n", (uint32_t) addr,
03364                    dwc_read_reg32(addr));
03365         addr = &core_if->dev_if->dev_global_regs->doepmsk;
03366         DWC_PRINTF("DOEPMSK      @0x%08X : 0x%08X\n", (uint32_t) addr,
03367                    dwc_read_reg32(addr));
03368         addr = &core_if->dev_if->dev_global_regs->daint;
03369         DWC_PRINTF("DAINT        @0x%08X : 0x%08X\n", (uint32_t) addr,
03370                    dwc_read_reg32(addr));
03371         addr = &core_if->dev_if->dev_global_regs->daintmsk;
03372         DWC_PRINTF("DAINTMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
03373                    dwc_read_reg32(addr));
03374         addr = &core_if->dev_if->dev_global_regs->dtknqr1;
03375         DWC_PRINTF("DTKNQR1      @0x%08X : 0x%08X\n", (uint32_t) addr,
03376                    dwc_read_reg32(addr));
03377         if (core_if->hwcfg2.b.dev_token_q_depth > 6) {
03378                 addr = &core_if->dev_if->dev_global_regs->dtknqr2;
03379                 DWC_PRINTF("DTKNQR2      @0x%08X : 0x%08X\n",
03380                            (uint32_t) addr, dwc_read_reg32(addr));
03381         }
03382 
03383         addr = &core_if->dev_if->dev_global_regs->dvbusdis;
03384         DWC_PRINTF("DVBUSID      @0x%08X : 0x%08X\n", (uint32_t) addr,
03385                    dwc_read_reg32(addr));
03386 
03387         addr = &core_if->dev_if->dev_global_regs->dvbuspulse;
03388         DWC_PRINTF("DVBUSPULSE  @0x%08X : 0x%08X\n",
03389                    (uint32_t) addr, dwc_read_reg32(addr));
03390 
03391                 addr = &core_if->dev_if->dev_global_regs->dtknqr3_dthrctl;
03392                 DWC_PRINTF("DTKNQR3_DTHRCTL      @0x%08X : 0x%08X\n",
03393                            (uint32_t) addr, dwc_read_reg32(addr));
03394 
03395         if (core_if->hwcfg2.b.dev_token_q_depth > 22) {
03396                 addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
03397                 DWC_PRINTF("DTKNQR4      @0x%08X : 0x%08X\n",
03398                            (uint32_t) addr, dwc_read_reg32(addr));
03399         }
03400 
03401         addr = &core_if->dev_if->dev_global_regs->dtknqr4_fifoemptymsk;
03402         DWC_PRINTF("FIFOEMPMSK   @0x%08X : 0x%08X\n", (uint32_t) addr,
03403                    dwc_read_reg32(addr));
03404 
03405         addr = &core_if->dev_if->dev_global_regs->deachint;
03406         DWC_PRINTF("DEACHINT     @0x%08X : 0x%08X\n", (uint32_t) addr,
03407                    dwc_read_reg32(addr));
03408         addr = &core_if->dev_if->dev_global_regs->deachintmsk;
03409         DWC_PRINTF("DEACHINTMSK  @0x%08X : 0x%08X\n", (uint32_t) addr,
03410                    dwc_read_reg32(addr));
03411 
03412         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03413                 addr = &core_if->dev_if->dev_global_regs->diepeachintmsk[i];
03414                 DWC_PRINTF("DIEPEACHINTMSK[%d]   @0x%08X : 0x%08X\n", i,
03415                            (uint32_t) addr, dwc_read_reg32(addr));
03416         }
03417 
03418         for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
03419                 addr = &core_if->dev_if->dev_global_regs->doepeachintmsk[i];
03420                 DWC_PRINTF("DOEPEACHINTMSK[%d]   @0x%08X : 0x%08X\n", i,
03421                            (uint32_t) addr, dwc_read_reg32(addr));
03422         }
03423 
03424         for (i = 0; i <= core_if->dev_if->num_in_eps; i++) {
03425                 DWC_PRINTF("Device IN EP %d Registers\n", i);
03426                 addr = &core_if->dev_if->in_ep_regs[i]->diepctl;
03427                 DWC_PRINTF("DIEPCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03428                            dwc_read_reg32(addr));
03429                 addr = &core_if->dev_if->in_ep_regs[i]->diepint;
03430                 DWC_PRINTF("DIEPINT      @0x%08X : 0x%08X\n", (uint32_t) addr,
03431                            dwc_read_reg32(addr));
03432                 addr = &core_if->dev_if->in_ep_regs[i]->dieptsiz;
03433                 DWC_PRINTF("DIETSIZ      @0x%08X : 0x%08X\n", (uint32_t) addr,
03434                            dwc_read_reg32(addr));
03435                 addr = &core_if->dev_if->in_ep_regs[i]->diepdma;
03436                 DWC_PRINTF("DIEPDMA      @0x%08X : 0x%08X\n", (uint32_t) addr,
03437                            dwc_read_reg32(addr));
03438                 addr = &core_if->dev_if->in_ep_regs[i]->dtxfsts;
03439                 DWC_PRINTF("DTXFSTS      @0x%08X : 0x%08X\n", (uint32_t) addr,
03440                            dwc_read_reg32(addr));
03441                 addr = &core_if->dev_if->in_ep_regs[i]->diepdmab;
03442                 DWC_PRINTF("DIEPDMAB     @0x%08X : 0x%08X\n", (uint32_t) addr,
03443                            0 /*dwc_read_reg32(addr) */ );
03444         }
03445 
03446         for (i = 0; i <= core_if->dev_if->num_out_eps; i++) {
03447                 DWC_PRINTF("Device OUT EP %d Registers\n", i);
03448                 addr = &core_if->dev_if->out_ep_regs[i]->doepctl;
03449                 DWC_PRINTF("DOEPCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03450                            dwc_read_reg32(addr));
03451                 addr = &core_if->dev_if->out_ep_regs[i]->doepfn;
03452                 DWC_PRINTF("DOEPFN       @0x%08X : 0x%08X\n", (uint32_t) addr,
03453                            dwc_read_reg32(addr));
03454                 addr = &core_if->dev_if->out_ep_regs[i]->doepint;
03455                 DWC_PRINTF("DOEPINT      @0x%08X : 0x%08X\n", (uint32_t) addr,
03456                            dwc_read_reg32(addr));
03457                 addr = &core_if->dev_if->out_ep_regs[i]->doeptsiz;
03458                 DWC_PRINTF("DOETSIZ      @0x%08X : 0x%08X\n", (uint32_t) addr,
03459                            dwc_read_reg32(addr));
03460                 addr = &core_if->dev_if->out_ep_regs[i]->doepdma;
03461                 DWC_PRINTF("DOEPDMA      @0x%08X : 0x%08X\n", (uint32_t) addr,
03462                            dwc_read_reg32(addr));
03463                 if (core_if->dma_enable) {      /* Don't access this register in SLAVE mode */
03464                         addr = &core_if->dev_if->out_ep_regs[i]->doepdmab;
03465                         DWC_PRINTF("DOEPDMAB     @0x%08X : 0x%08X\n",
03466                                    (uint32_t) addr, dwc_read_reg32(addr));
03467                 }
03468 
03469         }
03470 }
03471 
03477 void dwc_otg_dump_spram(dwc_otg_core_if_t * core_if)
03478 {
03479         volatile uint8_t *addr, *start_addr, *end_addr;
03480 
03481         DWC_PRINTF("SPRAM Data:\n");
03482         start_addr = (void *)core_if->core_global_regs;
03483         DWC_PRINTF("Base Address: 0x%8X\n", (uint32_t) start_addr);
03484         start_addr += 0x00028000;
03485         end_addr = (void *)core_if->core_global_regs;
03486         end_addr += 0x000280e0;
03487 
03488         for (addr = start_addr; addr < end_addr; addr += 16) {
03489                 DWC_PRINTF
03490                     ("0x%8X:\t%2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X %2X\n",
03491                      (uint32_t) addr, addr[0], addr[1], addr[2], addr[3],
03492                      addr[4], addr[5], addr[6], addr[7], addr[8], addr[9],
03493                      addr[10], addr[11], addr[12], addr[13], addr[14], addr[15]
03494                     );
03495         }
03496 
03497         return;
03498 }
03499 
03505 void dwc_otg_dump_host_registers(dwc_otg_core_if_t * core_if)
03506 {
03507         int i;
03508         volatile uint32_t *addr;
03509 
03510         DWC_PRINTF("Host Global Registers\n");
03511         addr = &core_if->host_if->host_global_regs->hcfg;
03512         DWC_PRINTF("HCFG                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03513                    dwc_read_reg32(addr));
03514         addr = &core_if->host_if->host_global_regs->hfir;
03515         DWC_PRINTF("HFIR                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03516                    dwc_read_reg32(addr));
03517         addr = &core_if->host_if->host_global_regs->hfnum;
03518         DWC_PRINTF("HFNUM        @0x%08X : 0x%08X\n", (uint32_t) addr,
03519                    dwc_read_reg32(addr));
03520         addr = &core_if->host_if->host_global_regs->hptxsts;
03521         DWC_PRINTF("HPTXSTS      @0x%08X : 0x%08X\n", (uint32_t) addr,
03522                    dwc_read_reg32(addr));
03523         addr = &core_if->host_if->host_global_regs->haint;
03524         DWC_PRINTF("HAINT        @0x%08X : 0x%08X\n", (uint32_t) addr,
03525                    dwc_read_reg32(addr));
03526         addr = &core_if->host_if->host_global_regs->haintmsk;
03527         DWC_PRINTF("HAINTMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
03528                    dwc_read_reg32(addr));
03529         if (core_if->dma_desc_enable) {
03530                 addr = &core_if->host_if->host_global_regs->hflbaddr;
03531                 DWC_PRINTF("HFLBADDR     @0x%08X : 0x%08X\n",(uint32_t) addr,
03532                            dwc_read_reg32(addr));
03533         }
03534         
03535         addr = core_if->host_if->hprt0;
03536         DWC_PRINTF("HPRT0        @0x%08X : 0x%08X\n", (uint32_t) addr,
03537                    dwc_read_reg32(addr));
03538 
03539         for (i = 0; i < core_if->core_params->host_channels; i++) {
03540                 DWC_PRINTF("Host Channel %d Specific Registers\n", i);
03541                 addr = &core_if->host_if->hc_regs[i]->hcchar;
03542                 DWC_PRINTF("HCCHAR       @0x%08X : 0x%08X\n", (uint32_t) addr,
03543                            dwc_read_reg32(addr));
03544                 addr = &core_if->host_if->hc_regs[i]->hcsplt;
03545                 DWC_PRINTF("HCSPLT       @0x%08X : 0x%08X\n", (uint32_t) addr,
03546                            dwc_read_reg32(addr));
03547                 addr = &core_if->host_if->hc_regs[i]->hcint;
03548                 DWC_PRINTF("HCINT        @0x%08X : 0x%08X\n", (uint32_t) addr,
03549                            dwc_read_reg32(addr));
03550                 addr = &core_if->host_if->hc_regs[i]->hcintmsk;
03551                 DWC_PRINTF("HCINTMSK     @0x%08X : 0x%08X\n", (uint32_t) addr,
03552                            dwc_read_reg32(addr));
03553                 addr = &core_if->host_if->hc_regs[i]->hctsiz;
03554                 DWC_PRINTF("HCTSIZ       @0x%08X : 0x%08X\n", (uint32_t) addr,
03555                            dwc_read_reg32(addr));
03556                 addr = &core_if->host_if->hc_regs[i]->hcdma;
03557                 DWC_PRINTF("HCDMA        @0x%08X : 0x%08X\n", (uint32_t) addr,
03558                            dwc_read_reg32(addr));
03559                 if (core_if->dma_desc_enable) {
03560                         addr=&core_if->host_if->hc_regs[i]->hcdmab;
03561                         DWC_PRINTF("HCDMAB       @0x%08X : 0x%08X\n",(uint32_t) addr, dwc_read_reg32(addr));
03562         }
03563 
03564         }
03565         return;
03566 }
03567 
03573 void dwc_otg_dump_global_registers(dwc_otg_core_if_t * core_if)
03574 {
03575         int i;
03576         volatile uint32_t *addr;
03577 
03578         DWC_PRINTF("Core Global Registers\n");
03579         addr = &core_if->core_global_regs->gotgctl;
03580         DWC_PRINTF("GOTGCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03581                    dwc_read_reg32(addr));
03582         addr = &core_if->core_global_regs->gotgint;
03583         DWC_PRINTF("GOTGINT      @0x%08X : 0x%08X\n", (uint32_t) addr,
03584                    dwc_read_reg32(addr));
03585         addr = &core_if->core_global_regs->gahbcfg;
03586         DWC_PRINTF("GAHBCFG      @0x%08X : 0x%08X\n", (uint32_t) addr,
03587                    dwc_read_reg32(addr));
03588         addr = &core_if->core_global_regs->gusbcfg;
03589         DWC_PRINTF("GUSBCFG      @0x%08X : 0x%08X\n", (uint32_t) addr,
03590                    dwc_read_reg32(addr));
03591         addr = &core_if->core_global_regs->grstctl;
03592         DWC_PRINTF("GRSTCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03593                    dwc_read_reg32(addr));
03594         addr = &core_if->core_global_regs->gintsts;
03595         DWC_PRINTF("GINTSTS      @0x%08X : 0x%08X\n", (uint32_t) addr,
03596                    dwc_read_reg32(addr));
03597         addr = &core_if->core_global_regs->gintmsk;
03598         DWC_PRINTF("GINTMSK      @0x%08X : 0x%08X\n", (uint32_t) addr,
03599                    dwc_read_reg32(addr));
03600         addr = &core_if->core_global_regs->grxstsr;
03601         DWC_PRINTF("GRXSTSR      @0x%08X : 0x%08X\n", (uint32_t) addr,
03602                    dwc_read_reg32(addr));
03603         addr = &core_if->core_global_regs->grxfsiz;
03604         DWC_PRINTF("GRXFSIZ      @0x%08X : 0x%08X\n", (uint32_t) addr,
03605                    dwc_read_reg32(addr));
03606         addr = &core_if->core_global_regs->gnptxfsiz;
03607         DWC_PRINTF("GNPTXFSIZ @0x%08X : 0x%08X\n", (uint32_t) addr,
03608                    dwc_read_reg32(addr));
03609         addr = &core_if->core_global_regs->gnptxsts;
03610         DWC_PRINTF("GNPTXSTS     @0x%08X : 0x%08X\n", (uint32_t) addr,
03611                    dwc_read_reg32(addr));
03612         addr = &core_if->core_global_regs->gi2cctl;
03613         DWC_PRINTF("GI2CCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03614                    dwc_read_reg32(addr));
03615         addr = &core_if->core_global_regs->gpvndctl;
03616         DWC_PRINTF("GPVNDCTL     @0x%08X : 0x%08X\n", (uint32_t) addr,
03617                    dwc_read_reg32(addr));
03618         addr = &core_if->core_global_regs->ggpio;
03619         DWC_PRINTF("GGPIO        @0x%08X : 0x%08X\n", (uint32_t) addr,
03620                    dwc_read_reg32(addr));
03621         addr = &core_if->core_global_regs->guid;
03622         DWC_PRINTF("GUID                 @0x%08X : 0x%08X\n", (uint32_t) addr,
03623                    dwc_read_reg32(addr));
03624         addr = &core_if->core_global_regs->gsnpsid;
03625         DWC_PRINTF("GSNPSID      @0x%08X : 0x%08X\n", (uint32_t) addr,
03626                    dwc_read_reg32(addr));
03627         addr = &core_if->core_global_regs->ghwcfg1;
03628         DWC_PRINTF("GHWCFG1      @0x%08X : 0x%08X\n", (uint32_t) addr,
03629                    dwc_read_reg32(addr));
03630         addr = &core_if->core_global_regs->ghwcfg2;
03631         DWC_PRINTF("GHWCFG2      @0x%08X : 0x%08X\n", (uint32_t) addr,
03632                    dwc_read_reg32(addr));
03633         addr = &core_if->core_global_regs->ghwcfg3;
03634         DWC_PRINTF("GHWCFG3      @0x%08X : 0x%08X\n", (uint32_t) addr,
03635                    dwc_read_reg32(addr));
03636         addr = &core_if->core_global_regs->ghwcfg4;
03637         DWC_PRINTF("GHWCFG4      @0x%08X : 0x%08X\n", (uint32_t) addr,
03638                    dwc_read_reg32(addr));
03639         addr = &core_if->core_global_regs->glpmcfg;
03640         DWC_PRINTF("GLPMCFG      @0x%08X : 0x%08X\n", (uint32_t) addr,
03641                    dwc_read_reg32(addr));
03642         addr = &core_if->core_global_regs->hptxfsiz;
03643         DWC_PRINTF("HPTXFSIZ     @0x%08X : 0x%08X\n", (uint32_t) addr,
03644                    dwc_read_reg32(addr));
03645 
03646         for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
03647                 addr = &core_if->core_global_regs->dptxfsiz_dieptxf[i];
03648                 DWC_PRINTF("DPTXFSIZ[%d] @0x%08X : 0x%08X\n", i,
03649                            (uint32_t) addr, dwc_read_reg32(addr));
03650         }
03651         addr = core_if->pcgcctl;
03652         DWC_PRINTF("PCGCCTL      @0x%08X : 0x%08X\n", (uint32_t) addr,
03653                    dwc_read_reg32(addr));
03654 }
03655 
03662 void dwc_otg_flush_tx_fifo(dwc_otg_core_if_t * core_if, const int num)
03663 {
03664         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
03665         volatile grstctl_t greset = {.d32 = 0 };
03666         int count = 0;
03667 
03668         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "Flush Tx FIFO %d\n", num);
03669 
03670         greset.b.txfflsh = 1;
03671         greset.b.txfnum = num;
03672         dwc_write_reg32(&global_regs->grstctl, greset.d32);
03673 
03674         do {
03675                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
03676                 if (++count > 10000) {
03677                         DWC_WARN("%s() HANG! GRSTCTL=%0x GNPTXSTS=0x%08x\n",
03678                                  __func__, greset.d32,
03679                                  dwc_read_reg32(&global_regs->gnptxsts));
03680                         break;
03681                 }
03682                 dwc_udelay(1);
03683         } while (greset.b.txfflsh == 1);
03684 
03685         /* Wait for 3 PHY Clocks */
03686         dwc_udelay(1);
03687 }
03688 
03694 void dwc_otg_flush_rx_fifo(dwc_otg_core_if_t * core_if)
03695 {
03696         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
03697         volatile grstctl_t greset = {.d32 = 0 };
03698         int count = 0;
03699 
03700         DWC_DEBUGPL((DBG_CIL | DBG_PCDV), "%s\n", __func__);
03701         /*
03702          * 
03703          */
03704         greset.b.rxfflsh = 1;
03705         dwc_write_reg32(&global_regs->grstctl, greset.d32);
03706 
03707         do {
03708                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
03709                 if (++count > 10000) {
03710                         DWC_WARN("%s() HANG! GRSTCTL=%0x\n", __func__,
03711                                  greset.d32);
03712                         break;
03713                 }
03714                 dwc_udelay(1);
03715         } while (greset.b.rxfflsh == 1);
03716 
03717         /* Wait for 3 PHY Clocks */
03718         dwc_udelay(1);
03719 }
03720 
03725 void dwc_otg_core_reset(dwc_otg_core_if_t * core_if)
03726 {
03727         dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
03728         volatile grstctl_t greset = {.d32 = 0 };
03729         int count = 0;
03730 
03731         DWC_DEBUGPL(DBG_CILV, "%s\n", __func__);
03732         /* Wait for AHB master IDLE state. */
03733         do {
03734                 dwc_udelay(10);
03735                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
03736                 if (++count > 100000) {
03737                         DWC_WARN("%s() HANG! AHB Idle GRSTCTL=%0x\n", __func__,
03738                                  greset.d32);
03739                         return;
03740                 }
03741         }
03742         while (greset.b.ahbidle == 0);
03743 
03744         /* Core Soft Reset */
03745         count = 0;
03746         greset.b.csftrst = 1;
03747         dwc_write_reg32(&global_regs->grstctl, greset.d32);
03748         do {
03749                 greset.d32 = dwc_read_reg32(&global_regs->grstctl);
03750                 if (++count > 10000) {
03751                         DWC_WARN("%s() HANG! Soft Reset GRSTCTL=%0x\n",
03752                                  __func__, greset.d32);
03753                         break;
03754                 }
03755                 dwc_udelay(1);
03756         }
03757         while (greset.b.csftrst == 1);
03758 
03759         /* Wait for 3 PHY Clocks */
03760         dwc_mdelay(100);
03761 }
03762 
03763 uint8_t dwc_otg_is_device_mode(dwc_otg_core_if_t * _core_if)
03764 {
03765         return (dwc_otg_mode(_core_if) != DWC_HOST_MODE);
03766 }
03767 
03768 uint8_t dwc_otg_is_host_mode(dwc_otg_core_if_t * _core_if)
03769 {
03770         return (dwc_otg_mode(_core_if) == DWC_HOST_MODE);
03771 }
03772 
03781 void dwc_otg_cil_register_hcd_callbacks(dwc_otg_core_if_t * core_if,
03782                                         dwc_otg_cil_callbacks_t * cb, void *p)
03783 {
03784         core_if->hcd_cb = cb;
03785         cb->p = p;
03786 }
03787 
03796 void dwc_otg_cil_register_pcd_callbacks(dwc_otg_core_if_t * core_if,
03797                                         dwc_otg_cil_callbacks_t * cb, void *p)
03798 {
03799         core_if->pcd_cb = cb;
03800         cb->p = p;
03801 }
03802 
03803 #ifdef DWC_EN_ISOC
03804 
03812 void write_isoc_frame_data(dwc_otg_core_if_t * core_if, dwc_ep_t * ep)
03813 {
03814         dwc_otg_dev_in_ep_regs_t *ep_regs;
03815         dtxfsts_data_t txstatus = {.d32 = 0 };
03816         uint32_t len = 0;
03817         uint32_t dwords;
03818 
03819         ep->xfer_len = ep->data_per_frame;
03820         ep->xfer_count = 0;
03821 
03822         ep_regs = core_if->dev_if->in_ep_regs[ep->num];
03823 
03824         len = ep->xfer_len - ep->xfer_count;
03825 
03826         if (len > ep->maxpacket) {
03827                 len = ep->maxpacket;
03828         }
03829 
03830         dwords = (len + 3) / 4;
03831 
03832         /* While there is space in the queue and space in the FIFO and
03833          * More data to tranfer, Write packets to the Tx FIFO */
03834         txstatus.d32 =
03835             dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dtxfsts);
03836         DWC_DEBUGPL(DBG_PCDV, "b4 dtxfsts[%d]=0x%08x\n", ep->num, txstatus.d32);
03837 
03838         while (txstatus.b.txfspcavail > dwords &&
03839                ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) {
03840                 /* Write the FIFO */
03841                 dwc_otg_ep_write_packet(core_if, ep, 0);
03842 
03843                 len = ep->xfer_len - ep->xfer_count;
03844                 if (len > ep->maxpacket) {
03845                         len = ep->maxpacket;
03846                 }
03847 
03848                 dwords = (len + 3) / 4;
03849                 txstatus.d32 =
03850                     dwc_read_reg32(&core_if->dev_if->in_ep_regs[ep->num]->
03851                                    dtxfsts);
03852                 DWC_DEBUGPL(DBG_PCDV, "dtxfsts[%d]=0x%08x\n", ep->num,
03853                             txstatus.d32);
03854         }
03855 }
03856 
03864 void dwc_otg_iso_ep_start_frm_transfer(dwc_otg_core_if_t * core_if,
03865                                        dwc_ep_t * ep)
03866 {
03867         deptsiz_data_t deptsiz = {.d32 = 0 };
03868         depctl_data_t depctl = {.d32 = 0 };
03869         dsts_data_t dsts = {.d32 = 0 };
03870         volatile uint32_t *addr;
03871 
03872         if (ep->is_in) {
03873                 addr = &core_if->dev_if->in_ep_regs[ep->num]->diepctl;
03874         } else {
03875                 addr = &core_if->dev_if->out_ep_regs[ep->num]->doepctl;
03876         }
03877 
03878         ep->xfer_len = ep->data_per_frame;
03879         ep->xfer_count = 0;
03880         ep->xfer_buff = ep->cur_pkt_addr;
03881         ep->dma_addr = ep->cur_pkt_dma_addr;
03882 
03883         if (ep->is_in) {
03884                 /* Program the transfer size and packet count
03885                  *      as follows: xfersize = N * maxpacket +
03886                  *      short_packet pktcnt = N + (short_packet
03887                  *      exist ? 1 : 0)  
03888                  */
03889                 deptsiz.b.xfersize = ep->xfer_len;
03890                 deptsiz.b.pktcnt =
03891                     (ep->xfer_len - 1 + ep->maxpacket) / ep->maxpacket;
03892                 deptsiz.b.mc = deptsiz.b.pktcnt;
03893                 dwc_write_reg32(&core_if->dev_if->in_ep_regs[ep->num]->dieptsiz,
03894                                 deptsiz.d32);
03895 
03896                 /* Write the DMA register */
03897                 if (core_if->dma_enable) {
03898                         dwc_write_reg32(&
03899                                         (core_if->dev_if->in_ep_regs[ep->num]->
03900                                          diepdma), (uint32_t) ep->dma_addr);
03901                 }
03902         } else {
03903                 deptsiz.b.pktcnt =
03904                     (ep->xfer_len + (ep->maxpacket - 1)) / ep->maxpacket;
03905                 deptsiz.b.xfersize = deptsiz.b.pktcnt * ep->maxpacket;
03906 
03907                 dwc_write_reg32(&core_if->dev_if->out_ep_regs[ep->num]->
03908                                 doeptsiz, deptsiz.d32);
03909 
03910                 if (core_if->dma_enable) {
03911                         dwc_write_reg32(&
03912                                         (core_if->dev_if->out_ep_regs[ep->num]->
03913                                          doepdma), (uint32_t) ep->dma_addr);
03914                 }
03915         }
03916 
03919         depctl.d32 = 0;
03920         if (ep->bInterval == 1) {
03921                 dsts.d32 =
03922                     dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
03923                 ep->next_frame = dsts.b.soffn + ep->bInterval;
03924 
03925                 if (ep->next_frame & 0x1) {
03926                         depctl.b.setd1pid = 1;
03927                 } else {
03928                         depctl.b.setd0pid = 1;
03929                 }
03930         } else {
03931                 ep->next_frame += ep->bInterval;
03932 
03933                 if (ep->next_frame & 0x1) {
03934                         depctl.b.setd1pid = 1;
03935                 } else {
03936                         depctl.b.setd0pid = 1;
03937                 }
03938         }
03939         depctl.b.epena = 1;
03940         depctl.b.cnak = 1;
03941 
03942         dwc_modify_reg32(addr, 0, depctl.d32);
03943         depctl.d32 = dwc_read_reg32(addr);
03944 
03945         if (ep->is_in && core_if->dma_enable == 0) {
03946                 write_isoc_frame_data(core_if, ep);
03947         }
03948 
03949 }
03950 #endif                          /* DWC_EN_ISOC */
03951 
03952 static void dwc_otg_set_uninitialized(int32_t * p, int size)
03953 {
03954         int i;
03955         for (i = 0; i < size; i++) {
03956                 p[i] = -1;
03957         }
03958 }
03959 
03960 static int dwc_otg_param_initialized(int32_t val)
03961 {
03962         return val != -1;
03963 }
03964 
03965 static int dwc_otg_setup_params(dwc_otg_core_if_t * core_if)
03966 {
03967         int i;
03968         core_if->core_params = DWC_ALLOC(sizeof(*core_if->core_params));
03969         if (!core_if->core_params) {
03970                 return -DWC_E_NO_MEMORY;
03971         }
03972         dwc_otg_set_uninitialized((int32_t *) core_if->core_params,
03973                                   sizeof(*core_if->core_params) /
03974                                   sizeof(int32_t));
03975         DWC_PRINTF("Setting default values for core params\n");
03976         dwc_otg_set_param_otg_cap(core_if, dwc_param_otg_cap_default);
03977         dwc_otg_set_param_dma_enable(core_if, dwc_param_dma_enable_default);
03978         dwc_otg_set_param_dma_desc_enable(core_if,
03979                                           dwc_param_dma_desc_enable_default);
03980         dwc_otg_set_param_opt(core_if, dwc_param_opt_default);
03981         dwc_otg_set_param_dma_burst_size(core_if,
03982                                          dwc_param_dma_burst_size_default);
03983         dwc_otg_set_param_host_support_fs_ls_low_power(core_if,
03984                                                        dwc_param_host_support_fs_ls_low_power_default);
03985         dwc_otg_set_param_enable_dynamic_fifo(core_if,
03986                                               dwc_param_enable_dynamic_fifo_default);
03987         dwc_otg_set_param_data_fifo_size(core_if,
03988                                          dwc_param_data_fifo_size_default);
03989         dwc_otg_set_param_dev_rx_fifo_size(core_if,
03990                                            dwc_param_dev_rx_fifo_size_default);
03991         dwc_otg_set_param_dev_nperio_tx_fifo_size(core_if,
03992                                                   dwc_param_dev_nperio_tx_fifo_size_default);
03993         dwc_otg_set_param_host_rx_fifo_size(core_if,
03994                                             dwc_param_host_rx_fifo_size_default);
03995         dwc_otg_set_param_host_nperio_tx_fifo_size(core_if,
03996                                                    dwc_param_host_nperio_tx_fifo_size_default);
03997         dwc_otg_set_param_host_perio_tx_fifo_size(core_if,
03998                                                   dwc_param_host_perio_tx_fifo_size_default);
03999         dwc_otg_set_param_max_transfer_size(core_if,
04000                                             dwc_param_max_transfer_size_default);
04001         dwc_otg_set_param_max_packet_count(core_if,
04002                                            dwc_param_max_packet_count_default);
04003         dwc_otg_set_param_host_channels(core_if,
04004                                         dwc_param_host_channels_default);
04005         dwc_otg_set_param_dev_endpoints(core_if,
04006                                         dwc_param_dev_endpoints_default);
04007         dwc_otg_set_param_phy_type(core_if, dwc_param_phy_type_default);
04008         dwc_otg_set_param_speed(core_if, dwc_param_speed_default);
04009         dwc_otg_set_param_host_ls_low_power_phy_clk(core_if,
04010                                                     dwc_param_host_ls_low_power_phy_clk_default);
04011         dwc_otg_set_param_phy_ulpi_ddr(core_if, dwc_param_phy_ulpi_ddr_default);
04012         dwc_otg_set_param_phy_ulpi_ext_vbus(core_if,
04013                                             dwc_param_phy_ulpi_ext_vbus_default);
04014         dwc_otg_set_param_phy_utmi_width(core_if,
04015                                          dwc_param_phy_utmi_width_default);
04016         dwc_otg_set_param_ts_dline(core_if, dwc_param_ts_dline_default);
04017         dwc_otg_set_param_i2c_enable(core_if, dwc_param_i2c_enable_default);
04018         dwc_otg_set_param_ulpi_fs_ls(core_if, dwc_param_ulpi_fs_ls_default);
04019         dwc_otg_set_param_en_multiple_tx_fifo(core_if,
04020                                               dwc_param_en_multiple_tx_fifo_default);
04021         for (i = 0; i < 15; i++) {
04022                 dwc_otg_set_param_dev_perio_tx_fifo_size(core_if,
04023                                                          dwc_param_dev_perio_tx_fifo_size_default,
04024                                                          i);
04025         }
04026 
04027         for (i = 0; i < 15; i++) {
04028                 dwc_otg_set_param_dev_tx_fifo_size(core_if,
04029                                                    dwc_param_dev_tx_fifo_size_default,
04030                                                    i);
04031         }
04032         dwc_otg_set_param_thr_ctl(core_if, dwc_param_thr_ctl_default);
04033         dwc_otg_set_param_mpi_enable(core_if, dwc_param_mpi_enable_default);
04034         dwc_otg_set_param_pti_enable(core_if, dwc_param_pti_enable_default);
04035         dwc_otg_set_param_lpm_enable(core_if, dwc_param_lpm_enable_default);
04036         dwc_otg_set_param_ic_usb_cap(core_if, dwc_param_ic_usb_cap_default);
04037         dwc_otg_set_param_tx_thr_length(core_if,
04038                                         dwc_param_tx_thr_length_default);
04039         dwc_otg_set_param_rx_thr_length(core_if,
04040                                         dwc_param_rx_thr_length_default);
04041         dwc_otg_set_param_ahb_thr_ratio(core_if, dwc_param_ahb_thr_ratio_default);
04042         return 0;
04043 }
04044 
04045 uint8_t dwc_otg_is_dma_enable(dwc_otg_core_if_t * core_if)
04046 {
04047         return core_if->dma_enable;
04048 }
04049 
04050 /* Checks if the parameter is outside of its valid range of values */
04051 #define DWC_OTG_PARAM_TEST(_param_, _low_, _high_) \
04052                 (((_param_) < (_low_)) || \
04053                 ((_param_) > (_high_)))
04054 
04055 /* Parameter access functions */
04056 int dwc_otg_set_param_otg_cap(dwc_otg_core_if_t * core_if, int32_t val)
04057 {
04058         int valid;
04059         int retval = 0;
04060         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
04061                 DWC_WARN("Wrong value for otg_cap parameter\n");
04062                 DWC_WARN("otg_cap parameter must be 0,1 or 2\n");
04063                 retval = -DWC_E_INVALID;
04064                 goto out;
04065         }
04066 
04067         valid = 1;
04068         switch (val) {
04069         case DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE:
04070                 if (core_if->hwcfg2.b.op_mode !=
04071                     DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
04072                         valid = 0;
04073                 break;
04074         case DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE:
04075                 if ((core_if->hwcfg2.b.op_mode !=
04076                      DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
04077                     && (core_if->hwcfg2.b.op_mode !=
04078                         DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
04079                     && (core_if->hwcfg2.b.op_mode !=
04080                         DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
04081                     && (core_if->hwcfg2.b.op_mode !=
04082                       DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) {
04083                         valid = 0;
04084                 }
04085                 break;
04086         case DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE:
04087                 /* always valid */
04088                 break;
04089         }
04090         if (!valid) {
04091                 if (dwc_otg_param_initialized(core_if->core_params->otg_cap)) {
04092                         DWC_ERROR
04093                             ("%d invalid for otg_cap paremter. Check HW configuration.\n",
04094                              val);
04095                 }
04096                 val =
04097                     (((core_if->hwcfg2.b.op_mode ==
04098                        DWC_HWCFG2_OP_MODE_HNP_SRP_CAPABLE_OTG)
04099                       || (core_if->hwcfg2.b.op_mode ==
04100                           DWC_HWCFG2_OP_MODE_SRP_ONLY_CAPABLE_OTG)
04101                       || (core_if->hwcfg2.b.op_mode ==
04102                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_DEVICE)
04103                       || (core_if->hwcfg2.b.op_mode ==
04104                           DWC_HWCFG2_OP_MODE_SRP_CAPABLE_HOST)) ?
04105                      DWC_OTG_CAP_PARAM_SRP_ONLY_CAPABLE :
04106                      DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
04107                 retval = -DWC_E_INVALID;
04108         }
04109 
04110         core_if->core_params->otg_cap = val;
04111       out:
04112         return retval;
04113 }
04114 
04115 int32_t dwc_otg_get_param_otg_cap(dwc_otg_core_if_t * core_if)
04116 {
04117         return core_if->core_params->otg_cap;
04118 }
04119 
04120 int dwc_otg_set_param_opt(dwc_otg_core_if_t * core_if, int32_t val)
04121 {
04122         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04123                 DWC_WARN("Wrong value for opt parameter\n");
04124                 return -DWC_E_INVALID;
04125         }
04126         core_if->core_params->opt = val;
04127         return 0;
04128 }
04129 
04130 int32_t dwc_otg_get_param_opt(dwc_otg_core_if_t * core_if)
04131 {
04132         return core_if->core_params->opt;
04133 }
04134 
04135 int dwc_otg_set_param_dma_enable(dwc_otg_core_if_t * core_if, int32_t val)
04136 {
04137         int retval = 0;
04138         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04139                 DWC_WARN("Wrong value for dma enable\n");
04140                 return -DWC_E_INVALID;
04141         }
04142 
04143         if ((val == 1) && (core_if->hwcfg2.b.architecture == 0)) {
04144                 if (dwc_otg_param_initialized(core_if->core_params->dma_enable)) {
04145                         DWC_ERROR
04146                             ("%d invalid for dma_enable paremter. Check HW configuration.\n",
04147                              val);
04148                 }
04149                 val = 0;
04150                 retval = -DWC_E_INVALID;
04151         }
04152 
04153         core_if->core_params->dma_enable = val;
04154         if (val == 0) {
04155                 dwc_otg_set_param_dma_desc_enable(core_if, 0);
04156         }
04157         return retval;
04158 }
04159 
04160 int32_t dwc_otg_get_param_dma_enable(dwc_otg_core_if_t * core_if)
04161 {
04162         return core_if->core_params->dma_enable;
04163 }
04164 
04165 int dwc_otg_set_param_dma_desc_enable(dwc_otg_core_if_t * core_if, int32_t val)
04166 {
04167         int retval = 0;
04168         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04169                 DWC_WARN("Wrong value for dma_enable\n");
04170                 DWC_WARN("dma_desc_enable must be 0 or 1\n");
04171                 return -DWC_E_INVALID;
04172         }
04173 
04174         if ((val == 1)
04175             && ((dwc_otg_get_param_dma_enable(core_if) == 0)
04176                 || (core_if->hwcfg4.b.desc_dma == 0))) {
04177                 if (dwc_otg_param_initialized
04178                     (core_if->core_params->dma_desc_enable)) {
04179                         DWC_ERROR
04180                             ("%d invalid for dma_desc_enable paremter. Check HW configuration.\n",
04181                              val);
04182                 }
04183                 val = 0;
04184                 retval = -DWC_E_INVALID;
04185         }
04186         core_if->core_params->dma_desc_enable = val;
04187         return retval;
04188 }
04189 
04190 int32_t dwc_otg_get_param_dma_desc_enable(dwc_otg_core_if_t * core_if)
04191 {
04192         return core_if->core_params->dma_desc_enable;
04193 }
04194 
04195 int dwc_otg_set_param_host_support_fs_ls_low_power(dwc_otg_core_if_t * core_if,
04196                                                    int32_t val)
04197 {
04198         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04199                 DWC_WARN("Wrong value for host_support_fs_low_power\n");
04200                 DWC_WARN("host_support_fs_low_power must be 0 or 1\n");
04201                 return -DWC_E_INVALID;
04202         }
04203         core_if->core_params->host_support_fs_ls_low_power = val;
04204         return 0;
04205 }
04206 
04207 int32_t dwc_otg_get_param_host_support_fs_ls_low_power(dwc_otg_core_if_t *
04208                                                        core_if)
04209 {
04210         return core_if->core_params->host_support_fs_ls_low_power;
04211 }
04212 
04213 int dwc_otg_set_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if,
04214                                           int32_t val)
04215 {
04216         int retval = 0;
04217         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04218                 DWC_WARN("Wrong value for enable_dynamic_fifo\n");
04219                 DWC_WARN("enable_dynamic_fifo must be 0 or 1\n");
04220                 return -DWC_E_INVALID;
04221         }
04222 
04223         if ((val == 1) && (core_if->hwcfg2.b.dynamic_fifo == 0)) {
04224                 if (dwc_otg_param_initialized
04225                     (core_if->core_params->enable_dynamic_fifo)) {
04226                         DWC_ERROR
04227                             ("%d invalid for enable_dynamic_fifo paremter. Check HW configuration.\n",
04228                              val);
04229                 }
04230                 val = 0;
04231                 retval = -DWC_E_INVALID;
04232         }
04233         core_if->core_params->enable_dynamic_fifo = val;
04234         return retval;
04235 }
04236 
04237 int32_t dwc_otg_get_param_enable_dynamic_fifo(dwc_otg_core_if_t * core_if)
04238 {
04239         return core_if->core_params->enable_dynamic_fifo;
04240 }
04241 
04242 int dwc_otg_set_param_data_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
04243 {
04244         int retval = 0;
04245         if (DWC_OTG_PARAM_TEST(val, 32, 32768)) {
04246                 DWC_WARN("Wrong value for data_fifo_size\n");
04247                 DWC_WARN("data_fifo_size must be 32-32768\n");
04248                 return -DWC_E_INVALID;
04249         }
04250 
04251         if (val > core_if->hwcfg3.b.dfifo_depth) {
04252                 if (dwc_otg_param_initialized
04253                     (core_if->core_params->data_fifo_size)) {
04254                         DWC_ERROR
04255                             ("%d invalid for data_fifo_size parameter. Check HW configuration.\n",
04256                              val);
04257                 }
04258                 val = core_if->hwcfg3.b.dfifo_depth;
04259                 retval = -DWC_E_INVALID;
04260         }
04261 
04262         core_if->core_params->data_fifo_size = val;
04263         return retval;
04264 }
04265 
04266 int32_t dwc_otg_get_param_data_fifo_size(dwc_otg_core_if_t * core_if)
04267 {
04268         return core_if->core_params->data_fifo_size;
04269 }
04270 
04271 int dwc_otg_set_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val)
04272 {
04273         int retval = 0;
04274         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
04275                 DWC_WARN("Wrong value for dev_rx_fifo_size\n");
04276                 DWC_WARN("dev_rx_fifo_size must be 16-32768\n");
04277                 return -DWC_E_INVALID;
04278         }
04279 
04280         if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
04281                 if(dwc_otg_param_initialized(core_if->core_params->dev_rx_fifo_size)) {
04282                 DWC_WARN("%d invalid for dev_rx_fifo_size parameter\n", val);
04283                 }
04284                 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
04285                 retval = -DWC_E_INVALID;
04286         }
04287 
04288         core_if->core_params->dev_rx_fifo_size = val;
04289         return retval;
04290 }
04291 
04292 int32_t dwc_otg_get_param_dev_rx_fifo_size(dwc_otg_core_if_t * core_if)
04293 {
04294         return core_if->core_params->dev_rx_fifo_size;
04295 }
04296 
04297 int dwc_otg_set_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
04298                                               int32_t val)
04299 {
04300         int retval = 0;
04301 
04302         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
04303                 DWC_WARN("Wrong value for dev_nperio_tx_fifo\n");
04304                 DWC_WARN("dev_nperio_tx_fifo must be 16-32768\n");
04305                 return -DWC_E_INVALID;
04306         }
04307 
04308         if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
04309                 if (dwc_otg_param_initialized
04310                     (core_if->core_params->dev_nperio_tx_fifo_size)) {
04311                         DWC_ERROR
04312                             ("%d invalid for dev_nperio_tx_fifo_size. Check HW configuration.\n",
04313                              val);
04314                 }
04315                 val =
04316                     (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
04317                      16);
04318                 retval = -DWC_E_INVALID;
04319         }
04320 
04321         core_if->core_params->dev_nperio_tx_fifo_size = val;
04322         return retval;
04323 }
04324 
04325 int32_t dwc_otg_get_param_dev_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
04326 {
04327         return core_if->core_params->dev_nperio_tx_fifo_size;
04328 }
04329 
04330 int dwc_otg_set_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if,
04331                                         int32_t val)
04332 {
04333         int retval = 0;
04334 
04335         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
04336                 DWC_WARN("Wrong value for host_rx_fifo_size\n");
04337                 DWC_WARN("host_rx_fifo_size must be 16-32768\n");
04338                 return -DWC_E_INVALID;
04339         }
04340 
04341         if (val > dwc_read_reg32(&core_if->core_global_regs->grxfsiz)) {
04342                 if (dwc_otg_param_initialized
04343                     (core_if->core_params->host_rx_fifo_size)) {
04344                         DWC_ERROR
04345                             ("%d invalid for host_rx_fifo_size. Check HW configuration.\n",
04346                              val);
04347                 }
04348                 val = dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
04349                 retval = -DWC_E_INVALID;
04350         }
04351 
04352         core_if->core_params->host_rx_fifo_size = val;
04353         return retval;
04354 
04355 }
04356 
04357 int32_t dwc_otg_get_param_host_rx_fifo_size(dwc_otg_core_if_t * core_if)
04358 {
04359         return core_if->core_params->host_rx_fifo_size;
04360 }
04361 
04362 int dwc_otg_set_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if,
04363                                                int32_t val)
04364 {
04365         int retval = 0;
04366 
04367         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
04368                 DWC_WARN("Wrong value for host_nperio_tx_fifo_size\n");
04369                 DWC_WARN("host_nperio_tx_fifo_size must be 16-32768\n");
04370                 return -DWC_E_INVALID;
04371         }
04372 
04373         if (val > (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >> 16)) {
04374                 if (dwc_otg_param_initialized
04375                     (core_if->core_params->host_nperio_tx_fifo_size)) {
04376                         DWC_ERROR
04377                             ("%d invalid for host_nperio_tx_fifo_size. Check HW configuration.\n",
04378                              val);
04379                 }
04380                 val =
04381                     (dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz) >>
04382                      16);
04383                 retval = -DWC_E_INVALID;
04384         }
04385 
04386         core_if->core_params->host_nperio_tx_fifo_size = val;
04387         return retval;
04388 }
04389 
04390 int32_t dwc_otg_get_param_host_nperio_tx_fifo_size(dwc_otg_core_if_t * core_if)
04391 {
04392         return core_if->core_params->host_nperio_tx_fifo_size;
04393 }
04394 
04395 int dwc_otg_set_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
04396                                               int32_t val)
04397 {
04398         int retval = 0;
04399         if (DWC_OTG_PARAM_TEST(val, 16, 32768)) {
04400                 DWC_WARN("Wrong value for host_perio_tx_fifo_size\n");
04401                 DWC_WARN("host_perio_tx_fifo_size must be 16-32768\n");
04402                 return -DWC_E_INVALID;
04403         }
04404 
04405         if (val >
04406             ((dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >> 16))) {
04407                 if (dwc_otg_param_initialized
04408                     (core_if->core_params->host_perio_tx_fifo_size)) {
04409                         DWC_ERROR
04410                             ("%d invalid for host_perio_tx_fifo_size. Check HW configuration.\n",
04411                              val);
04412                 }
04413                 val =
04414                     (dwc_read_reg32(&core_if->core_global_regs->hptxfsiz) >>
04415                      16);
04416                 retval = -DWC_E_INVALID;
04417         }
04418 
04419         core_if->core_params->host_perio_tx_fifo_size = val;
04420         return retval;
04421 }
04422 
04423 int32_t dwc_otg_get_param_host_perio_tx_fifo_size(dwc_otg_core_if_t * core_if)
04424 {
04425         return core_if->core_params->host_perio_tx_fifo_size;
04426 }
04427 
04428 int dwc_otg_set_param_max_transfer_size(dwc_otg_core_if_t * core_if,
04429                                         int32_t val)
04430 {
04431         int retval = 0;
04432 
04433         if (DWC_OTG_PARAM_TEST(val, 2047, 524288)) {
04434                 DWC_WARN("Wrong value for max_transfer_size\n");
04435                 DWC_WARN("max_transfer_size must be 2047-524288\n");
04436                 return -DWC_E_INVALID;
04437         }
04438 
04439         if (val >= (1 << (core_if->hwcfg3.b.xfer_size_cntr_width + 11))) {
04440                 if (dwc_otg_param_initialized
04441                     (core_if->core_params->max_transfer_size)) {
04442                         DWC_ERROR
04443                             ("%d invalid for max_transfer_size. Check HW configuration.\n",
04444                              val);
04445                 }
04446                 val =
04447                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 11)) -
04448                      1);
04449                 retval = -DWC_E_INVALID;
04450         }
04451 
04452         core_if->core_params->max_transfer_size = val;
04453         return retval;
04454 }
04455 
04456 int32_t dwc_otg_get_param_max_transfer_size(dwc_otg_core_if_t * core_if)
04457 {
04458         return core_if->core_params->max_transfer_size;
04459 }
04460 
04461 int dwc_otg_set_param_max_packet_count(dwc_otg_core_if_t * core_if, int32_t val)
04462 {
04463         int retval = 0;
04464 
04465         if (DWC_OTG_PARAM_TEST(val, 15, 511)) {
04466                 DWC_WARN("Wrong value for max_packet_count\n");
04467                 DWC_WARN("max_packet_count must be 15-511\n");
04468                 return -DWC_E_INVALID;
04469         }
04470 
04471         if (val > (1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4))) {
04472                 if (dwc_otg_param_initialized
04473                     (core_if->core_params->max_packet_count)) {
04474                         DWC_ERROR
04475                             ("%d invalid for max_packet_count. Check HW configuration.\n",
04476                              val);
04477                 }
04478                 val =
04479                     ((1 << (core_if->hwcfg3.b.packet_size_cntr_width + 4)) - 1);
04480                 retval = -DWC_E_INVALID;
04481         }
04482 
04483         core_if->core_params->max_packet_count = val;
04484         return retval;
04485 }
04486 
04487 int32_t dwc_otg_get_param_max_packet_count(dwc_otg_core_if_t * core_if)
04488 {
04489         return core_if->core_params->max_packet_count;
04490 }
04491 
04492 int dwc_otg_set_param_host_channels(dwc_otg_core_if_t * core_if, int32_t val)
04493 {
04494         int retval = 0;
04495 
04496         if (DWC_OTG_PARAM_TEST(val, 1, 16)) {
04497                 DWC_WARN("Wrong value for host_channels\n");
04498                 DWC_WARN("host_channels must be 1-16\n");
04499                 return -DWC_E_INVALID;
04500         }
04501 
04502         if (val > (core_if->hwcfg2.b.num_host_chan + 1)) {
04503                 if (dwc_otg_param_initialized
04504                     (core_if->core_params->host_channels)) {
04505                         DWC_ERROR
04506                             ("%d invalid for host_channels. Check HW configurations.\n",
04507                              val);
04508                 }
04509                 val = (core_if->hwcfg2.b.num_host_chan + 1);
04510                 retval = -DWC_E_INVALID;
04511         }
04512 
04513         core_if->core_params->host_channels = val;
04514         return retval;
04515 }
04516 
04517 int32_t dwc_otg_get_param_host_channels(dwc_otg_core_if_t * core_if)
04518 {
04519         return core_if->core_params->host_channels;
04520 }
04521 
04522 int dwc_otg_set_param_dev_endpoints(dwc_otg_core_if_t * core_if, int32_t val)
04523 {
04524         int retval = 0;
04525 
04526         if (DWC_OTG_PARAM_TEST(val, 1, 15)) {
04527                 DWC_WARN("Wrong value for dev_endpoints\n");
04528                 DWC_WARN("dev_endpoints must be 1-15\n");
04529                 return -DWC_E_INVALID;
04530         }
04531 
04532         if (val > (core_if->hwcfg2.b.num_dev_ep)) {
04533                 if (dwc_otg_param_initialized
04534                     (core_if->core_params->dev_endpoints)) {
04535                         DWC_ERROR
04536                             ("%d invalid for dev_endpoints. Check HW configurations.\n",
04537                              val);
04538                 }
04539                 val = core_if->hwcfg2.b.num_dev_ep;
04540                 retval = -DWC_E_INVALID;
04541         }
04542 
04543         core_if->core_params->dev_endpoints = val;
04544         return retval;
04545 }
04546 
04547 int32_t dwc_otg_get_param_dev_endpoints(dwc_otg_core_if_t * core_if)
04548 {
04549         return core_if->core_params->dev_endpoints;
04550 }
04551 
04552 int dwc_otg_set_param_phy_type(dwc_otg_core_if_t * core_if, int32_t val)
04553 {
04554         int retval = 0;
04555         int valid = 0;
04556 
04557         if (DWC_OTG_PARAM_TEST(val, 0, 2)) {
04558                 DWC_WARN("Wrong value for phy_type\n");
04559                 DWC_WARN("phy_type must be 0,1 or 2\n");
04560                 return -DWC_E_INVALID;
04561         }
04562 #ifndef NO_FS_PHY_HW_CHECKS
04563         if ((val == DWC_PHY_TYPE_PARAM_UTMI) &&
04564             ((core_if->hwcfg2.b.hs_phy_type == 1) ||
04565              (core_if->hwcfg2.b.hs_phy_type == 3))) {
04566                 valid = 1;
04567         } else if ((val == DWC_PHY_TYPE_PARAM_ULPI) &&
04568                    ((core_if->hwcfg2.b.hs_phy_type == 2) ||
04569                     (core_if->hwcfg2.b.hs_phy_type == 3))) {
04570                 valid = 1;
04571         } else if ((val == DWC_PHY_TYPE_PARAM_FS) &&
04572                    (core_if->hwcfg2.b.fs_phy_type == 1)) {
04573                 valid = 1;
04574         }
04575         if (!valid) {
04576                 if (dwc_otg_param_initialized(core_if->core_params->phy_type)) {
04577                         DWC_ERROR
04578                             ("%d invalid for phy_type. Check HW configurations.\n",
04579                              val);
04580                 }
04581                 if (core_if->hwcfg2.b.hs_phy_type) {
04582                         if ((core_if->hwcfg2.b.hs_phy_type == 3) ||
04583                             (core_if->hwcfg2.b.hs_phy_type == 1)) {
04584                                 val = DWC_PHY_TYPE_PARAM_UTMI;
04585                         } else {
04586                                 val = DWC_PHY_TYPE_PARAM_ULPI;
04587                         }
04588                 }
04589                 retval = -DWC_E_INVALID;
04590         }
04591 #endif
04592         core_if->core_params->phy_type = val;
04593         return retval;
04594 }
04595 
04596 int32_t dwc_otg_get_param_phy_type(dwc_otg_core_if_t * core_if)
04597 {
04598         return core_if->core_params->phy_type;
04599 }
04600 
04601 int dwc_otg_set_param_speed(dwc_otg_core_if_t * core_if, int32_t val)
04602 {
04603         int retval = 0;
04604         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04605                 DWC_WARN("Wrong value for speed parameter\n");
04606                 DWC_WARN("max_speed parameter must be 0 or 1\n");
04607                 return -DWC_E_INVALID;
04608         }
04609         if ((val == 0)
04610             && dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS) {
04611                 if (dwc_otg_param_initialized(core_if->core_params->speed)) {
04612                         DWC_ERROR
04613                             ("%d invalid for speed paremter. Check HW configuration.\n",
04614                              val);
04615                 }
04616                 val =
04617                     (dwc_otg_get_param_phy_type(core_if) ==
04618                      DWC_PHY_TYPE_PARAM_FS ? 1 : 0);
04619                 retval = -DWC_E_INVALID;
04620         }
04621         core_if->core_params->speed = val;
04622         return retval;
04623 }
04624 
04625 int32_t dwc_otg_get_param_speed(dwc_otg_core_if_t * core_if)
04626 {
04627         return core_if->core_params->speed;
04628 }
04629 
04630 int dwc_otg_set_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if,
04631                                                 int32_t val)
04632 {
04633         int retval = 0;
04634 
04635         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04636                 DWC_WARN
04637                     ("Wrong value for host_ls_low_power_phy_clk parameter\n");
04638                 DWC_WARN("host_ls_low_power_phy_clk must be 0 or 1\n");
04639                 return -DWC_E_INVALID;
04640         }
04641 
04642         if ((val == DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ)
04643             && (dwc_otg_get_param_phy_type(core_if) == DWC_PHY_TYPE_PARAM_FS)) {
04644                 if(dwc_otg_param_initialized(core_if->core_params->host_ls_low_power_phy_clk)) {
04645                         DWC_ERROR("%d invalid for host_ls_low_power_phy_clk. Check HW configuration.\n",
04646                      val);
04647                 }
04648                 val =
04649                     (dwc_otg_get_param_phy_type(core_if) ==
04650                      DWC_PHY_TYPE_PARAM_FS) ?
04651                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_6MHZ :
04652                     DWC_HOST_LS_LOW_POWER_PHY_CLK_PARAM_48MHZ;
04653                 retval = -DWC_E_INVALID;
04654         }
04655 
04656         core_if->core_params->host_ls_low_power_phy_clk = val;
04657         return retval;
04658 }
04659 
04660 int32_t dwc_otg_get_param_host_ls_low_power_phy_clk(dwc_otg_core_if_t * core_if)
04661 {
04662         return core_if->core_params->host_ls_low_power_phy_clk;
04663 }
04664 
04665 int dwc_otg_set_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if, int32_t val)
04666 {
04667         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04668                 DWC_WARN("Wrong value for phy_ulpi_ddr\n");
04669                 DWC_WARN("phy_upli_ddr must be 0 or 1\n");
04670                 return -DWC_E_INVALID;
04671         }
04672 
04673         core_if->core_params->phy_ulpi_ddr = val;
04674         return 0;
04675 }
04676 
04677 int32_t dwc_otg_get_param_phy_ulpi_ddr(dwc_otg_core_if_t * core_if)
04678 {
04679         return core_if->core_params->phy_ulpi_ddr;
04680 }
04681 
04682 int dwc_otg_set_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if,
04683                                         int32_t val)
04684 {
04685         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04686                 DWC_WARN("Wrong valaue for phy_ulpi_ext_vbus\n");
04687                 DWC_WARN("phy_ulpi_ext_vbus must be 0 or 1\n");
04688                 return -DWC_E_INVALID;
04689         }
04690 
04691         core_if->core_params->phy_ulpi_ext_vbus = val;
04692         return 0;
04693 }
04694 
04695 int32_t dwc_otg_get_param_phy_ulpi_ext_vbus(dwc_otg_core_if_t * core_if)
04696 {
04697         return core_if->core_params->phy_ulpi_ext_vbus;
04698 }
04699 
04700 int dwc_otg_set_param_phy_utmi_width(dwc_otg_core_if_t * core_if, int32_t val)
04701 {
04702         if (DWC_OTG_PARAM_TEST(val, 8, 8) && DWC_OTG_PARAM_TEST(val, 16, 16)) {
04703                 DWC_WARN("Wrong valaue for phy_utmi_width\n");
04704                 DWC_WARN("phy_utmi_width must be 8 or 16\n");
04705                 return -DWC_E_INVALID;
04706         }
04707 
04708         core_if->core_params->phy_utmi_width = val;
04709         return 0;
04710 }
04711 
04712 int32_t dwc_otg_get_param_phy_utmi_width(dwc_otg_core_if_t * core_if)
04713 {
04714         return core_if->core_params->phy_utmi_width;
04715 }
04716 
04717 int dwc_otg_set_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if, int32_t val)
04718 {
04719         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04720                 DWC_WARN("Wrong valaue for ulpi_fs_ls\n");
04721                 DWC_WARN("ulpi_fs_ls must be 0 or 1\n");
04722                 return -DWC_E_INVALID;
04723         }
04724 
04725         core_if->core_params->ulpi_fs_ls = val;
04726         return 0;
04727 }
04728 
04729 int32_t dwc_otg_get_param_ulpi_fs_ls(dwc_otg_core_if_t * core_if)
04730 {
04731         return core_if->core_params->ulpi_fs_ls;
04732 }
04733 
04734 int dwc_otg_set_param_ts_dline(dwc_otg_core_if_t * core_if, int32_t val)
04735 {
04736         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04737                 DWC_WARN("Wrong valaue for ts_dline\n");
04738                 DWC_WARN("ts_dline must be 0 or 1\n");
04739                 return -DWC_E_INVALID;
04740         }
04741 
04742         core_if->core_params->ts_dline = val;
04743         return 0;
04744 }
04745 
04746 int32_t dwc_otg_get_param_ts_dline(dwc_otg_core_if_t * core_if)
04747 {
04748         return core_if->core_params->ts_dline;
04749 }
04750 
04751 int dwc_otg_set_param_i2c_enable(dwc_otg_core_if_t * core_if, int32_t val)
04752 {
04753         int retval = 0;
04754         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04755                 DWC_WARN("Wrong valaue for i2c_enable\n");
04756                 DWC_WARN("i2c_enable must be 0 or 1\n");
04757                 return -DWC_E_INVALID;
04758         }
04759 #ifndef NO_FS_PHY_HW_CHECK
04760         if (val == 1 && core_if->hwcfg3.b.i2c == 0) {
04761                 if(dwc_otg_param_initialized(core_if->core_params->i2c_enable)) {
04762                         DWC_ERROR("%d invalid for i2c_enable. Check HW configuration.\n",
04763                      val);
04764                 }
04765                 val = 0;
04766                 retval = -DWC_E_INVALID;
04767         }
04768 #endif
04769 
04770         core_if->core_params->i2c_enable = val;
04771         return retval;
04772 }
04773 
04774 int32_t dwc_otg_get_param_i2c_enable(dwc_otg_core_if_t * core_if)
04775 {
04776         return core_if->core_params->i2c_enable;
04777 }
04778 
04779 int dwc_otg_set_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
04780                                              int32_t val, int fifo_num)
04781 {
04782         int retval = 0;
04783 
04784         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
04785                 DWC_WARN("Wrong value for dev_perio_tx_fifo_size\n");
04786                 DWC_WARN("dev_perio_tx_fifo_size must be 4-768\n");
04787                 return -DWC_E_INVALID;
04788         }
04789 
04790         if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
04791                 if(dwc_otg_param_initialized(core_if->core_params->dev_perio_tx_fifo_size[fifo_num])) {
04792                         DWC_ERROR("`%d' invalid for parameter `dev_perio_fifo_size_%d'. Check HW configuration.\n",
04793                      val, fifo_num);
04794                 }
04795                 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
04796                 retval = -DWC_E_INVALID;
04797         }
04798 
04799         core_if->core_params->dev_perio_tx_fifo_size[fifo_num] = val;
04800         return retval;
04801 }
04802 
04803 int32_t dwc_otg_get_param_dev_perio_tx_fifo_size(dwc_otg_core_if_t * core_if,
04804                                                  int fifo_num)
04805 {
04806         return core_if->core_params->dev_perio_tx_fifo_size[fifo_num];
04807 }
04808 
04809 int dwc_otg_set_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if,
04810                                           int32_t val)
04811 {
04812         int retval = 0;
04813         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04814                 DWC_WARN("Wrong valaue for en_multiple_tx_fifo,\n");
04815                 DWC_WARN("en_multiple_tx_fifo must be 0 or 1\n");
04816                 return -DWC_E_INVALID;
04817         }
04818 
04819         if (val == 1 && core_if->hwcfg4.b.ded_fifo_en == 0) {
04820                 if(dwc_otg_param_initialized(core_if->core_params->en_multiple_tx_fifo)) {
04821                         DWC_ERROR("%d invalid for parameter en_multiple_tx_fifo. Check HW configuration.\n",
04822                      val);
04823                 }
04824                 val = 0;
04825                 retval = -DWC_E_INVALID;
04826         }
04827 
04828         core_if->core_params->en_multiple_tx_fifo = val;
04829         return retval;
04830 }
04831 
04832 int32_t dwc_otg_get_param_en_multiple_tx_fifo(dwc_otg_core_if_t * core_if)
04833 {
04834         return core_if->core_params->en_multiple_tx_fifo;
04835 }
04836 
04837 int dwc_otg_set_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if, int32_t val,
04838                                        int fifo_num)
04839 {
04840         int retval = 0;
04841 
04842         if (DWC_OTG_PARAM_TEST(val, 4, 768)) {
04843                 DWC_WARN("Wrong value for dev_tx_fifo_size\n");
04844                 DWC_WARN("dev_tx_fifo_size must be 4-768\n");
04845                 return -DWC_E_INVALID;
04846         }
04847 
04848         if (val > (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]))) {
04849                 if(dwc_otg_param_initialized(core_if->core_params->dev_tx_fifo_size[fifo_num])) {
04850                         DWC_ERROR("`%d' invalid for parameter `dev_tx_fifo_size_%d'. Check HW configuration.\n",
04851                      val, fifo_num);
04852                 }
04853                 val = (dwc_read_reg32(&core_if->core_global_regs->dptxfsiz_dieptxf[fifo_num]));
04854                 retval = -DWC_E_INVALID;
04855         }
04856 
04857         core_if->core_params->dev_tx_fifo_size[fifo_num] = val;
04858         return retval;
04859 }
04860 
04861 int32_t dwc_otg_get_param_dev_tx_fifo_size(dwc_otg_core_if_t * core_if,
04862                                            int fifo_num)
04863 {
04864         return core_if->core_params->dev_tx_fifo_size[fifo_num];
04865 }
04866 
04867 int dwc_otg_set_param_thr_ctl(dwc_otg_core_if_t * core_if, int32_t val)
04868 {
04869         int retval = 0;
04870 
04871         if (DWC_OTG_PARAM_TEST(val, 0, 7)) {
04872                 DWC_WARN("Wrong value for thr_ctl\n");
04873                 DWC_WARN("thr_ctl must be 0-7\n");
04874                 return -DWC_E_INVALID;
04875         }
04876 
04877         if ((val != 0) &&
04878             (!dwc_otg_get_param_dma_enable(core_if) ||
04879              !core_if->hwcfg4.b.ded_fifo_en)) {
04880                 if(dwc_otg_param_initialized(core_if->core_params->thr_ctl)) {
04881                         DWC_ERROR("%d invalid for parameter thr_ctl. Check HW configuration.\n",
04882                      val);
04883                 }
04884                 val = 0;
04885                 retval = -DWC_E_INVALID;
04886         }
04887 
04888         core_if->core_params->thr_ctl = val;
04889         return retval;
04890 }
04891 
04892 int32_t dwc_otg_get_param_thr_ctl(dwc_otg_core_if_t * core_if)
04893 {
04894         return core_if->core_params->thr_ctl;
04895 }
04896 
04897 int dwc_otg_set_param_lpm_enable(dwc_otg_core_if_t * core_if, int32_t val)
04898 {
04899         int retval = 0;
04900 
04901         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04902                 DWC_WARN("Wrong value for lpm_enable\n");
04903                 DWC_WARN("lpm_enable must be 0 or 1\n");
04904                 return -DWC_E_INVALID;
04905         }
04906 
04907         if (val && !core_if->hwcfg3.b.otg_lpm_en) {
04908                 if(dwc_otg_param_initialized(core_if->core_params->lpm_enable)) {
04909                         DWC_ERROR("%d invalid for parameter lpm_enable. Check HW configuration.\n",
04910                      val);
04911                 }
04912                 val = 0;
04913                 retval = -DWC_E_INVALID;
04914         }
04915 
04916         core_if->core_params->lpm_enable = val;
04917         return retval;
04918 }
04919 
04920 int32_t dwc_otg_get_param_lpm_enable(dwc_otg_core_if_t * core_if)
04921 {
04922         return core_if->core_params->lpm_enable;
04923 }
04924 
04925 int dwc_otg_set_param_tx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
04926 {
04927         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
04928                 DWC_WARN("Wrong valaue for tx_thr_length\n");
04929                 DWC_WARN("tx_thr_length must be 8 - 128\n");
04930                 return -DWC_E_INVALID;
04931         }
04932 
04933         core_if->core_params->tx_thr_length = val;
04934         return 0;
04935 }
04936 
04937 int32_t dwc_otg_get_param_tx_thr_length(dwc_otg_core_if_t * core_if)
04938 {
04939         return core_if->core_params->tx_thr_length;
04940 }
04941 
04942 int dwc_otg_set_param_rx_thr_length(dwc_otg_core_if_t * core_if, int32_t val)
04943 {
04944         if (DWC_OTG_PARAM_TEST(val, 8, 128)) {
04945                 DWC_WARN("Wrong valaue for rx_thr_length\n");
04946                 DWC_WARN("rx_thr_length must be 8 - 128\n");
04947                 return -DWC_E_INVALID;
04948         }
04949 
04950         core_if->core_params->rx_thr_length = val;
04951         return 0;
04952 }
04953 
04954 int32_t dwc_otg_get_param_rx_thr_length(dwc_otg_core_if_t * core_if)
04955 {
04956         return core_if->core_params->rx_thr_length;
04957 }
04958 
04959 int dwc_otg_set_param_dma_burst_size(dwc_otg_core_if_t * core_if, int32_t val)
04960 {
04961         if (DWC_OTG_PARAM_TEST(val, 1, 1) &&
04962             DWC_OTG_PARAM_TEST(val, 4, 4) &&
04963             DWC_OTG_PARAM_TEST(val, 8, 8) &&
04964             DWC_OTG_PARAM_TEST(val, 16, 16) &&
04965             DWC_OTG_PARAM_TEST(val, 32, 32) &&
04966             DWC_OTG_PARAM_TEST(val, 64, 64) &&
04967             DWC_OTG_PARAM_TEST(val, 128, 128) &&
04968             DWC_OTG_PARAM_TEST(val, 256, 256)) {
04969                 DWC_WARN("`%d' invalid for parameter `dma_burst_size'\n", val);
04970                 return -DWC_E_INVALID;
04971         }
04972         core_if->core_params->dma_burst_size = val;
04973         return 0;
04974 }
04975 
04976 int32_t dwc_otg_get_param_dma_burst_size(dwc_otg_core_if_t * core_if)
04977 {
04978         return core_if->core_params->dma_burst_size;
04979 }
04980 
04981 int dwc_otg_set_param_pti_enable(dwc_otg_core_if_t * core_if, int32_t val)
04982 {
04983         int retval = 0;
04984         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
04985                 DWC_WARN("`%d' invalid for parameter `pti_enable'\n", val);
04986                 return -DWC_E_INVALID;
04987         }
04988         if (val && (core_if->snpsid < OTG_CORE_REV_2_72a)) {
04989                 if (dwc_otg_param_initialized(core_if->core_params->pti_enable)) {
04990                         DWC_ERROR("%d invalid for parameter pti_enable. Check HW configuration.\n",
04991                              val);
04992                 }
04993                 retval = -DWC_E_INVALID;
04994                 val = 0;
04995         }
04996         core_if->core_params->pti_enable = val;
04997         return retval;
04998 }
04999 
05000 int32_t dwc_otg_get_param_pti_enable(dwc_otg_core_if_t * core_if)
05001 {
05002         return core_if->core_params->pti_enable;
05003 }
05004 
05005 int dwc_otg_set_param_mpi_enable(dwc_otg_core_if_t * core_if, int32_t val)
05006 {
05007         int retval = 0;
05008         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05009                 DWC_WARN("`%d' invalid for parameter `mpi_enable'\n", val);
05010                 return -DWC_E_INVALID;
05011         }
05012         if (val && (core_if->hwcfg2.b.multi_proc_int == 0)) {
05013                 if (dwc_otg_param_initialized(core_if->core_params->mpi_enable)) {
05014                         DWC_ERROR("%d invalid for parameter mpi_enable. Check HW configuration.\n",
05015                              val);
05016                 }
05017                 retval = -DWC_E_INVALID;
05018                 val = 0;
05019         }
05020         core_if->core_params->mpi_enable = val;
05021         return retval;
05022 }
05023 
05024 int32_t dwc_otg_get_param_mpi_enable(dwc_otg_core_if_t * core_if)
05025 {
05026         return core_if->core_params->mpi_enable;
05027 }
05028 
05029 int dwc_otg_set_param_ic_usb_cap(dwc_otg_core_if_t * core_if,
05030                                         int32_t val)
05031 {
05032         int retval = 0;
05033         if (DWC_OTG_PARAM_TEST(val, 0, 1)) {
05034                 DWC_WARN("`%d' invalid for parameter `ic_usb_cap'\n", val);
05035                 DWC_WARN("ic_usb_cap must be 0 or 1\n");
05036                 return -DWC_E_INVALID;
05037         }
05038 
05039         if (val && (core_if->hwcfg3.b.otg_enable_ic_usb == 0)) {
05040                 if (dwc_otg_param_initialized(core_if->core_params->ic_usb_cap)) {
05041                         DWC_ERROR("%d invalid for parameter ic_usb_cap. Check HW configuration.\n",
05042                              val);
05043                 }
05044                 retval = -DWC_E_INVALID;
05045                 val = 0;
05046         }
05047         core_if->core_params->ic_usb_cap = val;
05048         return retval;
05049 }
05050 int32_t dwc_otg_get_param_ic_usb_cap(dwc_otg_core_if_t * core_if)
05051 {
05052         return core_if->core_params->ic_usb_cap;
05053 }
05054 
05055 int dwc_otg_set_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if, int32_t val)
05056 {
05057         int retval = 0;
05058         int valid = 1;
05059 
05060         if(DWC_OTG_PARAM_TEST(val, 0, 3)) {
05061                 DWC_WARN("`%d' invalid for parameter `ahb_thr_ratio'\n", val);
05062                 DWC_WARN("ahb_thr_ratio must be 0 - 3\n");
05063                 return -DWC_E_INVALID;
05064         }
05065 
05066         if(val && (core_if->snpsid < OTG_CORE_REV_2_81a || !dwc_otg_get_param_thr_ctl(core_if))) {
05067                 valid = 0;
05068         } else if(val && ((dwc_otg_get_param_tx_thr_length(core_if) / (1 << val)) < 4)) {
05069                 valid = 0;
05070         }
05071         if(valid == 0) {
05072                 if(dwc_otg_param_initialized(core_if->core_params->ahb_thr_ratio)) {
05073                         DWC_ERROR("%d invalid for parameter ahb_thr_ratio. Chack HW configuration.\n", val);
05074                 }
05075                 retval = -DWC_E_INVALID;
05076                 val = 0;
05077         }
05078 
05079         core_if->core_params->ahb_thr_ratio = val;
05080         return retval;
05081 }
05082 int32_t dwc_otg_get_param_ahb_thr_ratio(dwc_otg_core_if_t * core_if)
05083 {
05084         return core_if->core_params->ahb_thr_ratio;
05085 }
05086 
05087 
05088 uint32_t dwc_otg_get_hnpstatus(dwc_otg_core_if_t * core_if)
05089 {
05090         gotgctl_data_t otgctl;
05091         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
05092         return otgctl.b.hstnegscs;
05093 }
05094 
05095 uint32_t dwc_otg_get_srpstatus(dwc_otg_core_if_t * core_if)
05096 {
05097         gotgctl_data_t otgctl;
05098         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
05099         return otgctl.b.sesreqscs;
05100 }
05101 
05102 void dwc_otg_set_hnpreq(dwc_otg_core_if_t * core_if, uint32_t val)
05103 {
05104         gotgctl_data_t otgctl;
05105         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
05106         otgctl.b.hnpreq = val;
05107         dwc_write_reg32(&core_if->core_global_regs->gotgctl, otgctl.d32);
05108 }
05109 
05110 uint32_t dwc_otg_get_gsnpsid(dwc_otg_core_if_t * core_if)
05111 {
05112         return core_if->snpsid;
05113 }
05114 
05115 uint32_t dwc_otg_get_mode(dwc_otg_core_if_t * core_if)
05116 {
05117         gotgctl_data_t otgctl;
05118         otgctl.d32 = dwc_read_reg32(&core_if->core_global_regs->gotgctl);
05119         return otgctl.b.currmod;
05120 }
05121 
05122 uint32_t dwc_otg_get_hnpcapable(dwc_otg_core_if_t * core_if)
05123 {
05124         gusbcfg_data_t usbcfg;
05125         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
05126         return usbcfg.b.hnpcap;
05127 }
05128 
05129 void dwc_otg_set_hnpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
05130 {
05131         gusbcfg_data_t usbcfg;
05132         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
05133         usbcfg.b.hnpcap = val;
05134         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
05135 }
05136 
05137 uint32_t dwc_otg_get_srpcapable(dwc_otg_core_if_t * core_if)
05138 {
05139         gusbcfg_data_t usbcfg;
05140         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
05141         return usbcfg.b.srpcap;
05142 }
05143 
05144 void dwc_otg_set_srpcapable(dwc_otg_core_if_t * core_if, uint32_t val)
05145 {
05146         gusbcfg_data_t usbcfg;
05147         usbcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
05148         usbcfg.b.srpcap = val;
05149         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, usbcfg.d32);
05150 }
05151 
05152 uint32_t dwc_otg_get_devspeed(dwc_otg_core_if_t * core_if)
05153 {
05154         dcfg_data_t dcfg;
05155         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
05156         return dcfg.b.devspd;
05157 }
05158 
05159 void dwc_otg_set_devspeed(dwc_otg_core_if_t * core_if, uint32_t val)
05160 {
05161         dcfg_data_t dcfg;
05162         dcfg.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dcfg);
05163         dcfg.b.devspd = val;
05164         dwc_write_reg32(&core_if->dev_if->dev_global_regs->dcfg, dcfg.d32);
05165 }
05166 
05167 uint32_t dwc_otg_get_busconnected(dwc_otg_core_if_t * core_if)
05168 {
05169         hprt0_data_t hprt0;
05170         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05171         return hprt0.b.prtconnsts;
05172 }
05173 
05174 uint32_t dwc_otg_get_enumspeed(dwc_otg_core_if_t * core_if)
05175 {
05176         dsts_data_t dsts;
05177         dsts.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dsts);
05178         return dsts.b.enumspd;
05179 }
05180 
05181 uint32_t dwc_otg_get_prtpower(dwc_otg_core_if_t * core_if)
05182 {
05183         hprt0_data_t hprt0;
05184         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05185         return hprt0.b.prtpwr;
05186 
05187 }
05188 
05189 void dwc_otg_set_prtpower(dwc_otg_core_if_t * core_if, uint32_t val)
05190 {
05191         hprt0_data_t hprt0;
05192         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05193         hprt0.b.prtpwr = val;
05194         dwc_write_reg32(core_if->host_if->hprt0, val);
05195 }
05196 
05197 uint32_t dwc_otg_get_prtsuspend(dwc_otg_core_if_t * core_if)
05198 {
05199         hprt0_data_t hprt0;
05200         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05201         return hprt0.b.prtsusp;
05202 
05203 }
05204 
05205 void dwc_otg_set_prtsuspend(dwc_otg_core_if_t * core_if, uint32_t val)
05206 {
05207         hprt0_data_t hprt0;
05208         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05209         hprt0.b.prtsusp = val;
05210         dwc_write_reg32(core_if->host_if->hprt0, val);
05211 }
05212 
05213 void dwc_otg_set_prtresume(dwc_otg_core_if_t * core_if, uint32_t val)
05214 {
05215         hprt0_data_t hprt0;
05216         hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
05217         hprt0.b.prtres = val;
05218         dwc_write_reg32(core_if->host_if->hprt0, val);
05219 }
05220 
05221 uint32_t dwc_otg_get_remotewakesig(dwc_otg_core_if_t * core_if)
05222 {
05223         dctl_data_t dctl;
05224         dctl.d32 = dwc_read_reg32(&core_if->dev_if->dev_global_regs->dctl);
05225         return dctl.b.rmtwkupsig;
05226 }
05227 
05228 uint32_t dwc_otg_get_lpm_portsleepstatus(dwc_otg_core_if_t * core_if)
05229 {
05230         glpmcfg_data_t lpmcfg;
05231         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05232 
05233         DWC_ASSERT(!
05234                    ((core_if->lx_state == DWC_OTG_L1) ^ lpmcfg.b.prt_sleep_sts),
05235                    "lx_state = %d, lmpcfg.prt_sleep_sts = %d\n",
05236                    core_if->lx_state, lpmcfg.b.prt_sleep_sts);
05237 
05238         return lpmcfg.b.prt_sleep_sts;
05239 }
05240 
05241 uint32_t dwc_otg_get_lpm_remotewakeenabled(dwc_otg_core_if_t * core_if)
05242 {
05243         glpmcfg_data_t lpmcfg;
05244         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05245         return lpmcfg.b.rem_wkup_en;
05246 }
05247 
05248 uint32_t dwc_otg_get_lpmresponse(dwc_otg_core_if_t * core_if)
05249 {
05250         glpmcfg_data_t lpmcfg;
05251         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05252         return lpmcfg.b.appl_resp;
05253 }
05254 
05255 void dwc_otg_set_lpmresponse(dwc_otg_core_if_t * core_if, uint32_t val)
05256 {
05257         glpmcfg_data_t lpmcfg;
05258         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05259         lpmcfg.b.appl_resp = val;
05260         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
05261 }
05262 
05263 uint32_t dwc_otg_get_hsic_connect(dwc_otg_core_if_t * core_if)
05264 {
05265         glpmcfg_data_t lpmcfg;
05266         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05267         return lpmcfg.b.hsic_connect;
05268 }
05269 
05270 void dwc_otg_set_hsic_connect(dwc_otg_core_if_t * core_if, uint32_t val)
05271 {
05272         glpmcfg_data_t lpmcfg;
05273         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05274         lpmcfg.b.hsic_connect = val;
05275         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
05276 }
05277 
05278 uint32_t dwc_otg_get_inv_sel_hsic(dwc_otg_core_if_t * core_if)
05279 {
05280         glpmcfg_data_t lpmcfg;
05281         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05282         return lpmcfg.b.inv_sel_hsic;
05283 
05284 }
05285 
05286 void dwc_otg_set_inv_sel_hsic(dwc_otg_core_if_t * core_if, uint32_t val)
05287 {
05288         glpmcfg_data_t lpmcfg;
05289         lpmcfg.d32 = dwc_read_reg32(&core_if->core_global_regs->glpmcfg);
05290         lpmcfg.b.inv_sel_hsic = val;
05291         dwc_write_reg32(&core_if->core_global_regs->glpmcfg, lpmcfg.d32);
05292 }
05293 
05294 uint32_t dwc_otg_get_gotgctl(dwc_otg_core_if_t * core_if)
05295 {
05296         return dwc_read_reg32(&core_if->core_global_regs->gotgctl);
05297 }
05298 
05299 void dwc_otg_set_gotgctl(dwc_otg_core_if_t * core_if, uint32_t val)
05300 {
05301         dwc_write_reg32(&core_if->core_global_regs->gotgctl, val);
05302 }
05303 
05304 uint32_t dwc_otg_get_gusbcfg(dwc_otg_core_if_t * core_if)
05305 {
05306         return dwc_read_reg32(&core_if->core_global_regs->gusbcfg);
05307 }
05308 
05309 void dwc_otg_set_gusbcfg(dwc_otg_core_if_t * core_if, uint32_t val)
05310 {
05311         dwc_write_reg32(&core_if->core_global_regs->gusbcfg, val);
05312 }
05313 
05314 uint32_t dwc_otg_get_grxfsiz(dwc_otg_core_if_t * core_if)
05315 {
05316         return dwc_read_reg32(&core_if->core_global_regs->grxfsiz);
05317 }
05318 
05319 void dwc_otg_set_grxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
05320 {
05321         dwc_write_reg32(&core_if->core_global_regs->grxfsiz, val);
05322 }
05323 
05324 uint32_t dwc_otg_get_gnptxfsiz(dwc_otg_core_if_t * core_if)
05325 {
05326         return dwc_read_reg32(&core_if->core_global_regs->gnptxfsiz);
05327 }
05328 
05329 void dwc_otg_set_gnptxfsiz(dwc_otg_core_if_t * core_if, uint32_t val)
05330 {
05331         dwc_write_reg32(&core_if->core_global_regs->gnptxfsiz, val);
05332 }
05333 
05334 uint32_t dwc_otg_get_gpvndctl(dwc_otg_core_if_t * core_if)
05335 {
05336         return dwc_read_reg32(&core_if->core_global_regs->gpvndctl);
05337 }
05338 
05339 void dwc_otg_set_gpvndctl(dwc_otg_core_if_t * core_if, uint32_t val)
05340 {
05341         dwc_write_reg32(&core_if->core_global_regs->gpvndctl, val);
05342 }
05343 
05344 uint32_t dwc_otg_get_ggpio(dwc_otg_core_if_t * core_if)
05345 {
05346         return dwc_read_reg32(&core_if->core_global_regs->ggpio);
05347 }
05348 
05349 void dwc_otg_set_ggpio(dwc_otg_core_if_t * core_if, uint32_t val)
05350 {
05351         dwc_write_reg32(&core_if->core_global_regs->ggpio, val);
05352 }
05353 
05354 uint32_t dwc_otg_get_hprt0(dwc_otg_core_if_t * core_if)
05355 {
05356         return dwc_read_reg32(core_if->host_if->hprt0);
05357 
05358 }
05359 
05360 void dwc_otg_set_hprt0(dwc_otg_core_if_t * core_if, uint32_t val)
05361 {
05362         dwc_write_reg32(core_if->host_if->hprt0, val);
05363 }
05364 
05365 uint32_t dwc_otg_get_guid(dwc_otg_core_if_t * core_if)
05366 {
05367         return dwc_read_reg32(&core_if->core_global_regs->guid);
05368 }
05369 
05370 void dwc_otg_set_guid(dwc_otg_core_if_t * core_if, uint32_t val)
05371 {
05372         dwc_write_reg32(&core_if->core_global_regs->guid, val);
05373 }
05374 
05375 uint32_t dwc_otg_get_hptxfsiz(dwc_otg_core_if_t * core_if)
05376 {
05377         return dwc_read_reg32(&core_if->core_global_regs->hptxfsiz);
05378 }

Generated on Tue May 5 02:22:48 2009 for DesignWare USB 2.0 OTG Controller (DWC_otg) Device Driver by  doxygen 1.4.7