static void usbotg_wakeup_event_clear(void);
extern int clk_get_usecount(struct clk *clk);
-
/* Beginning of Common operation for DR port */
/*
.usb_wakeup_exhandle = usbotg_wakeup_event_clear,
};
+static void fsl_platform_otg_set_usb_phy_dis(
+ struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ u32 usb_phy_ctrl_dcdt = 0;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0) {
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_CLR);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET);
+
+ udelay(300);
+
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+
+ UOG_USBSTS |= (1 << 7);
+
+ while ((UOG_USBSTS & (1 << 7)) == 0)
+ ;
+
+ udelay(2);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR);
+
+ __raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+
+ }
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
+}
+
static void usbotg_internal_phy_clock_gate(bool on)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
#ifdef CONFIG_USB_EHCI_ARC_OTG
/* Beginning of host related operation for DR port */
-static void _host_platform_suspend(struct fsl_usb2_platform_data *pdata)
+static void _host_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
u32 tmp;
+ u32 index = 0;
+
+ /* before we set and then clear PWD bit,
+ * we must wait LS to be suspend */
+ if ((UOG_PORTSC1 & (3 << 26)) != (1 << 26)) {
+ while (((UOG_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_J_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ } else {
+ while (((UOG_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_K_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
tmp = (BM_USBPHY_PWD_TXPWDFS
| BM_USBPHY_PWD_TXPWDIBIAS
| BM_USBPHY_PWD_RXPWDDIFF
| BM_USBPHY_PWD_RXPWDRX);
__raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ fsl_platform_otg_set_usb_phy_dis(pdata, 0);
}
-static void _host_platform_resume(struct fsl_usb2_platform_data *pdata)
+static void _host_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
{
- void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
- u32 tmp;
+ u32 index = 0;
- tmp = (BM_USBPHY_PWD_TXPWDFS
- | BM_USBPHY_PWD_TXPWDIBIAS
- | BM_USBPHY_PWD_TXPWDV2I
- | BM_USBPHY_PWD_RXPWDENV
- | BM_USBPHY_PWD_RXPWD1PT1
- | BM_USBPHY_PWD_RXPWDDIFF
- | BM_USBPHY_PWD_RXPWDRX);
- __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+ if ((UOG_PORTSC1 & (3 << 26)) != (2 << 26))
+ return ;
+
+ while ((UOG_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ msleep(1);
+ index++;
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
+
+ msleep(1);
+ fsl_platform_otg_set_usb_phy_dis(pdata, 1);
}
static void _host_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
#ifdef CONFIG_USB_EHCI_ARC_OTG
dr_utmi_config.operating_mode = DR_HOST_MODE;
dr_utmi_config.wake_up_enable = _host_wakeup_enable;
- dr_utmi_config.platform_suspend = _host_platform_suspend;
- dr_utmi_config.platform_resume = _host_platform_resume;
+ dr_utmi_config.platform_rh_suspend = _host_platform_rh_suspend;
+ dr_utmi_config.platform_rh_resume = _host_platform_rh_resume;
+ dr_utmi_config.platform_set_disconnect_det = fsl_platform_otg_set_usb_phy_dis;
dr_utmi_config.phy_lowpower_suspend = _host_phy_lowpower_suspend;
dr_utmi_config.is_wakeup_event = _is_host_wakeup;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
#ifdef CONFIG_USB_GADGET_ARC
dr_utmi_config.operating_mode = DR_UDC_MODE;
dr_utmi_config.wake_up_enable = _device_wakeup_enable;
- dr_utmi_config.platform_suspend = NULL;
- dr_utmi_config.platform_resume = NULL;
+ dr_utmi_config.platform_rh_suspend = NULL;
+ dr_utmi_config.platform_rh_resume = NULL;
+ dr_utmi_config.platform_set_disconnect_det = NULL;
dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
dr_utmi_config.is_wakeup_event = _is_device_wakeup;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
extern int clk_get_usecount(struct clk *clk);
static struct fsl_usb2_platform_data usbh1_config;
+static void fsl_platform_h1_set_usb_phy_dis(
+ struct fsl_usb2_platform_data *pdata, bool enable)
+{
+ u32 usb_phy_ctrl_dcdt = 0;
+ void __iomem *anatop_base_addr = MX6_IO_ADDRESS(ANATOP_BASE_ADDR);
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0) {
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_CLR);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_SET);
+
+ udelay(300);
+
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+
+ UH1_USBSTS |= (1 << 7);
+
+ while ((UH1_USBSTS & (1 << 7)) == 0)
+ ;
+
+ udelay(2);
+
+ __raw_writel(BM_USBPHY_PWD_RXPWDENV,
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_PWD_CLR);
+
+ __raw_writel(BM_ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
+ anatop_base_addr + HW_ANADIG_USB2_PLL_480_CTRL_SET);
+
+ }
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
+}
+
static void usbh1_internal_phy_clock_gate(bool on)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
}
}
-static void usbh1_platform_suspend(struct fsl_usb2_platform_data *pdata)
+static void usbh1_platform_rh_suspend(struct fsl_usb2_platform_data *pdata)
{
void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
u32 tmp;
+ u32 index = 0;
+
+ /* before we set and then clear PWD bit,
+ * we must wait LS to be J */
+ if ((UH1_PORTSC1 & (3 << 26)) != (1 << 26)) {
+ while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_J_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ } else {
+ while (((UH1_PORTSC1 & PORTSC_LS_MASK) != PORTSC_LS_K_STATE) &&
+ (index < 1000)) {
+ index++;
+ udelay(4);
+ }
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
tmp = (BM_USBPHY_PWD_TXPWDFS
| BM_USBPHY_PWD_TXPWDIBIAS
| BM_USBPHY_PWD_RXPWDDIFF
| BM_USBPHY_PWD_RXPWDRX);
__raw_writel(tmp, phy_reg + HW_USBPHY_PWD_SET);
+
+ __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+
+ fsl_platform_h1_set_usb_phy_dis(pdata, 0);
}
-static void usbh1_platform_resume(struct fsl_usb2_platform_data *pdata)
+static void usbh1_platform_rh_resume(struct fsl_usb2_platform_data *pdata)
{
- void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY1_BASE_ADDR);
- u32 tmp;
+ u32 index = 0;
- tmp = (BM_USBPHY_PWD_TXPWDFS
- | BM_USBPHY_PWD_TXPWDIBIAS
- | BM_USBPHY_PWD_TXPWDV2I
- | BM_USBPHY_PWD_RXPWDENV
- | BM_USBPHY_PWD_RXPWD1PT1
- | BM_USBPHY_PWD_RXPWDDIFF
- | BM_USBPHY_PWD_RXPWDRX);
- __raw_writel(tmp, phy_reg + HW_USBPHY_PWD_CLR);
+ if ((UH1_PORTSC1 & (3 << 26)) != (2 << 26))
+ return ;
+
+ while ((UH1_PORTSC1 & PORTSC_PORT_FORCE_RESUME)
+ && (index < 1000)) {
+ msleep(1);
+ index++;
+ }
+
+ if (index >= 1000)
+ printk(KERN_INFO "%s big error\n", __func__);
+
+ msleep(1);
+ fsl_platform_h1_set_usb_phy_dis(pdata, 1);
}
static void _phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
.power_budget = 500, /* 500 mA max power */
.wake_up_enable = _wake_up_enable,
.usb_clock_for_pm = usbh1_clock_gate,
- .platform_suspend = usbh1_platform_suspend,
- .platform_resume = usbh1_platform_resume,
+ .platform_rh_suspend = usbh1_platform_rh_suspend,
+ .platform_rh_resume = usbh1_platform_rh_resume,
+ .platform_set_disconnect_det = fsl_platform_h1_set_usb_phy_dis,
.phy_lowpower_suspend = _phy_lowpower_suspend,
.is_wakeup_event = _is_usbh1_wakeup,
.wakeup_handler = h1_wakeup_handler,
void fsl_platform_set_usb_phy_dis(struct fsl_usb2_platform_data *pdata,
bool enable)
{
+ u32 usb_phy_ctrl_dcdt = 0;
/* for HSIC, we do not need to enable disconnect detection */
if (pdata->phy_mode == FSL_USB2_PHY_HSIC)
return;
-
- if (enable)
- __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
- MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_SET);
- else
- __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
- MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL_CLR);
+ usb_phy_ctrl_dcdt = __raw_readl(
+ MX6_IO_ADDRESS(pdata->phy_regs) + HW_USBPHY_CTRL) &
+ BM_USBPHY_CTRL_ENHOSTDISCONDETECT;
+ if (enable) {
+ if (usb_phy_ctrl_dcdt == 0)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_SET);
+ } else {
+ if (usb_phy_ctrl_dcdt
+ == BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
+ __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ MX6_IO_ADDRESS(pdata->phy_regs)
+ + HW_USBPHY_CTRL_CLR);
+ }
}
EXPORT_SYMBOL(fsl_platform_set_usb_phy_dis);
#endif