LCOV - code coverage report
Current view: top level - drivers/usb/host/dwc_otg - dwc_otg_cil.c (source / functions) Hit Total Coverage
Test: Real Lines: 780 2916 26.7 %
Date: 2020-10-17 15:46:16 Functions: 1 205 0.5 %
Legend: Neither, QEMU, Real, Both Branches: 0 0 -

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

Generated by: LCOV version 1.14