merge rk2928 usb
authoryangkai <yk@rock-chips.com>
Fri, 17 Aug 2012 08:20:17 +0000 (16:20 +0800)
committeryangkai <yk@rock-chips.com>
Fri, 17 Aug 2012 08:20:17 +0000 (16:20 +0800)
drivers/usb/dwc_otg/dwc_otg_cil.c
drivers/usb/dwc_otg/dwc_otg_driver.c
drivers/usb/dwc_otg/dwc_otg_hcd.c
drivers/usb/dwc_otg/dwc_otg_pcd.c
drivers/usb/dwc_otg/linux/dwc_otg_plat.h

index 9f44adc2796fb97ee8578e76e766f9bf04886ee0..406aad10392897a350d98661a4f666da78345d0b 100755 (executable)
@@ -731,6 +731,16 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );  //ep5 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );  //ep7 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );  //ep9 tx fifo
+#endif
+#ifdef CONFIG_ARCH_RK2928  //@lyz the same with RK30
+    /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
+    dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
+    dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 );             //ep0 tx fifo 
+    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 );   //ep1 tx fifo 256*4Byte
+    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );   //ep3 tx fifo 128*4Byte
+    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );   //ep5 tx fifo 128*4Byte
+    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 );   //ep7 tx fifo 128*4Byte
+    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 );   //ep9 tx fifo 16*4Byte
 #endif
        if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
        {
index 5efdecdd4705fb3f86aeab2f1813ca2ab2eb5ae9..e7bdd6d2d970ddec4877d1a2b29b3f80b1b7d840 100755 (executable)
@@ -1203,6 +1203,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
 #ifdef CONFIG_ARCH_RK30
     unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2);
 #endif
+#ifdef CONFIG_ARCH_RK2928
+    unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5);
+#endif
     
 #ifdef CONFIG_ARCH_RK29   
     regval = * otg_phy_con1; 
@@ -1291,6 +1294,35 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
     clk_disable(phyclk);
     clk_disable(ahbclk);
 #endif
+#endif
+//need to be checked @wlf
+#ifdef CONFIG_ARCH_RK2928                
+#ifndef CONFIG_USB20_HOST
+    otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON5);
+    /*
+     * disable usb host 2.0 phy if not support
+     */
+    phyclk = clk_get(NULL, "otgphy1");
+    if (IS_ERR(phyclk)) {
+            retval = PTR_ERR(phyclk);
+            DWC_ERROR("can't get USBPHY1 clock\n");
+           goto fail;
+    }
+    clk_enable(phyclk);
+    
+    ahbclk = clk_get(NULL, "hclk_otg1");
+    if (IS_ERR(ahbclk)) {
+            retval = PTR_ERR(ahbclk);
+            DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
+           goto fail;
+    }
+    clk_enable(ahbclk);
+    
+    *otg_phy_con = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16);   // enter suspend.
+    udelay(3);
+    clk_disable(phyclk);
+    clk_disable(ahbclk);
+#endif
 #endif
        dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
        
@@ -1385,6 +1417,42 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
        dwc_otg_device->phyclk = phyclk;
        dwc_otg_device->ahbclk = ahbclk;
 #endif
+//need to be checked @wlf
+#if 0//def CONFIG_ARCH_RK2928    
+    otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5);
+        cru_set_soft_reset(SOFT_RST_USBPHY0, true);
+       cru_set_soft_reset(SOFT_RST_OTGC0, true);
+       cru_set_soft_reset(SOFT_RST_USBOTG0, true);
+    udelay(1);
+       
+       cru_set_soft_reset(SOFT_RST_USBOTG0, false);
+       cru_set_soft_reset(SOFT_RST_OTGC0, false);
+       cru_set_soft_reset(SOFT_RST_USBPHY0, false);
+
+    phyclk = clk_get(NULL, "otgphy0");
+    if (IS_ERR(phyclk)) {
+            retval = PTR_ERR(phyclk);
+            DWC_ERROR("can't get USBPHY0 clock\n");
+           goto fail;
+    }
+    clk_enable(phyclk);
+    
+    ahbclk = clk_get(NULL, "hclk_otg0");
+    if (IS_ERR(ahbclk)) {
+            retval = PTR_ERR(ahbclk);
+            DWC_ERROR("can't get USB otg0 ahb bus clock\n");
+           goto fail;
+    }
+    clk_enable(ahbclk);
+    
+       /*
+        * Enable usb phy 0
+        */
+    *otg_phy_con =  (0x01<<16);
+    
+       dwc_otg_device->phyclk = phyclk;
+       dwc_otg_device->ahbclk = ahbclk;
+#endif
        /*
         * Map the DWC_otg Core memory into virtual address space.
         */
