#include <mach/cru.h>\r
\r
#include "usbdev_rk.h"\r
-#ifdef CONFIG_ARCH_RK30\r
+#include "dwc_otg_regs.h" \r
+\r
+#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK3188)\r
\r
#define GRF_REG_BASE RK30_GRF_BASE \r
#define USBOTG_SIZE RK30_USBOTG20_SIZE\r
-#ifdef CONFIG_ARCH_RK3066B\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
#define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0xac)\r
-#define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x118) // USBGRF_UOC0_CON3\r
-#define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x128) // USBGRF_UOC1_CON3\r
+#define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x114)\r
+#define USBGRF_UOC0_CON3 (GRF_REG_BASE+0x118)\r
+#define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x124)\r
+#define USBGRF_UOC1_CON3 (GRF_REG_BASE+0x128)\r
+\r
+#if defined(CONFIG_SOC_RK3066B) || defined(CONFIG_SOC_RK3108) \r
+#define RK3066B_HOST_DRV_VBUS RK30_PIN0_PD7\r
+#define RK3066B_OTG_DRV_VBUS RK30_PIN0_PD6\r
+#elif defined(CONFIG_SOC_RK3168) || defined(CONFIG_ARCH_RK3188) \r
+#define RK3066B_HOST_DRV_VBUS RK30_PIN0_PC0\r
+#define RK3066B_OTG_DRV_VBUS RK30_PIN3_PD5\r
+#endif\r
+\r
#else\r
#define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0x15c)\r
#define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x184)\r
#define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x190)\r
#endif\r
-//#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)\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_CON2);\r
+ \r
+ // softreset & clockgate \r
+ *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5); // otg0 phy clkgate\r
+ udelay(3);\r
+ *(unsigned int*)(RK30_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5); // otg0 phy clkgate\r
+ dsb();\r
+ *(unsigned int*)(RK30_CRU_BASE+0xd4) = ((1<<5)<<16); // otg0 phy clkgate\r
+ *(unsigned int*)(RK30_CRU_BASE+0xe4) = ((1<<13)<<16); // otg0 hclk clkgate\r
+ *(unsigned int*)(RK30_CRU_BASE+0xe0) = ((3<<5)<<16); // hclk usb clkgate\r
+ \r
+ // exit phy suspend \r
+ *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
+ \r
+ // soft connect\r
+ if(reg_base == 0){\r
+ reg_base = ioremap(RK30_USBOTG20_PHYS,USBOTG_SIZE);\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 &= ~2;\r
+ mdelay(50); // delay about 10ms\r
+ // check dp,dm\r
+ if((*otg_hprt0 & 0xc00)==0xc00)\r
+ bus_status = 2;\r
+ }\r
+out:\r
+ return bus_status;\r
+}\r
+\r
+EXPORT_SYMBOL(dwc_otg_check_dpdm);\r
\r
#ifdef CONFIG_USB20_OTG\r
/*DWC_OTG*/\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_CON2);\r
- *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
+ // close USB 2.0 HOST phy and clock\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+ unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC1_CON3);\r
+ *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16); //enable soft control\r
+ *otg_phy_con2 = 0x2A|(0x3F<<16); // enter suspend \r
+#else\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+ *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
#endif\r
- // usb phy config init\r
-\r
- // other haredware init\r
-#ifdef CONFIG_ARCH_RK3066B\r
- rk30_mux_api_set(GPIO3D5_PWM2_JTAGTCK_OTGDRVVBUS_NAME, GPIO3D_OTGDRVVBUS);\r
+#endif\r
+ // usb phy config init\r
+ \r
+ // other haredware init\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ //GPIO init\r
+ gpio_request(RK3066B_OTG_DRV_VBUS, NULL);\r
+ gpio_direction_output(RK3066B_OTG_DRV_VBUS, GPIO_LOW);\r
#else\r
- rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);\r
+ rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);\r
#endif\r
}\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_CON2);\r
- if(suspend){\r
- *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
- usbpdata->phy_status = 1;\r
- }\r
- else{\r
- *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
- usbpdata->phy_status = 0;\r
- }\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ struct dwc_otg_platform_data *usbpdata=pdata;\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
+ unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC0_CON3);\r
+ if(suspend){\r
+ *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16); ; //enable soft control\r
+ *otg_phy_con2 = 0x2A|(0x3F<<16);; // enter suspend\r
+ usbpdata->phy_status = 1;\r
+ }\r
+ else{\r
+ *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
+ usbpdata->phy_status = 0;\r
+ }\r
+#else\r
+ struct dwc_otg_platform_data *usbpdata=pdata;\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);\r
+ if(suspend){\r
+ *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
+ usbpdata->phy_status = 1;\r
+ }\r
+ else{\r
+ *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
+ usbpdata->phy_status = 0;\r
+ }\r
+#endif\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
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
void usb20otg_clock_enable(void* pdata, int enable)\r
{\r
struct dwc_otg_platform_data *usbpdata=pdata;\r
- #if 1\r
+\r
if(enable){\r
clk_enable(usbpdata->ahbclk);\r
clk_enable(usbpdata->phyclk);\r
clk_disable(usbpdata->phyclk);\r
clk_disable(usbpdata->ahbclk);\r
}\r
- #endif\r
}\r
int usb20otg_get_status(int id)\r
{\r
- int ret = -1;\r
+ int ret = -1;\r
+ unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
+ switch(id)\r
+ {\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ case USB_STATUS_BVABLID:\r
+ // bvalid in grf\r
+ ret = (usbgrf_status &(1<<10));\r
+ break;\r
+ case USB_STATUS_DPDM:\r
+ // dpdm in grf\r
+ ret = (usbgrf_status &(3<<11));\r
+ break;\r
+ case USB_STATUS_ID:\r
+ // id in grf\r
+ ret = (usbgrf_status &(1<<13));\r
+ break;\r
+#else\r
+ case USB_STATUS_BVABLID:\r
+ // bvalid in grf\r
+ ret = (usbgrf_status &0x20000);\r
+ break;\r
+ case USB_STATUS_DPDM:\r
+ // dpdm in grf\r
+ ret = (usbgrf_status &(3<<18));\r
+ break;\r
+ case USB_STATUS_ID:\r
+ // id in grf\r
+ ret = (usbgrf_status &(1<<20));\r
+ break;\r
+#endif\r
+ default:\r
+ break;\r
+ }\r
+ return ret;\r
+}\r
+ \r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+void usb20otg_power_enable(int enable)\r
+{ \r
unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
- switch(id)\r
+ if(0 == enable)//disable\r
{\r
- case 0x01:\r
- // bvalid in grf\r
- ret = (usbgrf_status &0x20000);\r
- break;\r
- case 0x02:\r
- // dpdm in grf\r
- ret = (usbgrf_status &(3<<18));\r
- break;\r
- case 0x03:\r
- // id in grf\r
- ret = (usbgrf_status &(1<<20));\r
- break;\r
- default:\r
- break;\r
+ gpio_set_value(RK3066B_OTG_DRV_VBUS, GPIO_LOW); \r
+\r
}\r
- return ret;\r
-}\r
-void usb20otg_power_enable(int enable)\r
-{\r
+ if(1 == enable)//enable\r
+ {\r
+ gpio_set_value(RK3066B_OTG_DRV_VBUS, GPIO_HIGH); \r
+ } \r
}\r
+#endif\r
struct dwc_otg_platform_data usb20otg_pdata = {\r
.phyclk = NULL,\r
.ahbclk = NULL,\r
.clock_init=usb20otg_clock_init,\r
.clock_enable=usb20otg_clock_enable,\r
.get_status=usb20otg_get_status,\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ .power_enable=usb20otg_power_enable,\r
+#endif \r
};\r
\r
struct platform_device device_usb20_otg = {\r
// usb phy config init\r
\r
// other haredware init\r
-#ifdef CONFIG_ARCH_RK3066B\r
- rk30_mux_api_set(GPIO3D6_PWM3_JTAGTMS_HOSTDRVVBUS_NAME, GPIO3D_HOSTDRVVBUS);\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ gpio_request(RK3066B_HOST_DRV_VBUS, NULL);\r
+ gpio_direction_output(RK3066B_HOST_DRV_VBUS, GPIO_HIGH);\r
#else\r
rk30_mux_api_set(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);\r
#endif\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_CON2);\r
- if(suspend){\r
- *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
- usbpdata->phy_status = 0;\r
- }\r
- else{\r
- *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
- usbpdata->phy_status = 1;\r
- }\r
+{ \r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ struct dwc_otg_platform_data *usbpdata=pdata;\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+ unsigned int * otg_phy_con2 = (unsigned int*)(USBGRF_UOC1_CON3);\r
+ if(suspend)\r
+ {\r
+ *otg_phy_con1 = (0x01<<2)|((0x01<<2)<<16); ; //enable soft control\r
+ *otg_phy_con2 = 0x2A|(0x3F<<16);; // enter suspend\r
+ usbpdata->phy_status = 1;\r
+ }\r
+ else\r
+ {\r
+ *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
+ usbpdata->phy_status = 0;\r
+ } \r
+#else\r
+ struct dwc_otg_platform_data *usbpdata=pdata;\r
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);\r
+ if(suspend)\r
+ {\r
+ *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.\r
+ usbpdata->phy_status = 1;\r
+ }\r
+ else\r
+ {\r
+ *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.\r
+ usbpdata->phy_status = 0;\r
+ }\r
+#endif \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
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
void usb20host_clock_enable(void* pdata, int enable)\r
{\r
struct dwc_otg_platform_data *usbpdata=pdata;\r
- #if 1\r
+ \r
if(enable){\r
clk_enable(usbpdata->ahbclk);\r
clk_enable(usbpdata->phyclk);\r
clk_disable(usbpdata->phyclk);\r
clk_disable(usbpdata->ahbclk);\r
}\r
- #endif\r
}\r
int usb20host_get_status(int id)\r
{\r
unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);\r
switch(id)\r
{\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ case USB_STATUS_BVABLID:\r
+ // bvalid in grf\r
+ ret = (usbgrf_status &(1<<17));\r
+ break;\r
+ case USB_STATUS_DPDM:\r
+ // dpdm in grf\r
+ ret = (usbgrf_status &(3<<18));\r
+ break;\r
+ case USB_STATUS_ID:\r
+ // id in grf\r
+ ret = (usbgrf_status &(1<<20));\r
+ break;\r
+#else\r
case USB_STATUS_BVABLID:\r
// bvalid in grf\r
ret = (usbgrf_status &(1<<22));\r
// id in grf\r
ret = 0;\r
break;\r
+#endif\r
default:\r
break;\r
}\r
return ret;\r
}\r
+\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
void usb20host_power_enable(int enable)\r
-{\r
+{ \r
+\r
+ if(0 == enable)//disable\r
+ {\r
+ //ret = gpio_request(RK3066B_HOST_DRV_VBUS, NULL);\r
+ //if (ret != 0) {\r
+ // gpio_free(RK3066B_HOST_DRV_VBUS);\r
+ //}\r
+ //gpio_direction_output(RK3066B_HOST_DRV_VBUS, 1);\r
+ //gpio_set_value(RK3066B_HOST_DRV_VBUS, 0);\r
+ //printk("!!!!!!!!!!!!!!!!!!!disable host power!!!!!!!!!!!!!!!!!!\n");\r
+ }\r
+\r
+ if(1 == enable)//enable\r
+ {\r
+ gpio_set_value(RK3066B_HOST_DRV_VBUS, GPIO_HIGH);\r
+ //printk("!!!!!!!!!!!!!!!!!!!!!enable host power!!!!!!!!!!!!!!!!!!\n");\r
+ } \r
}\r
+#endif\r
struct dwc_otg_platform_data usb20host_pdata = {\r
.phyclk = NULL,\r
.ahbclk = NULL,\r
.clock_init=usb20host_clock_init,\r
.clock_enable=usb20host_clock_enable,\r
.get_status=usb20host_get_status,\r
+#if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
+ .power_enable=usb20host_power_enable,\r
+#endif \r
};\r
\r
struct platform_device device_usb20_host = {\r
#ifdef CONFIG_USB20_HOST\r
platform_device_register(&device_usb20_host);\r
#endif\r
+ return 0;\r
}\r
arch_initcall(usbdev_init_devices);\r
-#endif
\ No newline at end of file
+#endif\r