From: wlf 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 = {