@@ -1519,6 +1587,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
 #endif
 #ifdef CONFIG_ARCH_RK30
     USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);    
+#endif
+#ifdef CONFIG_ARCH_RK2928
+    USB_IOMUX_INIT(GPIO3C1_OTG_DRVVBUS_NAME, GPIO3C_OTG_DRVVBUS);    
 #endif
        /*
         * Initialize the HCD
@@ -2057,7 +2128,10 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
     unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);
     *otg_phy_con1 = ((0x01<<2)<<16);    // exit suspend.
 #endif
-        
+#ifdef CONFIG_ARCH_RK2928
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5);
+    *otg_phy_con1 = (0x01<<16);    // exit suspend.
+#endif
     #if 0
     *otg_phy_con1 |= (0x01<<2);
     *otg_phy_con1 |= (0x01<<3);    // exit suspend.
@@ -2084,6 +2158,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
 #ifdef CONFIG_ARCH_RK30  
     *(unsigned int*)(USBGRF_UOC1_CON2+4) = ((1<<5)|((1<<5)<<16));
 #endif    
+#ifdef CONFIG_ARCH_RK2928  
+    *(unsigned int*)(USBGRF_UOC1_CON5-4) = ((1<<5)|((1<<5)<<16));
+#endif   
        if (dwc_otg_device == 0) 
        {
                dev_err(dev, "kmalloc of dwc_otg_device failed\n");
@@ -2108,6 +2185,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
 #ifdef CONFIG_ARCH_RK30  
     ahbclk = clk_get(NULL, "hclk_otg1");
 #endif    
+#ifdef CONFIG_ARCH_RK2928
+    ahbclk = clk_get(NULL, "hclk_otg1");    //need to be checked @wlf
+#endif 
     if (IS_ERR(ahbclk)) {
             retval = PTR_ERR(ahbclk);
             DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
@@ -2213,15 +2293,6 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
 #endif    
 #ifdef CONFIG_ARCH_RK30
     USB_IOMUX_INIT(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);    
-#ifdef CONFIG_MACH_RK30_DS1001B
-    USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_GPIO0A5); 
-    if(gpio_request(RK30_PIN0_PA5,"host_drv")<0){
-        DWC_ERROR("request of host power control failed\n");
-        gpio_free(RK30_PIN0_PA5);
-    }
-    gpio_direction_output(RK30_PIN0_PA5, GPIO_HIGH);
-    gpio_set_value(RK30_PIN0_PA5, GPIO_HIGH);
-#endif
 #endif
        /*
         * Initialize the DWC_otg core.
@@ -2246,9 +2317,15 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
 #ifndef CONFIG_USB20_HOST_EN
     clk_disable(phyclk);
     clk_disable(ahbclk);
+#if defined(CONFIG_ARCH_RK29)   
     otgreg &= ~(0x01<<14);    // suspend.
-    otgreg |= (0x01<<13);     // software control
+    otgreg |= (0x01<<13);     // software control enable
     *otg_phy_con1 = otgreg;
+#elif defined(CONFIG_ARCH_RK30)
+    *otg_phy_con1 = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16);   // enter suspend.
+#elif defined(CONFIG_ARCH_RK2928)
+    *otg_phy_con1 = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16);   // enter suspend.
+#endif
 #endif
        return 0;
 
index bef6e0db01d9d8dc8eac6f668e801430c09174e2..b2fb7519f5b67cd512bda9441fac0b3edef666e1 100755 (executable)
@@ -69,8 +69,10 @@ static int dwc_otg_hcd_suspend(struct usb_hcd *hcd)
        return 0;
     }
     hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+#ifdef CONFIG_USB_SUSPEND    
     if((!dwc_otg_hcd->host_enabled)||(!hprt0.b.prtena))
         return 0;
+#endif        
     DWC_PRINT("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
     if(hprt0.b.prtconnsts)  // usb device connected
     {
@@ -128,8 +130,10 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
        DWC_PRINT("%s, usb device mode\n", __func__);
        return 0;
     }
+#ifdef CONFIG_USB_SUSPEND    
     if(!dwc_otg_hcd->host_enabled)
         return 0;
+#endif
     #ifndef CONFIG_DWC_REMOTE_WAKEUP
     clk_enable(core_if->otg_dev->phyclk);
     clk_enable(core_if->otg_dev->ahbclk);
@@ -149,8 +153,10 @@ static int dwc_otg_hcd_resume(struct usb_hcd *hcd)
     dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
         
     hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+#ifdef CONFIG_USB_SUSPEND    
     if(!hprt0.b.prtena)
         return 0;
+#endif
     DWC_PRINT("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
     if(hprt0.b.prtconnsts)
     {
@@ -617,6 +623,24 @@ static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend)
         udelay(3);
         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
     }
+#endif
+#if 0//def CONFIG_ARCH_RK2928                
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
+    if(exitsuspend && (pcd->phy_suspend == 1)) {
+        clk_enable(pcd->otg_dev->ahbclk);
+        clk_enable(pcd->otg_dev->phyclk);
+        pcd->phy_suspend = 0;
+        *otg_phy_con1 = (0x01<<16);    // exit suspend.
+        DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
+    }
+    if( !exitsuspend && (pcd->phy_suspend == 0)) {
+        pcd->phy_suspend = 1;
+        *otg_phy_con1 = 0x55 |(0x7f<<16);   // enter suspend.
+        udelay(3);
+        clk_disable(pcd->otg_dev->phyclk);
+        clk_disable(pcd->otg_dev->ahbclk);
+        DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
+    }
 #endif
     return suspend;
 }
@@ -663,7 +687,7 @@ static struct tasklet_struct reset_tasklet = {
        .func = reset_tasklet_func,
        .data = 0,
 };
-#ifdef CONFIG_ARCH_RK30
+#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)     
 static void dwc_otg_hcd_enable(struct work_struct *work)
 {
     dwc_otg_hcd_t *dwc_otg_hcd;
@@ -721,7 +745,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
        local_irq_save(flags);
 
 //    DWC_PRINT("%s hprt %x, grfstatus 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
+#ifdef CONFIG_ARCH_RK30
     if(usbgrf_status & (7<<22)){
+#else //CONFIG_ARCH_RK2928
+    if(usbgrf_status & (7<<12)){
+#endif
     // usb device connected
         dwc_otg_hcd->host_setenable = 1;
     }
@@ -732,7 +760,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
     
     }
     if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){
-    DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
+#ifdef CONFIG_ARCH_RK30        
+    DWC_PRINT("%s schedule delaywork 0x%x, 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
+#else //CONFIG_ARCH_RK2928
+    DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<12));
+#endif
     schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 8);
     }
 //    dwc_otg_hcd->connect_detect_timer.expires = jiffies + (HZ<<1); /* 1 s */
