USB: Reduce the time of dwc_otg_driver_init.
authorwlf <wulf@rock-chips.com>
Wed, 26 Mar 2014 12:59:20 +0000 (20:59 +0800)
committerwlf <wulf@rock-chips.com>
Wed, 26 Mar 2014 12:59:20 +0000 (20:59 +0800)
drivers/usb/dwc_otg_310/dwc_otg_cil.c
drivers/usb/dwc_otg_310/dwc_otg_core_if.h
drivers/usb/dwc_otg_310/dwc_otg_driver.c
drivers/usb/dwc_otg_310/dwc_otg_hcd.c
drivers/usb/dwc_otg_310/dwc_otg_hcd_linux.c
drivers/usb/dwc_otg_310/dwc_otg_pcd.c
drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c

index 1eda4c0fd79cc057bd578d6f5ee5cdf0c3ae4f43..acd1c679fcb64490e30b363c74b1c978fb7f969c 100755 (executable)
@@ -1199,6 +1199,323 @@ static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
        return num_out_eps;
 }
 
+void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
+{
+       int i = 0;
+       dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
+       dwc_otg_dev_if_t *dev_if = core_if->dev_if;
+       gahbcfg_data_t ahbcfg = {.d32 = 0 };
+       gusbcfg_data_t usbcfg = {.d32 = 0 };
+       gi2cctl_data_t i2cctl = {.d32 = 0 };
+
+       DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
+       /* Common Initialization */
+       usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+
+       /* Program the ULPI External VBUS bit if needed */
+       usbcfg.b.ulpi_ext_vbus_drv =
+           (core_if->core_params->phy_ulpi_ext_vbus ==
+            DWC_PHY_ULPI_EXTERNAL_VBUS) ? 1 : 0;
+
+       /* Set external TS Dline pulsing */
+       usbcfg.b.term_sel_dl_pulse =
+           (core_if->core_params->ts_dline == 1) ? 1 : 0;
+       DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+
+       /* Reset the Controller */
+       dwc_otg_core_reset(core_if);
+
+       core_if->adp_enable = core_if->core_params->adp_supp_enable;
+       core_if->power_down = core_if->core_params->power_down;
+
+       /* Initialize parameters from Hardware configuration registers. */
+       dev_if->num_in_eps = calc_num_in_eps(core_if);
+       dev_if->num_out_eps = calc_num_out_eps(core_if);
+
+       DWC_DEBUGPL(DBG_CIL, "num_dev_perio_in_ep=%d\n",
+                   core_if->hwcfg4.b.num_dev_perio_in_ep);
+
+       for (i = 0; i < core_if->hwcfg4.b.num_dev_perio_in_ep; i++) {
+               dev_if->perio_tx_fifo_size[i] =
+                   DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
+               DWC_DEBUGPL(DBG_CIL, "Periodic Tx FIFO SZ #%d=0x%0x\n",
+                           i, dev_if->perio_tx_fifo_size[i]);
+       }
+
+       for (i = 0; i < core_if->hwcfg4.b.num_in_eps; i++) {
+               dev_if->tx_fifo_size[i] =
+                   DWC_READ_REG32(&global_regs->dtxfsiz[i]) >> 16;
+               DWC_DEBUGPL(DBG_CIL, "Tx FIFO SZ #%d=0x%0x\n",
+                           i, dev_if->tx_fifo_size[i]);
+       }
+
+       core_if->total_fifo_size = core_if->hwcfg3.b.dfifo_depth;
+       core_if->rx_fifo_size = DWC_READ_REG32(&global_regs->grxfsiz);
+       core_if->nperio_tx_fifo_size =
+           DWC_READ_REG32(&global_regs->gnptxfsiz) >> 16;
+
+       DWC_DEBUGPL(DBG_CIL, "Total FIFO SZ=%d\n", core_if->total_fifo_size);
+       DWC_DEBUGPL(DBG_CIL, "Rx FIFO SZ=%d\n", core_if->rx_fifo_size);
+       DWC_DEBUGPL(DBG_CIL, "NP Tx FIFO SZ=%d\n",
+                   core_if->nperio_tx_fifo_size);
+
+       /* This programming sequence needs to happen in FS mode before any other
+        * programming occurs */
+       if ((core_if->core_params->speed == DWC_SPEED_PARAM_FULL) &&
+           (core_if->core_params->phy_type == DWC_PHY_TYPE_PARAM_FS)) {
+               /* If FS mode with FS PHY */
+
+               /* core_init() is now called on every switch so only call the
+                * following for the first time through. */
+               if (!core_if->phy_init_done) {
+                       core_if->phy_init_done = 1;
+                       DWC_DEBUGPL(DBG_CIL, "FS_PHY detected\n");
+                       usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+                       usbcfg.b.physel = 1;
+                       DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+
+                       /* Reset after a PHY select */
+                       dwc_otg_core_reset(core_if);
+               }
+
+               /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
+                * do this on HNP Dev/Host mode switches (done in dev_init and
+                * host_init). */
+               if (dwc_otg_is_host_mode(core_if)) {
+                       init_fslspclksel(core_if);
+               } else {
+                       init_devspd(core_if);
+               }
+
+               if (core_if->core_params->i2c_enable) {
+                       DWC_DEBUGPL(DBG_CIL, "FS_PHY Enabling I2c\n");
+                       /* Program GUSBCFG.OtgUtmifsSel to I2C */
+                       usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+                       usbcfg.b.otgutmifssel = 1;
+                       DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+
+                       /* Program GI2CCTL.I2CEn */
+                       i2cctl.d32 = DWC_READ_REG32(&global_regs->gi2cctl);
+                       i2cctl.b.i2cdevaddr = 1;
+                       i2cctl.b.i2cen = 0;
+                       DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
+                       i2cctl.b.i2cen = 1;
+                       DWC_WRITE_REG32(&global_regs->gi2cctl, i2cctl.d32);
+               }
+
+       } /* endif speed == DWC_SPEED_PARAM_FULL */
+       else {
+               /* High speed PHY. */
+               if (!core_if->phy_init_done) {
+                       core_if->phy_init_done = 1;
+                       /* HS PHY parameters.  These parameters are preserved
+                        * during soft reset so only program the first time.  Do
+                        * a soft reset immediately after setting phyif.  */
+
+                       if (core_if->core_params->phy_type == 2) {
+                               /* ULPI interface */
+                               usbcfg.b.ulpi_utmi_sel = 1;
+                               usbcfg.b.phyif = 0;
+                               usbcfg.b.ddrsel =
+                                   core_if->core_params->phy_ulpi_ddr;
+                       } else if (core_if->core_params->phy_type == 1) {
+                               /* UTMI+ interface */
+                               usbcfg.b.ulpi_utmi_sel = 0;
+                               if (core_if->core_params->phy_utmi_width == 16) {
+                                       usbcfg.b.phyif = 1;
+
+                               } else {
+                                       usbcfg.b.phyif = 0;
+                               }
+                       } else {
+                               DWC_ERROR("FS PHY TYPE\n");
+                       }
+                       DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+                       /* Reset after setting the PHY parameters */
+                       dwc_otg_core_reset(core_if);
+               }
+       }
+
+       if ((core_if->hwcfg2.b.hs_phy_type == 2) &&
+           (core_if->hwcfg2.b.fs_phy_type == 1) &&
+           (core_if->core_params->ulpi_fs_ls)) {
+               DWC_DEBUGPL(DBG_CIL, "Setting ULPI FSLS\n");
+               usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+               usbcfg.b.ulpi_fsls = 1;
+               usbcfg.b.ulpi_clk_sus_m = 1;
+               DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+       } else {
+               usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+               usbcfg.b.ulpi_fsls = 0;
+               usbcfg.b.ulpi_clk_sus_m = 0;
+               DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+       }
+
+       /* Program the GAHBCFG Register. */
+       switch (core_if->hwcfg2.b.architecture) {
+
+       case DWC_SLAVE_ONLY_ARCH:
+               DWC_DEBUGPL(DBG_CIL, "Slave Only Mode\n");
+               ahbcfg.b.nptxfemplvl_txfemplvl =
+                   DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+               ahbcfg.b.ptxfemplvl = DWC_GAHBCFG_TXFEMPTYLVL_HALFEMPTY;
+               core_if->dma_enable = 0;
+               core_if->dma_desc_enable = 0;
+               break;
+
+       case DWC_EXT_DMA_ARCH:
+               DWC_DEBUGPL(DBG_CIL, "External DMA Mode\n");
+               {
+                       uint8_t brst_sz = core_if->core_params->dma_burst_size;
+                       ahbcfg.b.hburstlen = 0;
+                       while (brst_sz > 1) {
+                               ahbcfg.b.hburstlen++;
+                               brst_sz >>= 1;
+                       }
+               }
+               core_if->dma_enable = (core_if->core_params->dma_enable != 0);
+               core_if->dma_desc_enable =
+                   (core_if->core_params->dma_desc_enable != 0);
+               break;
+
+       case DWC_INT_DMA_ARCH:
+               DWC_DEBUGPL(DBG_CIL, "Internal DMA Mode\n");
+               /* Old value was DWC_GAHBCFG_INT_DMA_BURST_INCR - done for
+                  Host mode ISOC in issue fix - vahrama */
+               ahbcfg.b.hburstlen = DWC_GAHBCFG_INT_DMA_BURST_INCR16;
+               core_if->dma_enable = (core_if->core_params->dma_enable != 0);
+               core_if->dma_desc_enable =
+                   (core_if->core_params->dma_desc_enable != 0);
+               break;
+
+       }
+       if (core_if->dma_enable) {
+               if (core_if->dma_desc_enable) {
+                       DWC_PRINTF("Using Descriptor DMA mode\n");
+               } else {
+                       DWC_PRINTF("Using Buffer DMA mode\n");
+               }
+       } else {
+               DWC_PRINTF("Using Slave mode\n");
+               core_if->dma_desc_enable = 0;
+       }
+
+       if (core_if->core_params->ahb_single) {
+               ahbcfg.b.ahbsingle = 1;
+       }
+
+       ahbcfg.b.dmaenable = core_if->dma_enable;
+       DWC_WRITE_REG32(&global_regs->gahbcfg, ahbcfg.d32);
+
+       core_if->en_multiple_tx_fifo = core_if->hwcfg4.b.ded_fifo_en;
+
+       core_if->pti_enh_enable = core_if->core_params->pti_enable != 0;
+       core_if->multiproc_int_enable = core_if->core_params->mpi_enable;
+       DWC_PRINTF("Periodic Transfer Interrupt Enhancement - %s\n",
+                  ((core_if->pti_enh_enable) ? "enabled" : "disabled"));
+       DWC_PRINTF("Multiprocessor Interrupt Enhancement - %s\n",
+                  ((core_if->multiproc_int_enable) ? "enabled" : "disabled"));
+
+       /*
+        * Program the GUSBCFG register.
+        */
+       usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
+
+       switch (core_if->hwcfg2.b.op_mode) {
+       case DWC_MODE_HNP_SRP_CAPABLE:
+               usbcfg.b.hnpcap = (core_if->core_params->otg_cap ==
+                                  DWC_OTG_CAP_PARAM_HNP_SRP_CAPABLE);
+               usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
+                                  DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
+               break;
+
+       case DWC_MODE_SRP_ONLY_CAPABLE:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
+                                  DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
+               break;
+
+       case DWC_MODE_NO_HNP_SRP_CAPABLE:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = 0;
+               break;
+
+       case DWC_MODE_SRP_CAPABLE_DEVICE:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
+                                  DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
+               break;
+
+       case DWC_MODE_NO_SRP_CAPABLE_DEVICE:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = 0;
+               break;
+
+       case DWC_MODE_SRP_CAPABLE_HOST:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = (core_if->core_params->otg_cap !=
+                                  DWC_OTG_CAP_PARAM_NO_HNP_SRP_CAPABLE);
+               break;
+
+       case DWC_MODE_NO_SRP_CAPABLE_HOST:
+               usbcfg.b.hnpcap = 0;
+               usbcfg.b.srpcap = 0;
+               break;
+       }
+
+       DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
+
+#ifdef CONFIG_USB_DWC_OTG_LPM
+       if (core_if->core_params->lpm_enable) {
+               glpmcfg_data_t lpmcfg = {.d32 = 0 };
+
+               /* To enable LPM support set lpm_cap_en bit */
+               lpmcfg.b.lpm_cap_en = 1;
+
+               /* Make AppL1Res ACK */
+               lpmcfg.b.appl_resp = 1;
+
+               /* Retry 3 times */
+               lpmcfg.b.retry_count = 3;
+
+               DWC_MODIFY_REG32(&core_if->core_global_regs->glpmcfg,
+                                0, lpmcfg.d32);
+
+       }
+#endif
+       if (core_if->core_params->ic_usb_cap) {
+               gusbcfg_data_t gusbcfg = {.d32 = 0 };
+               gusbcfg.b.ic_usb_cap = 1;
+               DWC_MODIFY_REG32(&core_if->core_global_regs->gusbcfg,
+                                0, gusbcfg.d32);
+       }
+       {
+               gotgctl_data_t gotgctl = {.d32 = 0 };
+               gotgctl.b.otgver = core_if->core_params->otg_ver;
+               DWC_MODIFY_REG32(&core_if->core_global_regs->gotgctl, 0,
+                                gotgctl.d32);
+               /* Set OTG version supported */
+               core_if->otg_ver = core_if->core_params->otg_ver;
+               DWC_PRINTF("OTG VER PARAM: %d, OTG VER FLAG: %d\n",
+                          core_if->core_params->otg_ver, core_if->otg_ver);
+       }
+
+       /* Enable common interrupts */
+       dwc_otg_enable_common_interrupts(core_if);
+
+       /* Do device or host intialization based on mode during PCD
+        * and HCD initialization  */
+       if (dwc_otg_is_host_mode(core_if)) {
+               DWC_PRINTF("^^^^^^^^^^^^^^^^^^Host Mode\n" );
+               core_if->op_state = A_HOST;
+       } else {
+               DWC_PRINTF("^^^^^^^^^^^^^^^^^Device Mode\n" );
+               core_if->op_state = B_PERIPHERAL;
+#ifdef DWC_DEVICE_ONLY
+               dwc_otg_core_dev_init(core_if);
+#endif
+       }
+}
 /**
  * This function initializes the DWC_otg controller registers and
  * prepares the core for device mode or host mode operation.
@@ -1206,7 +1523,7 @@ static uint32_t calc_num_out_eps(dwc_otg_core_if_t * core_if)
  * @param core_if Programming view of the DWC_otg controller
  *
  */
