#include "dwc_otg_cil.h"
#include "dwc_otg_pcd.h"
#include "dwc_otg_hcd.h"
-#ifdef CONFIG_ARCH_RK29
#include <mach/cru.h>
-#endif
//#define DWC_DRIVER_VERSION "2.60a 22-NOV-2006"
//#define DWC_DRIVER_VERSION "2.70 2009-12-31"
#define DWC_DRIVER_VERSION "3.00 2010-12-12 rockchip"
#ifdef DWC_BOTH_HOST_SLAVE
extern void hcd_start( dwc_otg_core_if_t *_core_if );
-extern int rk28_usb_suspend( int exitsuspend );
+extern int dwc_otg20phy_suspend( int exitsuspend );
extern void hub_disconnect_device(struct usb_hub *hub);
static ssize_t force_usb_mode_show(struct device_driver *_drv, char *_buf)
}
if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
{
- rk28_usb_suspend( 1 );
+ dwc_otg20phy_suspend( 1 );
}
del_timer(&otg_dev->pcd->check_vbus_timer);
// force disconnect
core_if->usb_mode = new_mode;
if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
{
- rk28_usb_suspend( 1 );
+ dwc_otg20phy_suspend( 1 );
}
del_timer(&otg_dev->pcd->check_vbus_timer);
dwc_otg_set_gusbcfg(core_if, new_mode);
{
if((otg_dev->pcd)&&(otg_dev->pcd->phy_suspend == 1))
{
- rk28_usb_suspend( 1 );
+ dwc_otg20phy_suspend( 1 );
}
core_if->usb_mode = new_mode;
dwc_otg_set_gusbcfg(core_if, new_mode);
clk_disable(otg_dev->phyclk);
clk_put(otg_dev->ahbclk);
clk_disable(otg_dev->ahbclk);
+#ifdef CONFIG_ARCH_RK29
clk_put(otg_dev->busclk);
clk_disable(otg_dev->busclk);
+#endif
kfree(otg_dev);
/*
unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
#endif
#ifdef CONFIG_ARCH_RK30
- unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
+ unsigned int * otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2);
#endif
- regval = * otg_phy_con1;
-#ifdef CONFIG_ARCH_RK29
+#ifdef CONFIG_ARCH_RK29
+ regval = * otg_phy_con1;
#ifndef CONFIG_USB11_HOST
/*
* disable usb host 1.1 controller if not support
#endif
#endif
+#ifdef CONFIG_ARCH_RK30
+#ifndef CONFIG_USB20_HOST
+ otg_phy_con = (unsigned int*)(USBGRF_UOC1_CON2);
+ /*
+ * 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<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend.
+ udelay(3);
+ clk_disable(phyclk);
+ clk_disable(ahbclk);
+#endif
+#endif
dwc_otg_device = kmalloc(sizeof(dwc_otg_device_t), GFP_KERNEL);
if (dwc_otg_device == 0)
dwc_otg_device->phyclk = phyclk;
dwc_otg_device->ahbclk = ahbclk;
dwc_otg_device->busclk = busclk;
-#endif
+#endif
+#ifdef CONFIG_ARCH_RK30
+ otg_phy_con = (unsigned int*)(USBGRF_UOC0_CON2);
+ 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<<2)<<16);
+
+ dwc_otg_device->phyclk = phyclk;
+ dwc_otg_device->ahbclk = ahbclk;
+#endif
/*
* Map the DWC_otg Core memory into virtual address space.
*/
if (!res_base)
goto fail;
- dwc_otg_device->base =
- ioremap(res_base->start,USBOTG_SIZE);
+ dwc_otg_device->base = ioremap(res_base->start,USBOTG_SIZE);
if (dwc_otg_device->base == NULL)
{
dev_err(dev, "ioremap() failed\n");
}
#ifndef CONFIG_DWC_OTG_HOST_ONLY
-extern int rk28_usb_suspend( int exitsuspend );
+extern int dwc_otg20phy_suspend( int exitsuspend );
static int dwc_otg_driver_suspend(struct platform_device *_dev , pm_message_t state )
{
struct device *dev = &_dev->dev;
/* Clear any pending interrupts */
dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF);
dwc_otg_disable_global_interrupts(core_if);
- rk28_usb_suspend(0);
+ dwc_otg20phy_suspend(0);
del_timer(&otg_dev->pcd->check_vbus_timer);
return 0;
}
#ifndef CONFIG_DWC_OTG_HOST_ONLY
- rk28_usb_suspend(1);
+ dwc_otg20phy_suspend(1);
/* soft disconnect */
/* 20100226,HSL@RK,if not disconnect,when usb cable in,will auto reconnect
* 20090925,add vbus test code.500ms ¼ä¸ô.
* 20100122,HSL@RK,hard reset usb controller and phy.
*/
-int rk28_usb_suspend( int exitsuspend )
+int dwc_otg20phy_suspend( int exitsuspend )
{
dwc_otg_pcd_t *pcd = s_pcd;
#ifdef CONFIG_ARCH_RK29
unsigned int * otg_phy_con1 = (unsigned int*)(USB_GRF_CON);
-#endif
-#ifdef CONFIG_ARCH_RK30
- unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
-#endif
if(exitsuspend && (pcd->phy_suspend == 1)) {
clk_enable(pcd->otg_dev->ahbclk);
clk_enable(pcd->otg_dev->phyclk);
//debug_print("disable usb phy\n");
DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
-
- return pcd->phy_suspend;
-}
-void rk28_usb_force_resume( void )
-{
- dwc_otg_pcd_t *pcd = s_pcd;
- if( pcd ) {
- del_timer(&pcd->check_vbus_timer);
+#endif
+#ifdef CONFIG_ARCH_RK30
+ unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
+ 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<<2)<<16); // exit suspend.
+// *otg_phy_con1 |= (0x01<<3);
+// *otg_phy_con1 &= ~(0x01<<2);
+
+ /* 20091011,reenable usb phy ,will raise reset intr */
+// DWC_PRINT("enable usb phy 0x%x\n", *otg_phy_con1);
+ DWC_DEBUGPL(DBG_PCDV, "enable usb phy\n");
}
- mdelay( 10 );
- if( pcd ) {
+ if( !exitsuspend && (pcd->phy_suspend == 0)) {
pcd->phy_suspend = 1;
- pcd->vbus_status = 0;
- dwc_otg_pcd_start_vbus_timer(pcd);
+ *otg_phy_con1 = ((0x01<<2)|(0x00<<3)|(0x05<<6))|(((0x01<<2)|(0x01<<3)|(0x07<<6))<<16); // enter suspend.
+ udelay(3);
+ clk_disable(pcd->otg_dev->phyclk);
+ clk_disable(pcd->otg_dev->ahbclk);
+ //*otg_phy_con1 &= ~(0x01<<2);
+// DWC_PRINT("disable usb phy 0x%x\n", *otg_phy_con1);
+ DWC_DEBUGPL(DBG_PCDV, "disable usb phy\n");
}
+#endif
+
+ return pcd->phy_suspend;
}
-
int dwc_otg_reset( void )
{
dwc_otg_pcd_t * pcd = s_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 for 500ms */
- rk28_usb_suspend( 0 );
+ dwc_otg20phy_suspend( 0 );
_pcd->check_vbus_timer.expires = jiffies + (HZ/2); /* 500 ms */
} else if( _pcd->phy_suspend == 1 ) {
- rk28_usb_suspend( 1 );
+ dwc_otg20phy_suspend( 1 );
/*20100325 yk@rk,delay 2-->8,for host connect id detect*/
_pcd->check_vbus_timer.expires = jiffies + 8; /* 20091127,HSL@RK,1-->2 */
dctl_data_t dctl = {.d32=0};
//dsts_data_t gsts;
unsigned long flags;
+ local_irq_save(flags);
#ifdef CONFIG_ARCH_RK30
unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
#endif
if(usbgrf_status &0x20000){ // bvalid
/* if usb not connect before ,then start connect */
if( _pcd->vbus_status == 0 ) {
- dwc_otg_msc_lock(_pcd);
DWC_PRINT("********vbus detect*********************************************\n");
+ dwc_otg_msc_lock(_pcd);
_pcd->vbus_status = 1;
if(_pcd->conn_en)
- {
- if( _pcd->phy_suspend == 1 ) {
-// rk28_usb_suspend( 1 );
- }
- schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
- _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
- }
-
- } else if((_pcd->conn_status>0)&&(_pcd->conn_status <3)) {
- //dwc_otg_msc_unlock(_pcd);
+ goto connect;
+ }
+ else if((_pcd->conn_en)&&(_pcd->conn_status>=0)&&(_pcd->conn_status <3)){
DWC_PRINT("********soft reconnect******************************************\n");
- //_pcd->vbus_status =0;
-
- /* soft disconnect */
- dctl.d32 = dwc_read_reg32( &core_if->dev_if->dev_global_regs->dctl );
- dctl.b.sftdiscon = 1;
- dwc_write_reg32( &core_if->dev_if->dev_global_regs->dctl, dctl.d32 );
- /* Clear any pending interrupts */
- dwc_write_reg32( &core_if->core_global_regs->gintsts, 0xFFFFFFFF);
- if(_pcd->conn_en)
- {
- schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
- _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
- }
- }
- else if((_pcd->conn_en)&&(_pcd->conn_status == 0))
- {
- DWC_PRINT("********vbus detect ccccc*********************************************\n");
-
- schedule_delayed_work( &_pcd->reconnect , 8 ); /* delay 1 jiffies */
- _pcd->check_vbus_timer.expires = jiffies + (HZ<<1); /* 1 s */
+ goto connect;
}
- else if(_pcd->conn_status ==3)
- {
+ else if(_pcd->conn_status ==3){
//*Á¬½Ó²»ÉÏʱÊÍ·ÅËø£¬ÔÊÐíϵͳ½øÈë¶þ¼¶Ë¯Ãߣ¬yk@rk,20100331*//
dwc_otg_msc_unlock(_pcd);
_pcd->conn_status++;
/* 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 */
- rk28_usb_suspend( 0 );
+ 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