dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 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
+#ifdef CONFIG_ARCH_RK2928 //@lyz the same with RK30
+ /* Configure data FIFO sizes, RK30 otg has 0x3cc dwords total */
+ dwc_write_reg32( &global_regs->grxfsiz, 0x00000120 );
+ dwc_write_reg32( &global_regs->gnptxfsiz, 0x00100120 ); //ep0 tx fifo
+ dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[0], 0x01000130 ); //ep1 tx fifo 256*4Byte
+ dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[1], 0x00800230 ); //ep3 tx fifo 128*4Byte
+ dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[2], 0x008002b0 ); //ep5 tx fifo 128*4Byte
+ dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[3], 0x00800330 ); //ep7 tx fifo 128*4Byte
+ dwc_write_reg32( &global_regs->dptxfsiz_dieptxf[4], 0x001003b0 ); //ep9 tx fifo 16*4Byte
#endif
if(_core_if->en_multiple_tx_fifo && _core_if->dma_enable)
{
#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;
clk_disable(phyclk);
clk_disable(ahbclk);
#endif
+#endif
+//need to be checked @wlf
+#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);
dwc_otg_device->phyclk = phyclk;
dwc_otg_device->ahbclk = ahbclk;
#endif
+//need to be checked @wlf
+#if 0//def 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.
*/
#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
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
#if 0
*otg_phy_con1 |= (0x01<<2);
*otg_phy_con1 |= (0x01<<3); // exit suspend.
#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");
#ifdef CONFIG_ARCH_RK30
ahbclk = clk_get(NULL, "hclk_otg1");
#endif
+#ifdef CONFIG_ARCH_RK2928
+ ahbclk = clk_get(NULL, "hclk_otg1"); //need to be checked @wlf
+#endif
if (IS_ERR(ahbclk)) {
retval = PTR_ERR(ahbclk);
DWC_ERROR("can't get USBOTG1 ahb bus clock\n");
#endif
#ifdef CONFIG_ARCH_RK30
USB_IOMUX_INIT(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);
-#ifdef CONFIG_MACH_RK30_DS1001B
- USB_IOMUX_INIT(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_GPIO0A5);
- if(gpio_request(RK30_PIN0_PA5,"host_drv")<0){
- DWC_ERROR("request of host power control failed\n");
- gpio_free(RK30_PIN0_PA5);
- }
- gpio_direction_output(RK30_PIN0_PA5, GPIO_HIGH);
- gpio_set_value(RK30_PIN0_PA5, GPIO_HIGH);
-#endif
#endif
/*
* Initialize the DWC_otg core.
#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;
return 0;
}
hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+#ifdef CONFIG_USB_SUSPEND
if((!dwc_otg_hcd->host_enabled)||(!hprt0.b.prtena))
return 0;
+#endif
DWC_PRINT("%s suspend, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
if(hprt0.b.prtconnsts) // usb device connected
{
DWC_PRINT("%s, usb device mode\n", __func__);
return 0;
}
+#ifdef CONFIG_USB_SUSPEND
if(!dwc_otg_hcd->host_enabled)
return 0;
+#endif
#ifndef CONFIG_DWC_REMOTE_WAKEUP
clk_enable(core_if->otg_dev->phyclk);
clk_enable(core_if->otg_dev->ahbclk);
dwc_write_reg32(&core_if->core_global_regs->gintmsk, gintmsk.d32);
hprt0.d32 = dwc_read_reg32(core_if->host_if->hprt0);
+#ifdef CONFIG_USB_SUSPEND
if(!hprt0.b.prtena)
return 0;
+#endif
DWC_PRINT("%s resume, HPRT0:0x%x\n",hcd->self.bus_name,hprt0.d32);
if(hprt0.b.prtconnsts)
{
udelay(3);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
+#endif
+#if 0//def 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;
}
.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;
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;
}
}
if(dwc_otg_hcd->host_setenable != dwc_otg_hcd->host_enabled){
- DWC_PRINT("%s schedule delaywork \n", __func__, dwc_read_reg32(core_if->host_if->hprt0), usbgrf_status& (7<<22));
+#ifdef CONFIG_ARCH_RK30
+ DWC_PRINT("%s schedule delaywork 0x%x, 0x%x\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 */
udelay(3);
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
+#endif
+#if 0//def 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;
}
goto error3;
}
-#ifdef CONFIG_ARCH_RK30
+#if defined(CONFIG_ARCH_RK30) || defined(CONFIG_ARCH_RK2928)
dwc_otg_hcd->host_setenable = 1;
dwc_otg_hcd->connect_detect_timer.function = dwc_otg_hcd_connect_detect;
dwc_otg_hcd->connect_detect_timer.data = (unsigned long)(dwc_otg_hcd);
* This function assigns periodic Tx FIFO to an periodic EP
* in shared Tx FIFO mode
*/
- #ifdef CONFIG_ARCH_RK30
+ #if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
static uint32_t assign_perio_tx_fifo(dwc_otg_core_if_t *core_if)
{
uint32_t PerTxMsk = 1;
* This function assigns periodic Tx FIFO to an periodic EP
* in Dedicated FIFOs mode
*/
-#ifdef CONFIG_ARCH_RK30
+#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
static uint32_t assign_tx_fifo(dwc_otg_core_if_t *core_if)
{
uint32_t TxMsk = 1;
if(ep->dwc_ep.is_in)
{
-#ifndef CONFIG_ARCH_RK29
+#if defined(CONFIG_ARCH_RK30)||defined(CONFIG_ARCH_RK2928) //@lyz
if(!pcd->otg_dev->core_if->en_multiple_tx_fifo)
{
ep->dwc_ep.tx_fifo_num = 0;
* EP8&EP9 of rk30 are IN&OUT ep, we use ep8 as OUT EP default
*/
#ifdef CONFIG_ARCH_RK30
+ if(i == 8)
+ continue;
+ #endif
+ #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
if(i == 8)
continue;
#endif
* EP8&EP9 of rk30 are IN&OUT ep, we use ep9 as IN EP default
*/
#ifdef CONFIG_ARCH_RK30
+ if(i == 9)
+ continue;
+ #endif
+ #ifdef CONFIG_ARCH_RK2928 //@lyz the same with rk30
if(i == 9)
continue;
#endif
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.
+ // *otg_phy_con1 = 0x1D5 |(0x1ff<<16); // enter suspend. enable dm,dp debug_wlf @2012.8.10
+ 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;
}
return;
}
+#endif
+#ifdef CONFIG_ARCH_RK2928
+static void dwc_otg_pcd_check_vbus_timer( unsigned long pdata )
+{
+ dwc_otg_pcd_t * _pcd = (dwc_otg_pcd_t *)pdata;
+ unsigned long flags;
+ unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);//@lyz USBGRF_SOC_STATUS0½á¹¹Óбä
+
+ local_irq_save(flags);
+ _pcd->check_vbus_timer.expires = jiffies + (HZ); /* 1 s */
+ if((usbgrf_status &(1<<10)) == 0){ // id low //@lyz SOC_STATUS0[10] represents id_dig
+
+ if( _pcd->phy_suspend)
+ dwc_otg20phy_suspend( 1 );
+ }
+ else if(usbgrf_status & (1<<7)){ //@lyz SOC_STATUS0[7] represents bvalid
+ /* if usb not connect before ,then start connect */
+ if( _pcd->vbus_status == 0 ) {
+ DWC_PRINT("********vbus detect*********************************************\n");
+ dwc_otg_msc_lock(_pcd);
+ _pcd->vbus_status = 1;
+ if(_pcd->conn_en)
+ goto connect;
+ else
+ dwc_otg20phy_suspend( 0 );
+ }
+ else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
+ DWC_PRINT("********soft reconnect******************************************\n");
+ goto connect;
+ }
+ else if(_pcd->conn_status ==3){
+ //*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
+ dwc_otg_msc_unlock(_pcd);
+ _pcd->conn_status++;
+ if((dwc_read_reg32((uint32_t*)((uint8_t *)_pcd->otg_dev->base + DWC_OTG_HOST_PORT_REGS_OFFSET))&0xc00) == 0xc00)
+ _pcd->vbus_status = 2;
+ }
+ }else {
+ _pcd->vbus_status = 0;
+ if(_pcd->conn_status)
+ {
+ _pcd->conn_status = 0;
+ dwc_otg_msc_unlock(_pcd);
+ }
+ /* every 500 ms open usb phy power and start 1 jiffies timer to get vbus */
+ if( _pcd->phy_suspend == 0 )
+ /* no vbus detect here , close usb phy */
+ dwc_otg20phy_suspend( 0 );
+ }
+ add_timer(&_pcd->check_vbus_timer);
+ local_irq_restore(flags);
+ return;
+
+connect:
+ if( _pcd->phy_suspend == 1 )
+ dwc_otg20phy_suspend( 1 );
+ schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
+ _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
+ add_timer(&_pcd->check_vbus_timer);
+ local_irq_restore(flags);
+ return;
+}
+
#endif
#ifdef CONFIG_ARCH_RK29
/*
return bus_status;
}
+EXPORT_SYMBOL(dwc_otg_check_dpdm);
+#endif
+#ifdef CONFIG_ARCH_RK2928
+int dwc_otg_check_dpdm(void)
+{
+ static uint8_t * reg_base = 0;
+ volatile unsigned int * otg_dctl;
+ volatile unsigned int * otg_gotgctl;
+ volatile unsigned int * otg_hprt0;
+ int bus_status = 0;
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON5);//@lyz modify UOC0_CON2 to CON5
+
+ // softreset & clockgate //@lyz modify RK2928_CRU_BASE
+ *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(7<<5); // otg0 phy clkgate
+ udelay(3);
+ *(unsigned int*)(RK2928_CRU_BASE+0x120) = ((7<<5)<<16)|(0<<5); // otg0 phy clkgate
+ dsb();
+ *(unsigned int*)(RK2928_CRU_BASE+0xd4) = ((1<<5)<<16); // otg0 phy clkgate
+ *(unsigned int*)(RK2928_CRU_BASE+0xe4) = ((1<<13)<<16); // otg0 hclk clkgate
+ *(unsigned int*)(RK2928_CRU_BASE+0xf4) = ((3<<10)<<16); // hclk usb clkgate//@lyz to be check
+
+ // exit phy suspend
+ *otg_phy_con1 = ((0x01<<0)<<16); // exit suspend.@lyz
+
+ // soft connect
+ if(reg_base == 0){
+ reg_base = ioremap(RK2928_USBOTG20_PHYS,USBOTG_SIZE);//@lyz
+ if(!reg_base){
+ bus_status = -1;
+ goto out;
+ }
+ }
+ mdelay(105);
+ printk("regbase %p 0x%x, otg_phy_con%p, 0x%x\n",
+ reg_base, *(reg_base), otg_phy_con1, *otg_phy_con1);
+ otg_dctl = (unsigned int * )(reg_base+0x804);
+ otg_gotgctl = (unsigned int * )(reg_base);
+ otg_hprt0 = (unsigned int * )(reg_base + DWC_OTG_HOST_PORT_REGS_OFFSET);
+ if(*otg_gotgctl &(1<<19)){
+ bus_status = 1;
+ *otg_dctl &= ~(0x01<<1);//@lyz exit soft-disconnect mode
+ mdelay(50); // delay about 10ms
+ // check dp,dm
+ if((*otg_hprt0 & 0xc00)==0xc00)//@lyz check hprt[11:10]
+ bus_status = 2;
+ }
+out:
+ return bus_status;
+}
+
EXPORT_SYMBOL(dwc_otg_check_dpdm);
#endif
void dwc_otg_pcd_start_vbus_timer( dwc_otg_pcd_t * _pcd )
#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
#endif
+#ifdef CONFIG_ARCH_RK2928
+#include <mach/iomux.h>
+#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
*