-void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
+void dwc_otg_core_init_no_reset(dwc_otg_core_if_t * core_if)
 {
        int i = 0;
        dwc_otg_core_global_regs_t *global_regs = core_if->core_global_regs;
@@ -1216,7 +1533,6 @@ void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
        gi2cctl_data_t i2cctl = {.d32 = 0 };
 
        DWC_DEBUGPL(DBG_CILV, "dwc_otg_core_init(%p)\n", core_if);
-
        /* Common Initialization */
        usbcfg.d32 = DWC_READ_REG32(&global_regs->gusbcfg);
 
@@ -1231,7 +1547,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
        DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
 
        /* Reset the Controller */
-       dwc_otg_core_reset(core_if);
+//     dwc_otg_core_reset(core_if);
 
        core_if->adp_enable = core_if->core_params->adp_supp_enable;
        core_if->power_down = core_if->core_params->power_down;
@@ -1283,7 +1599,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
                        DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
 
                        /* Reset after a PHY select */
-                       dwc_otg_core_reset(core_if);
+//                     dwc_otg_core_reset(core_if);
                }
 
                /* Program DCFG.DevSpd or HCFG.FSLSPclkSel to 48Mhz in FS.      Also
@@ -1340,7 +1656,7 @@ void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
                        }
                        DWC_WRITE_REG32(&global_regs->gusbcfg, usbcfg.d32);
                        /* Reset after setting the PHY parameters */
