USB: add usb soft reset.
authorwlf <wulf@rock-chips.com>
Wed, 9 Apr 2014 09:04:22 +0000 (17:04 +0800)
committerwlf <wulf@rock-chips.com>
Wed, 9 Apr 2014 09:04:22 +0000 (17:04 +0800)
drivers/usb/dwc_otg_310/dwc_otg_driver.c
drivers/usb/dwc_otg_310/dwc_otg_pcd_linux.c
drivers/usb/dwc_otg_310/usbdev_rk.h
drivers/usb/dwc_otg_310/usbdev_rk32.c

index 8095bf8524721068744610ef33d36dce9eebf807..47c2f48cfc62d037f48c3a405f8f98316cb13ee3 100755 (executable)
@@ -1381,8 +1381,13 @@ static int otg20_driver_probe(struct platform_device *_dev)
        if(pldata->dwc_otg_uart_mode)
                pldata->dwc_otg_uart_mode(pldata, PHY_USB_MODE);
 
+       /* do reset later, because reset need about
+        * 100ms to ensure otg id state change.
+        */
+       /*
        if(pldata->soft_reset)
                pldata->soft_reset();
+       */
        /*end todo*/
 
        res_base=platform_get_resource(_dev, IORESOURCE_MEM, 0);
index 443b839339faa1f0a67c0aa8f3dccd8992e1c311..23bc90f0e50914e3d393942efdc36d919fb0bb04 100755 (executable)
@@ -1470,13 +1470,16 @@ static void dwc_phy_reconnect(struct work_struct *work)
        dwc_otg_core_if_t *core_if;
        gotgctl_data_t    gctrl;
        dctl_data_t dctl = {.d32=0};
+       struct dwc_otg_platform_data *pldata;
 
        pcd = container_of(work, dwc_otg_pcd_t, reconnect.work);
+       pldata = pcd->otg_dev->pldata;
        core_if = GET_CORE_IF(pcd);
        gctrl.d32 = DWC_READ_REG32( &core_if->core_global_regs->gotgctl );
 
        if(gctrl.b.bsesvld){
                pcd->conn_status++;
+               pldata->soft_reset();
                dwc_pcd_reset(pcd);
                /*
                 * Enable the global interrupt after all the interrupt
index 56aa975f61a2feb55315fd21500ec5fd74189d95..021548a83aaa5574273cc84d46705270030a57f6 100755 (executable)
@@ -18,7 +18,7 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
-
+#include <linux/rockchip/cru.h>
 
 #include "usbdev_grf_regs.h"
 #include "usbdev_bc.h"
index be90b9982d29e260f11bd244e0d9b8afd440b56a..290e554330b9c452373b78987f55cfc77683461b 100755 (executable)
@@ -43,6 +43,15 @@ static void usb20otg_phy_suspend(void* pdata, int suspend)
 
 static void usb20otg_soft_reset(void)
 {
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTG_H, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGPHY, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGC, true);
+       udelay(5);
+
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTG_H, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGPHY, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBOTGC, false);
+       mdelay(2);
 }
 
 static void usb20otg_clock_init(void* pdata)
@@ -188,6 +197,15 @@ static void usb20host_phy_suspend(void* pdata, int suspend)
 
 static void usb20host_soft_reset(void)
 {
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1_H, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1PHY, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1C, true);
+       udelay(5);
+
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1_H, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1PHY, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST1C, false);
+       mdelay(2);
 }
 
 static void usb20host_clock_init(void* pdata)
@@ -370,6 +388,21 @@ static void rk_hsic_clock_enable(void* pdata, int enable)
 
 static void rk_hsic_soft_reset(void)
 {
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC_AUX, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSICPHY, true);
+       udelay(5);
+
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSIC_AUX, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_HSICPHY, false);
+       mdelay(2);
+
+       /* HSIC per-port reset */
+       control_usb->grf_uoc3_base->CON0 = ((1<<10)<<16)|(1<<10);
+       udelay(2);
+       control_usb->grf_uoc3_base->CON0 = ((1<<10)<<16)|(0<<10);
+       udelay(2);
 }
 
 struct rkehci_platform_data rkhsic_pdata_rk3288 = {
@@ -435,7 +468,17 @@ static void rk_ehci_clock_enable(void* pdata, int enable)
 
 static void rk_ehci_soft_reset(void)
 {
-
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0_H, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0PHY, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0C, true);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USB_HOST0, true);
+       udelay(5);
+
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0_H, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0PHY, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USBHOST0C, false);
+       rk3288_cru_set_soft_reset(RK3288_SOFT_RST_USB_HOST0, false);
+       mdelay(2);
 }
 
 struct rkehci_platform_data rkehci_pdata_rk3288 = {