@@ -1116,6 +1148,24 @@ static int32_t host20_phy_suspend_cb( void *_p, int suspend)
         udelay(3);
         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
     }
+#endif
+#if 0//def CONFIG_ARCH_RK2928                
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
+    if(exitsuspend && (pcd->phy_suspend == 1)) {
+        clk_enable(pcd->otg_dev->ahbclk);
+        clk_enable(pcd->otg_dev->phyclk);
+        pcd->phy_suspend = 0;
+        *otg_phy_con1 = (0x01<<16);    // exit suspend.
+        DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
+    }
+    if( !exitsuspend && (pcd->phy_suspend == 0)) {
+        pcd->phy_suspend = 1;
+        *otg_phy_con1 = 0x55 |(0x7f<<16);   // enter suspend.
+        udelay(3);
+        clk_disable(pcd->otg_dev->phyclk);
+        clk_disable(pcd->otg_dev->ahbclk);
+        DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
+    }
 #endif
     return suspend;
 }
@@ -1266,7 +1316,7 @@ int __devinit host20_hcd_init(struct device *dev)
                goto error3;
        }
     
-#ifdef CONFIG_ARCH_RK30        
+#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)     
     dwc_otg_hcd->host_setenable = 1;
     dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
     dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
index 6f6d975e09c69a3868b2cc7998308d57e0e634d8..81456fd70dbde150d0c69356fa4b3a3a6345c3ea 100755 (executable)
@@ -189,7 +189,7 @@ void request_nuke( dwc_otg_pcd_ep_t *_ep )
  * This function assigns periodic Tx FIFO to an periodic EP
  * in shared Tx FIFO mode
  */