-                       dwc_otg_core_reset(core_if);
+//                     dwc_otg_core_reset(core_if);
                }
        }
 
@@ -1514,10 +1830,10 @@ void dwc_otg_core_init(dwc_otg_core_if_t * core_if)
        /* Do device or host intialization based on mode during PCD
         * and HCD initialization  */
        if (dwc_otg_is_host_mode(core_if)) {
-               DWC_DEBUGPL(DBG_ANY, "Host Mode\n");
+               DWC_PRINTF("^^^^^^^^^^^^^^^^^^Host Mode\n" );
                core_if->op_state = A_HOST;
        } else {
-               DWC_DEBUGPL(DBG_ANY, "Device Mode\n");
+               DWC_PRINTF("^^^^^^^^^^^^^^^^^Device Mode\n" );
                core_if->op_state = B_PERIPHERAL;
 #ifdef DWC_DEVICE_ONLY
                dwc_otg_core_dev_init(core_if);
index 0c01dba21e32d6b082b5171418eb59deb4b71a10..6b69bd9689195044a1c43a7104de4bb493de72eb 100755 (executable)
@@ -52,6 +52,7 @@ typedef struct dwc_otg_core_if dwc_otg_core_if_t;
 
 extern dwc_otg_core_if_t *dwc_otg_cil_init(const uint32_t * _reg_base_addr);
 extern void dwc_otg_core_init(dwc_otg_core_if_t * _core_if);
+extern void dwc_otg_core_init_no_reset(dwc_otg_core_if_t * _core_if);
 extern void dwc_otg_cil_remove(dwc_otg_core_if_t * _core_if);
 
 extern void dwc_otg_enable_global_interrupts(dwc_otg_core_if_t * _core_if);
index 107d8950552f4f549b0fbe71ab885fca5487cedb..2afbb32cfc734ca219c5118e188f12cb9c4f5dea 100755 (executable)
@@ -1126,8 +1126,10 @@ static int host20_driver_probe(struct platform_device *_dev)
 
        /*
         * Initialize the DWC_otg core.
+        * In order to reduce the time of initialization,
+        * we do core soft reset after connection detected.
         */
-       dwc_otg_core_init(dwc_otg_device->core_if);
+       dwc_otg_core_init_no_reset(dwc_otg_device->core_if);
                
        /*
         * Initialize the HCD
@@ -1144,8 +1146,14 @@ static int host20_driver_probe(struct platform_device *_dev)
         * handlers are installed if there is no ADP support else 
         * perform initial actions required for Internal ADP logic.
         */
-       if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if))     
-               dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
+       if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if))     {
+               if( pldata->phy_status == USB_PHY_ENABLED ){
+                       pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+                       udelay(3);
+                       pldata->clock_enable( pldata, 0);
+               }
+//             dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
+       }
        else
                dwc_otg_adp_start(dwc_otg_device->core_if, 
                                                        dwc_otg_is_host_mode(dwc_otg_device->core_if));
