USB: support RK3188 usb bypass uart function
authorwlf <wulf@rock-chips.com>
Sat, 26 Jan 2013 11:33:31 +0000 (19:33 +0800)
committerwlf <wulf@rock-chips.com>
Sat, 26 Jan 2013 11:33:31 +0000 (19:33 +0800)
arch/arm/common/fiq_debugger.c
arch/arm/mach-rk30/common.c
arch/arm/plat-rk/usb_detect.c
drivers/usb/dwc_otg/usbdev_rk30.c

index d23809165927cc716f6ac7d79b151e531204a4d3..d92bafa616e58ee0022639da64356411c0ad869e 100644 (file)
@@ -1050,10 +1050,15 @@ static void debug_fiq(struct fiq_glue_handler *h, void *regs, void *svc_sp)
         * and make uart controller enter infinite fiq loop 
         */
 #ifdef CONFIG_RK_USB_UART
-       if(!(readl_relaxed(RK2928_GRF_BASE + 0x014c) & (1<<10))) //id low    
-       {         
+#ifdef CONFIG_ARCH_RK2928
+       if(!(readl_relaxed(RK2928_GRF_BASE + 0x014c) & (1<<10))){//id low          
                writel_relaxed(0x34000000, RK2928_GRF_BASE + 0x190);   //enter usb phy    
        }
+#elif defined(CONFIG_ARCH_RK3188)
+       if(!(readl_relaxed(RK30_GRF_BASE + 0x00ac) & (1 << 13))){//id low          
+               writel_relaxed((0x0300 << 16), RK30_GRF_BASE + 0x010c);   //enter usb phy    
+       }
+#endif
 #endif
        need_irq = debug_handle_uart_interrupt(state, this_cpu, regs, svc_sp);
        if (need_irq)
index f5148b95487acb462100922bed723f30b9d143c5..3ca82ba813b0f05c6107b863474e5750870c6cfd 100755 (executable)
@@ -151,6 +151,30 @@ void __init rk30_init_irq(void)
 void __init rk30_map_io(void)
 {
        rk30_map_common_io();
+#ifdef DEBUG_UART_BASE
+#ifdef CONFIG_RK_USB_UART
+       if(!(readl_relaxed(RK30_GRF_BASE + GRF_SOC_STATUS0) & (1 << 13))){//detect id
+               writel_relaxed((0x0300 << 16), RK30_GRF_BASE + GRF_UOC0_CON0);
+       }else{
+               if(!(readl_relaxed(RK30_GRF_BASE + GRF_SOC_STATUS0) & (1 << 10))){//detect vbus
+                       writel_relaxed(((0x01 << 2) | ((0x01 << 2) << 16)), RK30_GRF_BASE + GRF_UOC0_CON2); //software control usb phy enable 
+                       writel_relaxed((0x2A | (0x3F << 16)), RK30_GRF_BASE + GRF_UOC0_CON3);  //usb phy enter suspend
+                       writel_relaxed((0x0300 | (0x0300 << 16)), RK30_GRF_BASE + GRF_UOC0_CON0);
+               }else{
+                       writel_relaxed((0x0300 << 16), RK30_GRF_BASE + GRF_UOC0_CON0);
+               }
+       }
+#else
+       writel_relaxed((0x0300 << 16), RK30_GRF_BASE + GRF_UOC0_CON0);
+#endif
+       writel_relaxed(0x07, DEBUG_UART_BASE + 0x88);
+       writel_relaxed(0x07, DEBUG_UART_BASE + 0x88);
+       writel_relaxed(0x00, DEBUG_UART_BASE + 0x04);                                                                               
+       writel_relaxed(0x83, DEBUG_UART_BASE + 0x0c);
+       writel_relaxed(0x0d, DEBUG_UART_BASE + 0x00);
+       writel_relaxed(0x00, DEBUG_UART_BASE + 0x04);
+       writel_relaxed(0x03, DEBUG_UART_BASE + 0x0c);
+#endif
        rk29_setup_early_printk();
        rk30_cpu_axi_init();
        rk30_io_drive_strength_init();
index b649730274021a55afb0bd730c63e46a9e542544..b40b020a94de6934e2d4cf1bb2e0de75db5b0f2f 100755 (executable)
@@ -91,6 +91,10 @@ static irqreturn_t bvalid_irq_handler(int irq, void *dev_id)
 #endif
 #elif defined(CONFIG_ARCH_RK3188)
        writel_relaxed((1 << 31) | (1 << 15), RK30_GRF_BASE + GRF_UOC0_CON3);
+#ifdef CONFIG_RK_USB_UART
+       /* usb otg dp/dm switch to usb phy */
+       writel_relaxed((0x0300 << 16), RK30_GRF_BASE + GRF_UOC0_CON0);
+#endif
 #endif
 
 #ifdef CONFIG_RK_USB_DETECT_BY_OTG_BVALID
index 02aeecc5ef209cf3cafd77edfd3959b934f5e42b..85d6f54de1f299b973f68e27aff562bc0de95d74 100755 (executable)
@@ -18,6 +18,7 @@
 #define USBOTG_SIZE    RK30_USBOTG20_SIZE\r
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
 #define USBGRF_SOC_STATUS0     (GRF_REG_BASE+0xac)\r
+#define USBGRF_UOC0_CON0       (GRF_REG_BASE+0x10c)\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
@@ -228,7 +229,27 @@ int usb20otg_get_status(int id)
         }\r
         return ret;\r
 }\r
\r
+\r
+#ifdef CONFIG_RK_USB_UART\r
+void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)\r
+{\r
+       unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON0);\r
+             \r
+       if(1 == enter_usb_uart_mode){  //enter uart mode\r
+               /*note: can't disable otg here! If otg disable, the ID change\r
+               *interrupt can't be triggered when otg cable connect without\r
+               *device.At the same time, uart can't be used normally \r
+               */\r
+               //*otg_phy_con1 = (0x10 | (0x10 << 16));//otg disable\r
+               *otg_phy_con1 = (0x0300 | (0x0300 << 16));//bypass dm       \r
+       }\r
+       if(0 == enter_usb_uart_mode){  //enter usb mode \r
+               *otg_phy_con1 = (0x0300 << 16); //bypass dm disable\r
+               //*otg_phy_con1 = (0x10 << 16);//otg enable             \r
+       }\r
+}\r
+#endif\r
+\r
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
 void usb20otg_power_enable(int enable)\r
 { \r
@@ -257,7 +278,10 @@ struct dwc_otg_platform_data usb20otg_pdata = {
     .get_status=usb20otg_get_status,\r
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)\r
     .power_enable=usb20otg_power_enable,\r
-#endif    \r
+#endif\r
+#ifdef CONFIG_RK_USB_UART\r
+    .dwc_otg_uart_mode=dwc_otg_uart_mode,\r
+#endif\r
 };\r
 \r
 struct platform_device device_usb20_otg = {\r