- #ifdef CONFIG_ARCH_RK30
+ #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
 static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
 {
        uint32_t PerTxMsk = 1;
@@ -218,7 +218,7 @@ static void release_perio_tx_fifo(dwc_otg_core_if_t *core_if, uint32_t fifo_num)
  * This function assigns periodic Tx FIFO to an periodic EP
  * in Dedicated FIFOs mode
  */
-#ifdef CONFIG_ARCH_RK30
+#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
 static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
 {
        uint32_t TxMsk = 1;
@@ -304,7 +304,7 @@ static int dwc_otg_pcd_ep_enable(struct usb_ep *_ep,
 
        if(ep->dwc_ep.is_in)
        {
-#ifndef CONFIG_ARCH_RK29
+#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
                if(!pcd->otg_dev->core_if->en_multiple_tx_fifo)
                {
                        ep->dwc_ep.tx_fifo_num = 0;
@@ -1497,6 +1497,10 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
                         * EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default
                         */
                #ifdef CONFIG_ARCH_RK30
+               if(i == 8)
+                   continue;
+               #endif
+               #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
                if(i == 8)
                    continue;
                #endif
@@ -1558,6 +1562,10 @@ void dwc_otg_pcd_reinit(dwc_otg_pcd_t *_pcd)
                         * EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default
                         */
                #ifdef CONFIG_ARCH_RK30
+               if(i == 9)
+                   continue;
+               #endif
+               #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
                if(i == 9)
                    continue;
                #endif
@@ -1663,7 +1671,25 @@ int dwc_otg20phy_suspend( int exitsuspend )
         DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
     }
 #endif
-    
+#ifdef CONFIG_ARCH_RK2928                
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);
+    if(exitsuspend && (pcd->phy_suspend == 1)) {
+        clk_enable(pcd->otg_dev->ahbclk);
+        clk_enable(pcd->otg_dev->phyclk);
+        pcd->phy_suspend = 0;
+        *otg_phy_con1 = (0x01<<16);    // exit suspend.
+        DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
+    }
+    if( !exitsuspend && (pcd->phy_suspend == 0)) {
+        pcd->phy_suspend = 1;
+       *otg_phy_con1 = 0x55 |(0x7f<<16);   // enter suspend.
+      //  *otg_phy_con1 = 0x1D5 |(0x1ff<<16);   // enter suspend.   enable dm,dp  debug_wlf @2012.8.10
+        udelay(3);
+        clk_disable(pcd->otg_dev->phyclk);
+        clk_disable(pcd->otg_dev->ahbclk);
+        DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
+    }
+#endif
     return pcd->phy_suspend;
 }
 
@@ -1873,6 +1899,69 @@ connect:
     return;
 }
 
+#endif
+#ifdef CONFIG_ARCH_RK2928
+static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
+{
+    dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
+       unsigned long flags;
+    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0½á¹¹Óбä
+
+       local_irq_save(flags);
+    _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
+    if((usbgrf_status &(1<<10)) == 0){  // id low  //@lyz SOC_STATUS0[10] represents id_dig
+    
+        if( _pcd->phy_suspend) 
+             dwc_otg20phy_suspend( 1 );
+    }
+       else if(usbgrf_status & (1<<7)){  //@lyz SOC_STATUS0[7] represents bvalid
+        /* if usb not connect before ,then start connect */
+         if( _pcd->vbus_status == 0 ) {
+            DWC_PRINT("********vbus detect*********************************************\n");
+            dwc_otg_msc_lock(_pcd);
+           _pcd->vbus_status = 1;
+            if(_pcd->conn_en)
+                goto connect;
+            else
+                dwc_otg20phy_suspend( 0 );
+        } 
+        else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
+            DWC_PRINT("********soft reconnect******************************************\n");
+           goto connect;
+        }
+        else if(_pcd->conn_status ==3){
+                       //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
+            dwc_otg_msc_unlock(_pcd);
+            _pcd->conn_status++;
+            if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
+                _pcd->vbus_status = 2;
+        }
+       }else {
+        _pcd->vbus_status = 0;
+        if(_pcd->conn_status)
+        {
+             _pcd->conn_status = 0;
+             dwc_otg_msc_unlock(_pcd);
+        }
+        /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
+        if( _pcd->phy_suspend == 0 ) 
+                /* no vbus detect here , close usb phy  */
+             dwc_otg20phy_suspend( 0 );
+    }
+    add_timer(&_pcd->check_vbus_timer); 
+       local_irq_restore(flags);
+    return;
+
+connect:
+    if( _pcd->phy_suspend  == 1 )
+         dwc_otg20phy_suspend( 1 );
+    schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
+     _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
+    add_timer(&_pcd->check_vbus_timer); 
+       local_irq_restore(flags);
+    return;
+}
+
 #endif
 #ifdef CONFIG_ARCH_RK29
 /*
@@ -1980,6 +2069,56 @@ out:
     return bus_status;
 }
 
+EXPORT_SYMBOL(dwc_otg_check_dpdm);
+#endif
+#ifdef CONFIG_ARCH_RK2928
+int dwc_otg_check_dpdm(void)
+{
+       static uint8_t * reg_base = 0;
+    volatile unsigned int * otg_dctl;
+    volatile unsigned int * otg_gotgctl;
+    volatile unsigned int * otg_hprt0;
+    int bus_status = 0;
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5
+    
+    // softreset & clockgate //@lyz modify RK2928_CRU_BASE
+    *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate
+    udelay(3);
+    *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate
+    dsb();
+    *(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate
+    *(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate
+    *(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16);    // hclk usb clkgate//@lyz to be check
+    
+    // exit phy suspend 
+        *otg_phy_con1 = ((0x01<<0)<<16);    // exit suspend.@lyz
+    
+    // soft connect
+    if(reg_base == 0){
+        reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz
+        if(!reg_base){
+            bus_status = -1;
+            goto out;
+        }
+    }
+    mdelay(105);
+    printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
+        reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
+    otg_dctl = (unsigned int * )(reg_base+0x804);
+    otg_gotgctl = (unsigned int * )(reg_base);
+    otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
+    if(*otg_gotgctl &(1<<19)){
+        bus_status = 1;
+        *otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode
+        mdelay(50);    // delay about 10ms
+    // check dp,dm
+        if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10] 
+            bus_status = 2;
+    }
+out:
+    return bus_status;
+}
+
 EXPORT_SYMBOL(dwc_otg_check_dpdm);
 #endif
 void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd )
index e3f7d6e996404319a6a68e389cbdd8c9e284f3f0..1fa1f5c886a6d97a39e7605fcd9736d1d8d6f6e8 100755 (executable)
 #define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
 #endif
 
+#ifdef CONFIG_ARCH_RK2928
+#include <mach/iomux.h>
+#define GRF_REG_BASE RK2928_GRF_BASE
+#define USBOTG_SIZE    RK2928_USBOTG20_SIZE
+#define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0x14c)
+#define USBGRF_UOC0_CON5       (GRF_REG_BASE+0x17c)
+#define USBGRF_UOC1_CON5       (GRF_REG_BASE+0x194)
+#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
+#endif
 /**
  * @file 
  *