From: wlf Date: Mon, 30 Jul 2012 03:28:35 +0000 (+0800) Subject: RK2928 usb hcd modified X-Git-Tag: firefly_0821_release~8912^2~57^2~1 X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=07dd9223d97c9f9f384429cfef404085b8c4f5d5;p=firefly-linux-kernel-4.4.55.git RK2928 usb hcd modified --- diff --git a/arch/arm/mach-rk2928/devices.c b/arch/arm/mach-rk2928/devices.c index 5c670f4330df..eca32631660f 100755 --- a/arch/arm/mach-rk2928/devices.c +++ b/arch/arm/mach-rk2928/devices.c @@ -621,6 +621,51 @@ 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[] = { { @@ -711,6 +756,12 @@ static int __init rk2928_init_devices(void) #endif #ifdef CONFIG_LCDC_RK2928 platform_device_register(&device_lcdc); +#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) diff --git a/drivers/usb/dwc_otg/dwc_otg_cil.c b/drivers/usb/dwc_otg/dwc_otg_cil.c index ec4f27fb9981..9f44adc2796f 100755 --- a/drivers/usb/dwc_otg/dwc_otg_cil.c +++ b/drivers/usb/dwc_otg/dwc_otg_cil.c @@ -729,8 +729,8 @@ void dwc_otg_core_dev_init(dwc_otg_core_if_t *_core_if) dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 ); //ep1 tx fifo dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 ); //ep3 tx fifo dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x00800330 ); //ep7 tx fifo - dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x001003b0 ); //ep9 tx fifo + dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo + dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo #endif if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable) { diff --git a/drivers/usb/dwc_otg/dwc_otg_driver.c b/drivers/usb/dwc_otg/dwc_otg_driver.c index 34af78a3a4dd..84c360d55af3 100755 --- a/drivers/usb/dwc_otg/dwc_otg_driver.c +++ b/drivers/usb/dwc_otg/dwc_otg_driver.c @@ -1203,6 +1203,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_RK30 unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2); #endif +#ifdef CONFIG_ARCH_RK2928 + unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5); +#endif #ifdef CONFIG_ARCH_RK29 regval = * otg_phy_con1; @@ -1254,8 +1257,8 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) } clk_enable(ahbclk); - regval &= ~(0x01<<14); // exit suspend. - regval |= (0x01<<13); // software control + regval &= ~(0x01<<14); // enter suspend. + regval |= (0x01<<13); // software control enable. *otg_phy_con1 = regval; udelay(3); @@ -1291,6 +1294,34 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) clk_disable(phyclk); clk_disable(ahbclk); #endif +#endif +#ifdef CONFIG_ARCH_RK2928 +#ifndef CONFIG_USB20_HOST + otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON5); + /* + * disable usb host 2.0 phy if not support + */ + phyclk = clk_get(NULL, "otgphy1"); + if (IS_ERR(phyclk)) { + retval = PTR_ERR(phyclk); + DWC_ERROR("can't get USBPHY1 clock\n"); + goto fail; + } + clk_enable(phyclk); + + ahbclk = clk_get(NULL, "hclk_otg1"); + if (IS_ERR(ahbclk)) { + retval = PTR_ERR(ahbclk); + DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); + goto fail; + } + clk_enable(ahbclk); + + *otg_phy_con = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend. + udelay(3); + clk_disable(phyclk); + clk_disable(ahbclk); +#endif #endif dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL); @@ -1385,6 +1416,41 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device->phyclk = phyclk; dwc_otg_device->ahbclk = ahbclk; #endif +#ifdef CONFIG_ARCH_RK2928 + otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON5); + cru_set_soft_reset(SOFT_RST_USBPHY0, true); + cru_set_soft_reset(SOFT_RST_OTGC0, true); + cru_set_soft_reset(SOFT_RST_USBOTG0, true); + udelay(1); + + cru_set_soft_reset(SOFT_RST_USBOTG0, false); + cru_set_soft_reset(SOFT_RST_OTGC0, false); + cru_set_soft_reset(SOFT_RST_USBPHY0, false); + + phyclk = clk_get(NULL, "otgphy0"); + if (IS_ERR(phyclk)) { + retval = PTR_ERR(phyclk); + DWC_ERROR("can't get USBPHY0 clock\n"); + goto fail; + } + clk_enable(phyclk); + + ahbclk = clk_get(NULL, "hclk_otg0"); + if (IS_ERR(ahbclk)) { + retval = PTR_ERR(ahbclk); + DWC_ERROR("can't get USB otg0 ahb bus clock\n"); + goto fail; + } + clk_enable(ahbclk); + + /* + * Enable usb phy 0 + */ + *otg_phy_con = (0x01<<16); + + dwc_otg_device->phyclk = phyclk; + dwc_otg_device->ahbclk = ahbclk; +#endif /* * Map the DWC_otg Core memory into virtual address space. */ @@ -1498,6 +1564,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_HOST; #else dwc_otg_device->core_if->usb_mode = USB_MODE_NORMAL; +#ifdef CONFIG_DWC_OTG_DEFAULT_DEVICE + dwc_otg_device->core_if->usb_mode = USB_MODE_FORCE_DEVICE; +#endif #endif #endif @@ -1516,6 +1585,9 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) #endif #ifdef CONFIG_ARCH_RK30 USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS); +#endif +#ifdef CONFIG_ARCH_RK2928 + USB_IOMUX_INIT(GPIO3C1_OTG_DRVVBUS_NAME, GPIO3C_OTG_DRVVBUS); #endif /* * Initialize the HCD @@ -1557,6 +1629,26 @@ static __devinit int dwc_otg_driver_probe(struct platform_device *pdev) *otg_phy_con1 &= ~(0x01<<3); // enter suspend. } #endif +#endif +#ifdef CONFIG_ARCH_RK30 +#ifndef CONFIG_DWC_OTG_DEVICE_ONLY + if(dwc_otg_device->hcd->host_enabled == 0) + { + clk_disable(dwc_otg_device->phyclk); + clk_disable(dwc_otg_device->ahbclk); + *otg_phy_con = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend. + } +#endif +#endif +#ifdef CONFIG_ARCH_RK2928 +#ifndef CONFIG_DWC_OTG_DEVICE_ONLY + if(dwc_otg_device->hcd->host_enabled == 0) + { + clk_disable(dwc_otg_device->phyclk); + clk_disable(dwc_otg_device->ahbclk); + *otg_phy_con = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend. + } +#endif #endif return 0; fail: @@ -2044,16 +2136,20 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) */ #ifdef CONFIG_ARCH_RK29 unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON); + otgreg = * otg_phy_con1; + otgreg |= (0x01<<13); // software control enable + otgreg |= (0x01<<14); // exit suspend. + otgreg &= ~(0x01<<13); // software control disable + *otg_phy_con1 = otgreg; #endif #ifdef CONFIG_ARCH_RK30 unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2); + *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend. +#endif +#ifdef CONFIG_ARCH_RK2928 + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON5); + *otg_phy_con1 = (0x01<<16); // exit suspend. #endif - - otgreg = * otg_phy_con1; - otgreg |= (0x01<<13); // software control - otgreg |= (0x01<<14); // exit suspend. - otgreg &= ~(0x01<<13); // software control - *otg_phy_con1 = otgreg; #if 0 *otg_phy_con1 |= (0x01<<2); *otg_phy_con1 |= (0x01<<3); // exit suspend. @@ -2080,6 +2176,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_RK30 *(unsigned int*)(USBGRF_UOC1_CON2+4) = ((1<<5)|((1<<5)<<16)); #endif +#ifdef CONFIG_ARCH_RK2928 + *(unsigned int*)(USBGRF_UOC1_CON5-4) = ((1<<5)|((1<<5)<<16)); +#endif if (dwc_otg_device == 0) { dev_err(dev, "kmalloc of dwc_otg_device failed\n"); @@ -2104,6 +2203,9 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) #ifdef CONFIG_ARCH_RK30 ahbclk = clk_get(NULL, "hclk_otg1"); #endif +#ifdef CONFIG_ARCH_RK2928 + ahbclk = clk_get(NULL, "hclk_otg1"); //check +#endif if (IS_ERR(ahbclk)) { retval = PTR_ERR(ahbclk); DWC_ERROR("can't get USBOTG1 ahb bus clock\n"); @@ -2242,9 +2344,15 @@ static __devinit int host20_driver_probe(struct platform_device *pdev) #ifndef CONFIG_USB20_HOST_EN clk_disable(phyclk); clk_disable(ahbclk); +#if defined(CONFIG_ARCH_RK29) otgreg &= ~(0x01<<14); // suspend. - otgreg |= (0x01<<13); // software control + otgreg |= (0x01<<13); // software control enable *otg_phy_con1 = otgreg; +#elif defined(CONFIG_ARCH_RK30) + *otg_phy_con1 = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend. +#elif defined(CONFIG_ARCH_RK2928) + *otg_phy_con1 = ((0x01<<0)|(0x00<<1)|(0x05<<4))|(((0x01<<0)|(0x01<<1)|(0x07<<4))<<16); // enter suspend. +#endif #endif return 0; diff --git a/drivers/usb/dwc_otg/dwc_otg_hcd.c b/drivers/usb/dwc_otg/dwc_otg_hcd.c index e85ada78ead6..4c84033c2a59 100755 --- a/drivers/usb/dwc_otg/dwc_otg_hcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_hcd.c @@ -617,6 +617,24 @@ static int32_t dwc_otg_phy_suspend_cb( void *_p, int suspend) udelay(3); DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); } +#endif +#ifdef CONFIG_ARCH_RK2928 + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5); + if(exitsuspend && (pcd->phy_suspend == 1)) { + clk_enable(pcd->otg_dev->ahbclk); + clk_enable(pcd->otg_dev->phyclk); + pcd->phy_suspend = 0; + *otg_phy_con1 = (0x01<<16); // exit suspend. + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + if( !exitsuspend && (pcd->phy_suspend == 0)) { + pcd->phy_suspend = 1; + *otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend. + udelay(3); + clk_disable(pcd->otg_dev->phyclk); + clk_disable(pcd->otg_dev->ahbclk); + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } #endif return suspend; } @@ -663,7 +681,7 @@ static struct tasklet_struct reset_tasklet = { .func = reset_tasklet_func, .data = 0, }; -#ifdef CONFIG_ARCH_RK30 +#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928) static void dwc_otg_hcd_enable(struct work_struct *work) { dwc_otg_hcd_t *dwc_otg_hcd; @@ -721,7 +739,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata) local_irq_save(flags); // DWC_PRINT("%s hprt %x, grfstatus 0x%x\n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22)); +#ifdef CONFIG_ARCH_RK30 if(usbgrf_status & (7<<22)){ +#else //CONFIG_ARCH_RK2928 + if(usbgrf_status & (7<<12)){ +#endif // usb device connected dwc_otg_hcd->host_setenable = 1; } @@ -732,7 +754,11 @@ static void dwc_otg_hcd_connect_detect(unsigned long pdata) } if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){ +#ifdef CONFIG_ARCH_RK30 DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22)); +#else //CONFIG_ARCH_RK2928 + DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<12)); +#endif schedule_delayed_work(&dwc_otg_hcd->host_enable_work, 8); } // dwc_otg_hcd->connect_detect_timer.expires = jiffies + (HZ<<1); /* 1 s */ @@ -1116,6 +1142,24 @@ static int32_t host20_phy_suspend_cb( void *_p, int suspend) udelay(3); DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); } +#endif +#ifdef CONFIG_ARCH_RK2928 + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5); + if(exitsuspend && (pcd->phy_suspend == 1)) { + clk_enable(pcd->otg_dev->ahbclk); + clk_enable(pcd->otg_dev->phyclk); + pcd->phy_suspend = 0; + *otg_phy_con1 = (0x01<<16); // exit suspend. + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + if( !exitsuspend && (pcd->phy_suspend == 0)) { + pcd->phy_suspend = 1; + *otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend. + udelay(3); + clk_disable(pcd->otg_dev->phyclk); + clk_disable(pcd->otg_dev->ahbclk); + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } #endif return suspend; } @@ -1266,7 +1310,7 @@ int __devinit host20_hcd_init(struct device *dev) goto error3; } -#ifdef CONFIG_ARCH_RK30 +#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928) dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect; dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd); init_timer( &dwc_otg_hcd->connect_detect_timer); diff --git a/drivers/usb/dwc_otg/dwc_otg_pcd.c b/drivers/usb/dwc_otg/dwc_otg_pcd.c index c89715f0e4dc..35729af45d88 100755 --- a/drivers/usb/dwc_otg/dwc_otg_pcd.c +++ b/drivers/usb/dwc_otg/dwc_otg_pcd.c @@ -1657,7 +1657,24 @@ int dwc_otg20phy_suspend( int exitsuspend ) DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); } #endif - +#ifdef CONFIG_ARCH_RK2928 + unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5); + if(exitsuspend && (pcd->phy_suspend == 1)) { + clk_enable(pcd->otg_dev->ahbclk); + clk_enable(pcd->otg_dev->phyclk); + pcd->phy_suspend = 0; + *otg_phy_con1 = (0x01<<16); // exit suspend. + DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n"); + } + if( !exitsuspend && (pcd->phy_suspend == 0)) { + pcd->phy_suspend = 1; + *otg_phy_con1 = 0x55 |(0x7f<<16); // enter suspend. + udelay(3); + clk_disable(pcd->otg_dev->phyclk); + clk_disable(pcd->otg_dev->ahbclk); + DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n"); + } +#endif return pcd->phy_suspend; } diff --git a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h index e3f7d6e99640..1fa1f5c886a6 100755 --- a/drivers/usb/dwc_otg/linux/dwc_otg_plat.h +++ b/drivers/usb/dwc_otg/linux/dwc_otg_plat.h @@ -67,6 +67,15 @@ #define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b) #endif +#ifdef CONFIG_ARCH_RK2928 +#include +#define GRF_REG_BASE RK2928_GRF_BASE +#define USBOTG_SIZE RK2928_USBOTG20_SIZE +#define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0x14c) +#define USBGRF_UOC0_CON5 (GRF_REG_BASE+0x17c) +#define USBGRF_UOC1_CON5 (GRF_REG_BASE+0x194) +#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b) +#endif /** * @file *