From: wlf <wulf@rock-chips.com>
Date: Sat, 26 Jan 2013 11:33:31 +0000 (+0800)
Subject: USB:  support RK3188 usb bypass uart function
X-Git-Tag: firefly_0821_release~7753
X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d308c6e3940adf661833556b75d85ec9dc778b5f;p=firefly-linux-kernel-4.4.55.git

USB:  support RK3188 usb bypass uart function
---

diff --git a/arch/arm/common/fiq_debugger.c b/arch/arm/common/fiq_debugger.c
index d23809165927..d92bafa616e5 100644
--- a/arch/arm/common/fiq_debugger.c
+++ b/arch/arm/common/fiq_debugger.c
@@ -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)
diff --git a/arch/arm/mach-rk30/common.c b/arch/arm/mach-rk30/common.c
index f5148b95487a..3ca82ba813b0 100755
--- a/arch/arm/mach-rk30/common.c
+++ b/arch/arm/mach-rk30/common.c
@@ -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();
diff --git a/arch/arm/plat-rk/usb_detect.c b/arch/arm/plat-rk/usb_detect.c
index b64973027402..b40b020a94de 100755
--- a/arch/arm/plat-rk/usb_detect.c
+++ b/arch/arm/plat-rk/usb_detect.c
@@ -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
diff --git a/drivers/usb/dwc_otg/usbdev_rk30.c b/drivers/usb/dwc_otg/usbdev_rk30.c
index 02aeecc5ef20..85d6f54de1f2 100755
--- a/drivers/usb/dwc_otg/usbdev_rk30.c
+++ b/drivers/usb/dwc_otg/usbdev_rk30.c
@@ -18,6 +18,7 @@
 #define USBOTG_SIZE	RK30_USBOTG20_SIZE
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
 #define USBGRF_SOC_STATUS0	(GRF_REG_BASE+0xac)
+#define USBGRF_UOC0_CON0	(GRF_REG_BASE+0x10c)
 #define USBGRF_UOC0_CON2	(GRF_REG_BASE+0x114)
 #define USBGRF_UOC0_CON3	(GRF_REG_BASE+0x118)
 #define USBGRF_UOC1_CON2	(GRF_REG_BASE+0x124)
@@ -228,7 +229,27 @@ int usb20otg_get_status(int id)
         }
         return ret;
 }
- 
+
+#ifdef CONFIG_RK_USB_UART
+void dwc_otg_uart_mode(void* pdata, int enter_usb_uart_mode)
+{
+	unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON0);
+	      
+	if(1 == enter_usb_uart_mode){  //enter uart mode
+		/*note: can't disable otg here! If otg disable, the ID change
+		*interrupt can't be triggered when otg cable connect without
+		*device.At the same time, uart can't be used normally 
+		*/
+		//*otg_phy_con1 = (0x10 | (0x10 << 16));//otg disable
+		*otg_phy_con1 = (0x0300 | (0x0300 << 16));//bypass dm       
+	}
+	if(0 == enter_usb_uart_mode){  //enter usb mode 
+		*otg_phy_con1 = (0x0300 << 16); //bypass dm disable
+		//*otg_phy_con1 = (0x10 << 16);//otg enable		
+	}
+}
+#endif
+
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
 void usb20otg_power_enable(int enable)
 { 
@@ -257,7 +278,10 @@ struct dwc_otg_platform_data usb20otg_pdata = {
     .get_status=usb20otg_get_status,
 #if defined(CONFIG_ARCH_RK3066B) || defined(CONFIG_ARCH_RK3188)
     .power_enable=usb20otg_power_enable,
-#endif    
+#endif
+#ifdef CONFIG_RK_USB_UART
+    .dwc_otg_uart_mode=dwc_otg_uart_mode,
+#endif
 };
 
 struct platform_device device_usb20_otg = {