@@ -1368,8 +1376,10 @@ static int otg20_driver_probe(struct platform_device *_dev)
 
        if(pldata->phy_suspend)
                pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+
        if(pldata->dwc_otg_uart_mode)
                pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
+
        if(pldata->soft_reset)
                pldata->soft_reset();
        /*end todo*/
@@ -1477,8 +1487,10 @@ static int otg20_driver_probe(struct platform_device *_dev)
 
        /*
         * Initialize the DWC_otg core.
+        * In order to reduce the time of initialization,
+        * we do core soft reset after connection detected.
         */
-       dwc_otg_core_init(dwc_otg_device->core_if);
+       dwc_otg_core_init_no_reset(dwc_otg_device->core_if);
        dwc_otg_device->core_if->usb_mode = 0;// TODO: Can be read from Device-Tree
 #ifndef DWC_HOST_ONLY
        /*
@@ -1507,8 +1519,14 @@ static int otg20_driver_probe(struct platform_device *_dev)
         * handlers are installed if there is no ADP support else 
         * perform initial actions required for Internal ADP logic.
         */
-       if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if))     
-               dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
+       if (!dwc_otg_get_param_adp_enable(dwc_otg_device->core_if)){
+               if( pldata->phy_status == USB_PHY_ENABLED ){
+                       pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
+                       udelay(3);
+                       pldata->clock_enable( pldata, 0);
+               }
+//             dwc_otg_enable_global_interrupts(dwc_otg_device->core_if);
+       }
        else
                dwc_otg_adp_start(dwc_otg_device->core_if, 
                                                        dwc_otg_is_host_mode(dwc_otg_device->core_if));
