RK2928 usb hcd modified
authorwlf <wlf@fs-server.(none)>
Mon, 30 Jul 2012 03:28:35 +0000 (11:28 +0800)
committerwlf <wlf@fs-server.(none)>
Mon, 30 Jul 2012 03:28:35 +0000 (11:28 +0800)
arch/arm/mach-rk2928/devices.c
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 5c670f4330df45878efdcb72f7eb3400f1c15694..eca32631660fd869a368400064f529e65c643ff5 100755 (executable)
@@ -621,6 +621,51 @@ static struct platform_device device_keys = {
 };
 #endif
 
+#ifdef CONFIG_USB20_OTG
+/*DWC_OTG*/
+static struct resource usb20_otg_resource[] = {
+       {
+               .start = IRQ_USB_OTG,
+               .end   = IRQ_USB_OTG,
+               .flags = IORESOURCE_IRQ,
+       },
+       {
+               .start = RK2928_USBOTG20_PHYS,
+               .end   = RK2928_USBOTG20_PHYS + RK2928_USBOTG20_SIZE - 1,
+               .flags = IORESOURCE_MEM,
+       },
+
+};
+
+struct platform_device device_usb20_otg = {
+       .name             = "usb20_otg",
+       .id               = -1,
+       .num_resources    = ARRAY_SIZE(usb20_otg_resource),
+       .resource         = usb20_otg_resource,
+};
+#endif
+#ifdef CONFIG_USB20_HOST
+static struct resource usb20_host_resource[] = {
+    {
+        .start = IRQ_USB_HOST,
+        .end   = IRQ_USB_HOST,
+        .flags = IORESOURCE_IRQ,
+    },
+    {
+        .start = RK2928_USBHOST20_PHYS,
+        .end   = RK2928_USBHOST20_PHYS + RK2928_USBHOST20_SIZE - 1,
+        .flags = IORESOURCE_MEM,
+    },
+
+};
+
+struct platform_device device_usb20_host = {
+    .name             = "usb20_host",
+    .id               = -1,
+    .num_resources    = ARRAY_SIZE(usb20_host_resource),
+    .resource         = usb20_host_resource,
+};
+#endif
 #ifdef CONFIG_SDMMC0_RK29
 static struct resource resources_sdmmc0[] = {
        {
@@ -711,6 +756,12 @@ static int __init rk2928_init_devices(void)
 #endif
 #ifdef CONFIG_LCDC_RK2928
        platform_device_register(&device_lcdc);
+#endif
+#ifdef CONFIG_USB20_OTG
+       platform_device_register(&device_usb20_otg);
+#endif
+#ifdef CONFIG_USB20_HOST
+       platform_device_register(&device_usb20_host);
 #endif
        rk2928_init_sdmmc();
 #if defined(CONFIG_FIQ_DEBUGGER) && defined(DEBUG_UART_PHYS)
index ec4f27fb998149e9acc307309e1e7990bc1a090f..9f44adc2796fb97ee8578e76e766f9bf04886ee0 100755 (executable)
@@ -729,8 +729,8 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if)
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 );  //ep1 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 );  //ep3 tx fifo
     dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 );  //ep5 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x00800330 );  //ep7 tx fifo
-    dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x001003b0 );  //ep9 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
        if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
        {
index 34af78a3a4dd40562c61808a339fd03c5b746307..84c360d55af348b867f4d1004862176650240577 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; 
@@ -1254,8 +1257,8 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
     }
     clk_enable(ahbclk);
     
-    regval &= ~(0x01<<14);    // exit suspend.
-    regval |= (0x01<<13);    // software control
+    regval &= ~(0x01<<14);    // enter suspend.              
+    regval |= (0x01<<13);    // software control enable.    
 
     *otg_phy_con1 = regval;
     udelay(3);
@@ -1291,6 +1294,34 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
     clk_disable(phyclk);
     clk_disable(ahbclk);
 #endif
+#endif
+#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 +1416,41 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
        dwc_otg_device->phyclk = phyclk;
        dwc_otg_device->ahbclk = ahbclk;
 #endif
+#ifdef 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.
         */
@@ -1498,6 +1564,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
         dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST;
 #else 
         dwc_otg_device->core_if->usb_mode = USB_MODE_NORMAL;
+#ifdef CONFIG_DWC_OTG_DEFAULT_DEVICE
+        dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_DEVICE;
+#endif
 #endif
 
 #endif
@@ -1516,6 +1585,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
@@ -1557,6 +1629,26 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev)
         *otg_phy_con1 &= ~(0x01<<3);    // enter suspend.
     }
 #endif
+#endif
+#ifdef CONFIG_ARCH_RK30                   
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
+    if(dwc_otg_device->hcd->host_enabled == 0)
+    {
+        clk_disable(dwc_otg_device->phyclk);
+        clk_disable(dwc_otg_device->ahbclk);
+       *otg_phy_con = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16);   // enter suspend.
+    }
+#endif
+#endif
+#ifdef CONFIG_ARCH_RK2928                   
+#ifndef CONFIG_DWC_OTG_DEVICE_ONLY
+    if(dwc_otg_device->hcd->host_enabled == 0)
+    {
+        clk_disable(dwc_otg_device->phyclk);
+        clk_disable(dwc_otg_device->ahbclk);
+       *otg_phy_con =   ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16);   // enter suspend.
+    }
+#endif
 #endif
        return 0;
  fail:
@@ -2044,16 +2136,20 @@ static __devinit int host20_driver_probe(struct platform_device *pdev)
         */
 #ifdef CONFIG_ARCH_RK29    
     unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
+    otgreg = * otg_phy_con1;
+    otgreg |= (0x01<<13);    // software control enable
+    otgreg |= (0x01<<14);    // exit suspend.
+    otgreg &= ~(0x01<<13);    // software control disable
+    *otg_phy_con1 = otgreg;
 #endif
 #ifdef CONFIG_ARCH_RK30
     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
-        
-    otgreg = * otg_phy_con1;
-    otgreg |= (0x01<<13);    // software control
-    otgreg |= (0x01<<14);    // exit suspend.
-    otgreg &= ~(0x01<<13);    // software control
-    *otg_phy_con1 = otgreg;
     #if 0
     *otg_phy_con1 |= (0x01<<2);
     *otg_phy_con1 |= (0x01<<3);    // exit suspend.
@@ -2080,6 +2176,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");
@@ -2104,6 +2203,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");    //check
+#endif 
     if (IS_ERR(ahbclk)) {
             retval = PTR_ERR(ahbclk);
             DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
@@ -2242,9 +2344,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 e85ada78ead6c841e295e274f5b6866b2cf8ef07..4c84033c2a59663c1c17c0446175166a2c287efa 100755 (executable)
@@ -617,6 +617,24 @@ static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend)
         udelay(3);
         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.
+        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 +681,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 +739,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 +754,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata)
     
     }
     if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){
+#ifdef CONFIG_ARCH_RK30        
     DWC_PRINT("%s schedule delaywork \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 +1142,24 @@ static int32_t host20_phy_suspend_cb( void *_p, int suspend)
         udelay(3);
         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.
+        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 +1310,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->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 c89715f0e4dce123566d69c63e7f9cf1723e58df..35729af45d88128146cb3ff9bd9884310f39fe8f 100755 (executable)
@@ -1657,7 +1657,24 @@ 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.
+        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;
 }
 
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 
  *