RK2928 USB modified
authorwlf <wulf@rock-chips.com>
Mon, 3 Sep 2012 10:03:22 +0000 (18:03 +0800)
committerwlf <wulf@rock-chips.com>
Mon, 3 Sep 2012 10:03:22 +0000 (18:03 +0800)
arch/arm/mach-rk2928/devices.c
drivers/usb/dwc_otg/usbdev_rk2928.c

index f6c2717d37face8f5ffaa6f426c4f797232f2b6e..ccccbfa7f69c10291b30c6acc29525b90fe0a49b 100755 (executable)
@@ -727,51 +727,6 @@ 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[] = {
        {
@@ -861,12 +816,6 @@ static int __init rk2928_init_devices(void)
 #endif
 #ifdef CONFIG_RGA_RK30
        platform_device_register(&device_rga);
-#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 f34620091cf149718570857e6e52e9718a75833b..e3d74450a216808c8af5c07da8195990155a1080 100755 (executable)
@@ -1,2 +1,332 @@
+#include <linux/kernel.h>\r
+#include <linux/platform_device.h>\r
+#include <linux/delay.h>\r
+#include <linux/dma-mapping.h>\r
+#include <linux/clk.h>\r
+\r
+#include <mach/irqs.h>\r
+#include <mach/gpio.h>\r
+#include <mach/iomux.h>\r
+#include <mach/cru.h>\r
+\r
+#include "usbdev_rk.h"\r
+#include "dwc_otg_regs.h"\r
 #ifdef CONFIG_ARCH_RK2928\r
-#endif
\ No newline at end of file
+\r
+#define GRF_REG_BASE RK2928_GRF_BASE\r
+#define USBOTG_SIZE    RK2928_USBOTG20_SIZE\r
+#define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0x14c)\r
+#define USBGRF_UOC0_CON5       (GRF_REG_BASE+0x17c)\r
+#define USBGRF_UOC1_CON5       (GRF_REG_BASE+0x194)\r
+\r
+\r
+int dwc_otg_check_dpdm(void)\r
+{\r
+       static uint8_t * reg_base = 0;\r
+    volatile unsigned int * otg_dctl;\r
+    volatile unsigned int * otg_gotgctl;\r
+    volatile unsigned int * otg_hprt0;\r
+    int bus_status = 0;\r
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5\r
+    \r
+    // softreset & clockgate //@lyz modify RK2928_CRU_BASE\r
+    *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5);    // otg0 phy clkgate\r
+    udelay(3);\r
+    *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5);    // otg0 phy clkgate\r
+    dsb();\r
+    *(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16);    // otg0 phy clkgate\r
+    *(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16);   // otg0 hclk clkgate\r
+    *(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16);    // hclk usb clkgate//@lyz to be check\r
+    \r
+    // exit phy suspend \r
+        *otg_phy_con1 = ((0x01<<0)<<16);    // exit suspend.@lyz\r
+    \r
+    // soft connect\r
+    if(reg_base == 0){\r
+        reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz\r
+        if(!reg_base){\r
+            bus_status = -1;\r
+            goto out;\r
+        }\r
+    }\r
+    mdelay(105);\r
+    printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",\r
+        reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);\r
+    otg_dctl = (unsigned int * )(reg_base+0x804);\r
+    otg_gotgctl = (unsigned int * )(reg_base);\r
+    otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);\r
+    if(*otg_gotgctl &(1<<19)){\r
+        bus_status = 1;\r
+        *otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode\r
+        mdelay(50);    // delay about 10ms\r
+    // check dp,dm\r
+        if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10] \r
+            bus_status = 2;\r
+    }\r
+out:\r
+    return bus_status;\r
+}\r
+\r
+EXPORT_SYMBOL(dwc_otg_check_dpdm);\r
+\r
+\r
+#ifdef CONFIG_USB20_OTG\r
+/*DWC_OTG*/\r
+static struct resource usb20_otg_resource[] = {\r
+       {\r
+               .start = IRQ_USB_OTG,\r
+               .end   = IRQ_USB_OTG,\r
+               .flags = IORESOURCE_IRQ,\r
+       },\r
+       {\r
+               .start = RK2928_USBOTG20_PHYS,\r
+               .end   = RK2928_USBOTG20_PHYS + RK2928_USBOTG20_SIZE - 1,\r
+               .flags = IORESOURCE_MEM,\r
+       },\r
+\r
+};\r
+\r
+void usb20otg_hw_init(void)\r
+{\r
+#ifndef CONFIG_USB20_HOST\r
+    // close USB 2.0 HOST phy and clock\r
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5);\r
+    *otg_phy_con1 = 0x1D5 |(0x1ff<<16);   // enter suspend.\r
+#endif\r
+    // usb phy config init\r
+\r
+    // other hardware init\r
+    rk30_mux_api_set(GPIO3C1_OTG_DRVVBUS_NAME, GPIO3C_OTG_DRVVBUS);    \r
+}\r
+void usb20otg_phy_suspend(void* pdata, int suspend)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);\r
+    if(suspend){\r
+        *otg_phy_con1 = 0x1D5 |(0x1ff<<16);   // enter suspend.\r
+        usbpdata->phy_status = 1;\r
+    }\r
+    else{\r
+        *otg_phy_con1 = (0x01<<16);    // exit suspend.\r
+        usbpdata->phy_status = 0;\r
+    }\r
+}\r
+void usb20otg_soft_reset(void)\r
+{\r
+#if 1\r
+    cru_set_soft_reset(SOFT_RST_USBOTG0, true);\r
+    cru_set_soft_reset(SOFT_RST_USBPHY0, true);\r
+    cru_set_soft_reset(SOFT_RST_OTGC0, true);\r
+    udelay(1);\r
+\r
+    cru_set_soft_reset(SOFT_RST_USBOTG0, false);\r
+    cru_set_soft_reset(SOFT_RST_USBPHY0, false);\r
+    cru_set_soft_reset(SOFT_RST_OTGC0, false);\r
+    mdelay(1);\r
+#endif\r
+}\r
+void usb20otg_clock_init(void* pdata)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    struct clk* ahbclk,*phyclk;\r
+    ahbclk = clk_get(NULL, "hclk_otg0");\r
+    phyclk = clk_get(NULL, "otgphy0");\r
+       usbpdata->phyclk = phyclk;\r
+       usbpdata->ahbclk = ahbclk;\r
+}\r
+void usb20otg_clock_enable(void* pdata, int enable)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    #if 1\r
+    if(enable){\r
+        clk_enable(usbpdata->ahbclk);\r
+        clk_enable(usbpdata->phyclk);\r
+    }\r
+    else{\r
+   // clk_disable(usbpdata->phyclk);   /* otg/host20 use the same phyclk, so can't disable phyclk in case host20 is used.*/ \r
+        clk_disable(usbpdata->ahbclk);    \r
+    }\r
+    #endif\r
+}\r
+int usb20otg_get_status(int id)\r
+{\r
+    int ret = -1;\r
+    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
+    switch(id)\r
+    {\r
+        case USB_STATUS_BVABLID:\r
+            // bvalid in grf\r
+            ret = (usbgrf_status &(1<<7));\r
+            break;\r
+        case USB_STATUS_DPDM:\r
+            // dpdm in grf\r
+            ret = (usbgrf_status &(3<<8));\r
+            break;\r
+        case USB_STATUS_ID:\r
+            // id in grf\r
+            ret = (usbgrf_status &(1<<10));\r
+            break;\r
+        default:\r
+            break;\r
+    }\r
+    return ret;\r
+}\r
+void usb20otg_power_enable(int enable)\r
+{\r
+}\r
+struct dwc_otg_platform_data usb20otg_pdata = {\r
+    .phyclk = NULL,\r
+    .ahbclk = NULL,\r
+    .busclk = NULL,\r
+    .phy_status = 0,\r
+    .hw_init=usb20otg_hw_init,\r
+    .phy_suspend=usb20otg_phy_suspend,\r
+    .soft_reset=usb20otg_soft_reset,\r
+    .clock_init=usb20otg_clock_init,\r
+    .clock_enable=usb20otg_clock_enable,\r
+    .get_status=usb20otg_get_status,\r
+};\r
+\r
+struct platform_device device_usb20_otg = {\r
+       .name             = "usb20_otg",\r
+       .id               = -1,\r
+       .num_resources    = ARRAY_SIZE(usb20_otg_resource),\r
+       .resource         = usb20_otg_resource,\r
+       .dev            = {\r
+               .platform_data  = &usb20otg_pdata,\r
+       },\r
+};\r
+#endif\r
+#ifdef CONFIG_USB20_HOST\r
+static struct resource usb20_host_resource[] = {\r
+    {\r
+        .start = IRQ_USB_HOST,\r
+        .end   = IRQ_USB_HOST,\r
+        .flags = IORESOURCE_IRQ,\r
+    },\r
+    {\r
+        .start = RK2928_USBHOST20_PHYS,\r
+        .end   = RK2928_USBHOST20_PHYS + RK2928_USBHOST20_SIZE - 1,\r
+        .flags = IORESOURCE_MEM,\r
+    },\r
+\r
+};\r
+\r
+void usb20host_hw_init(void)\r
+{\r
+    // usb phy config init\r
+    *(unsigned int *)(USBGRF_UOC0_CON5+4) = 0x07e00350;\r
+    // other haredware init\r
+    \r
+}\r
+void usb20host_phy_suspend(void* pdata, int suspend)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5);\r
+    if(suspend){\r
+        *otg_phy_con1 = 0x1D5 |(0x1ff<<16);   // enter suspend.\r
+        usbpdata->phy_status = 1;\r
+    }\r
+    else{\r
+        *otg_phy_con1 = (0x01<<16);    // exit suspend.\r
+        usbpdata->phy_status = 0;\r
+    }\r
+}\r
+void usb20host_soft_reset(void)\r
+{\r
+#if 1\r
+    cru_set_soft_reset(SOFT_RST_USBOTG1, true);\r
+    cru_set_soft_reset(SOFT_RST_USBPHY1, true);\r
+    cru_set_soft_reset(SOFT_RST_OTGC1, true);\r
+    udelay(1);\r
+\r
+    cru_set_soft_reset(SOFT_RST_USBOTG1, false);\r
+    cru_set_soft_reset(SOFT_RST_USBPHY1, false);\r
+    cru_set_soft_reset(SOFT_RST_OTGC1, false);\r
+    mdelay(1);\r
+#endif\r
+}\r
+void usb20host_clock_init(void* pdata)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    struct clk* ahbclk,*phyclk;\r
+    ahbclk = clk_get(NULL, "hclk_otg1");\r
+    phyclk = clk_get(NULL, "otgphy1");\r
+       usbpdata->phyclk = phyclk;\r
+       usbpdata->ahbclk = ahbclk;\r
+}\r
+void usb20host_clock_enable(void* pdata, int enable)\r
+{\r
+    struct dwc_otg_platform_data *usbpdata=pdata;\r
+    #if 1\r
+    if(enable){\r
+        clk_enable(usbpdata->ahbclk);\r
+        clk_enable(usbpdata->phyclk);\r
+    }\r
+    else{\r
+        clk_disable(usbpdata->phyclk);\r
+        clk_disable(usbpdata->ahbclk);\r
+    }\r
+    #endif\r
+}\r
+int usb20host_get_status(int id)\r
+{\r
+    int ret = -1;\r
+    unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
+    switch(id)\r
+    {\r
+        case USB_STATUS_BVABLID:\r
+            // bvalid in grf\r
+            ret = (usbgrf_status &(1<<12));\r
+            break;\r
+        case USB_STATUS_DPDM:\r
+            // dpdm in grf\r
+            ret = (usbgrf_status &(3<<13));\r
+            break;\r
+        case USB_STATUS_ID:\r
+            // id in grf\r
+            ret = 0;\r
+            break;\r
+        default:\r
+            break;\r
+    }\r
+    return ret;\r
+}\r
+void usb20host_power_enable(int enable)\r
+{\r
+}\r
+struct dwc_otg_platform_data usb20host_pdata = {\r
+    .phyclk = NULL,\r
+    .ahbclk = NULL,\r
+    .busclk = NULL,\r
+    .phy_status = 0,\r
+    .hw_init=usb20host_hw_init,\r
+    .phy_suspend=usb20host_phy_suspend,\r
+    .soft_reset=usb20host_soft_reset,\r
+    .clock_init=usb20host_clock_init,\r
+    .clock_enable=usb20host_clock_enable,\r
+    .get_status=usb20host_get_status,\r
+};\r
+\r
+struct platform_device device_usb20_host = {\r
+    .name             = "usb20_host",\r
+    .id               = -1,\r
+    .num_resources    = ARRAY_SIZE(usb20_host_resource),\r
+    .resource         = usb20_host_resource,\r
+    .dev               = {\r
+               .platform_data  = &usb20host_pdata,\r
+       },\r
+};\r
+#endif\r
+static int __init usbdev_init_devices(void)\r
+{\r
+#ifdef CONFIG_USB20_OTG\r
+       platform_device_register(&device_usb20_otg);\r
+#endif\r
+#ifdef CONFIG_USB20_HOST\r
+       platform_device_register(&device_usb20_host);\r
+#endif\r
+}\r
+arch_initcall(usbdev_init_devices);\r
+#endif\r
+\r