index 9fa1312c63d93bbc15ac86bf1c12f5bad6785e58..1ac55659ca4ba9d0fc688e0200ba602d96fca526 100755 (executable)
@@ -899,7 +899,7 @@ int dwc_otg_hcd_init(dwc_otg_hcd_t * hcd, dwc_otg_core_if_t * core_if)
         */
        if (hcd->core_if->dma_enable) {
                hcd->status_buf =
-                   DWC_DMA_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE,
+                   DWC_DMA_ALLOC_ATOMIC(DWC_OTG_HCD_STATUS_BUF_SIZE,
                                  &hcd->status_buf_dma);
        } else {
                hcd->status_buf = DWC_ALLOC(DWC_OTG_HCD_STATUS_BUF_SIZE);
index 5c125e07c020691cbe05b9e2e7fb8e65a46678c0..a5dadd24c980b5c85fd601f543e5b6fef8085392 100755 (executable)
@@ -415,6 +415,22 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
        return;
 }
 
+static void otg20_hcd_connect_detect(unsigned long pdata)
+{
+       dwc_otg_hcd_t *dwc_otg_hcd = (dwc_otg_hcd_t *)pdata;
+       dwc_otg_core_if_t *core_if = dwc_otg_hcd->core_if;
+       struct dwc_otg_platform_data *pldata;
+       pldata = core_if->otg_dev->pldata;
+
+       if( pldata->phy_status == USB_PHY_SUSPEND){
+               pldata->clock_enable(pldata, 1);
+               pldata->phy_suspend(pldata, USB_PHY_ENABLED);
+       }
+       dwc_otg_core_init(core_if);
+       dwc_otg_enable_global_interrupts(core_if);
+       cil_hcd_start(core_if);
+}
+
 /**
  * Initializes the HCD. This function allocates memory for and initializes the
  * static parts of the usb_hcd and dwc_otg_hcd structures. It also registers the
@@ -501,7 +517,12 @@ int otg20_hcd_init( struct platform_device *_dev )
 
        dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
        dwc_otg_hcd->host_enabled = 1;
-
+       if(dwc_otg_is_host_mode(otg_dev->core_if)){
+               dwc_otg_hcd->connect_detect_timer.function = otg20_hcd_connect_detect;
+               dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
+               init_timer( &dwc_otg_hcd->connect_detect_timer);
+               mod_timer(&dwc_otg_hcd->connect_detect_timer, jiffies+(HZ<<2));
+       }
        return 0;
 
 error2:
@@ -596,8 +617,8 @@ int host20_hcd_init( struct platform_device *_dev )
 
        dwc_otg_hcd_set_priv_data(dwc_otg_hcd, hcd);
 
-       dwc_otg_hcd->host_enabled = 1;
-       dwc_otg_hcd->host_setenable = 1;
+       dwc_otg_hcd->host_enabled = 2;
+       dwc_otg_hcd->host_setenable = 2;
        dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
        dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
        init_timer( &dwc_otg_hcd->connect_detect_timer);
index a8897cb12758f3b84f3e86e8856c80201f7f62ba..dfe28d329fadc7ca2109139a9fb25915ce4dddb4 100755 (executable)
@@ -1156,7 +1156,7 @@ dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if)
         */
        if (GET_CORE_IF(pcd)->dma_enable) {
                pcd->setup_pkt =
-                   DWC_DMA_ALLOC(sizeof(*pcd->setup_pkt) * 5,
+                   DWC_DMA_ALLOC_ATOMIC(sizeof(*pcd->setup_pkt) * 5,
                                  &pcd->setup_pkt_dma_handle);
                if (pcd->setup_pkt == NULL) {
                        DWC_FREE(pcd);
@@ -1164,7 +1164,7 @@ dwc_otg_pcd_t *dwc_otg_pcd_init(dwc_otg_core_if_t * core_if)
                }
 
                pcd->status_buf =
-                   DWC_DMA_ALLOC(sizeof(uint16_t),
+                   DWC_DMA_ALLOC_ATOMIC(sizeof(uint16_t),
                                  &pcd->status_buf_dma_handle);
                if (pcd->status_buf == NULL) {
                        DWC_DMA_FREE(sizeof(*pcd->setup_pkt) * 5,
index f763e69b54201a589b5108bac22eb58700bcbad1..83e3d4c359496d10cffa51356a191731c3cad8d0 100755 (executable)
@@ -1565,16 +1565,17 @@ static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
                }
 
                if( pldata->phy_status == USB_PHY_ENABLED ){
+                       /* release wake lock */
+                       dwc_otg_msc_unlock(_pcd);
                        /* no vbus detect here , close usb phy  */
                        pldata->phy_suspend(pldata, USB_PHY_SUSPEND);
                        udelay(3);
                        pldata->clock_enable( pldata, 0);
-                       /* usb phy bypass to uart mode  */
-                       if( pldata->dwc_otg_uart_mode != NULL )
-                               pldata->dwc_otg_uart_mode( pldata, PHY_UART_MODE);
-                       /* release wake lock */
-                       dwc_otg_msc_unlock(_pcd);
                }
+
+               /* usb phy bypass to uart mode  */
+               if( pldata->dwc_otg_uart_mode != NULL )
+                       pldata->dwc_otg_uart_mode( pldata, PHY_UART_MODE);
        }
 
        schedule_delayed_work(&_pcd->check_vbus_work, HZ);
@@ -1583,15 +1584,15 @@ static void dwc_otg_pcd_check_vbus_work( struct work_struct *work )
        return;
     
 connect:
-       if(_pcd->conn_status==0)
-               dwc_otg_msc_lock(_pcd);
-
        if( pldata->phy_status)
        {
                pldata->clock_enable(pldata, 1);
                pldata->phy_suspend(pldata, USB_PHY_ENABLED);
        }
 
+       if(_pcd->conn_status==0)
+               dwc_otg_msc_lock(_pcd);
+
        schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 8 jiffies */
        schedule_delayed_work(&_pcd->check_vbus_work, (HZ<<2));
        local_irq_restore(flags);
@@ -1644,7 +1645,6 @@ static void dwc_otg_pcd_work_init(dwc_otg_pcd_t *pcd, struct platform_device *de
                        pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
                }else{
                        //usb phy bypass to uart mode
-                       pldata->phy_suspend(pldata,USB_PHY_SUSPEND);
                        pldata->dwc_otg_uart_mode(pldata, PHY_UART_MODE);
                }
 #endif