static int msm_hsic_reset(struct msm_hsic_hcd *mehci) { struct usb_hcd *hcd = hsic_to_hcd(mehci); int ret; struct msm_hsic_host_platform_data *pdata = mehci->dev->platform_data; msm_hsic_clk_reset(mehci); /* select ulpi phy */ writel_relaxed(0x80000000, USB_PORTSC); mb(); /* HSIC init sequence when HSIC signals (Strobe/Data) are routed via GPIOs */ if (pdata && pdata->strobe && pdata->data) { /* Enable LV_MODE in HSIC_CAL_PAD_CTL register */ writel_relaxed(HSIC_LV_MODE, HSIC_CAL_PAD_CTL); mb(); /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */ ulpi_write(mehci, 0xFF, 0x33); /* Enable periodic IO calibration in HSIC_CFG register */ ulpi_write(mehci, HSIC_PAD_CALIBRATION, 0x30); /* Configure GPIO pins for HSIC functionality mode */ ret = msm_hsic_config_gpios(mehci, 1); if (ret) { dev_err(mehci->dev, " gpio configuarion failed\n"); return ret; } /* Set LV_MODE=0x1 and DCC=0x2 in HSIC_GPIO PAD_CTL register */ writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_STROBE_GPIO_PAD_CTL); writel_relaxed(HSIC_GPIO_PAD_VAL, HSIC_DATA_GPIO_PAD_CTL); mb(); /* Enable HSIC mode in HSIC_CFG register */ ulpi_write(mehci, 0x01, 0x31); } else { /* HSIC init sequence when HSIC signals (Strobe/Data) are routed via dedicated I/O */ /* programmable length of connect signaling (33.2ns) */ ret = ulpi_write(mehci, 3, HSIC_DBG1_REG); if (ret) { pr_err("%s: Unable to program length of connect " "signaling\n", __func__); } /*set periodic calibration interval to ~2.048sec in HSIC_IO_CAL_REG */ ulpi_write(mehci, 0xFF, 0x33); /* Enable HSIC mode in HSIC_CFG register */ ulpi_write(mehci, 0xA9, 0x30); } /*disable auto resume*/ ulpi_write(mehci, ULPI_IFC_CTRL_AUTORESUME, ULPI_CLR(ULPI_IFC_CTRL)); return 0; }
static inline int twl4030_usb_clear_bits(struct twl4030_usb *twl, u8 reg, u8 bits) { return twl4030_usb_write(twl, ULPI_CLR(reg), bits); }
static int msm_hsusb_reset(struct msm_hcd *mhcd) { struct usb_hcd *hcd = mhcd_to_hcd(mhcd); struct msm_usb_host_platform_data *pdata; unsigned long timeout; int ret; if (!IS_ERR(mhcd->alt_core_clk)) clk_prepare_enable(mhcd->alt_core_clk); ret = msm_ehci_phy_reset(mhcd); if (ret) { dev_err(mhcd->dev, "phy_reset failed\n"); return ret; } writel_relaxed(USBCMD_RESET, USB_USBCMD); timeout = jiffies + usecs_to_jiffies(LINK_RESET_TIMEOUT_USEC); while (readl_relaxed(USB_USBCMD) & USBCMD_RESET) { if (time_after(jiffies, timeout)) return -ETIMEDOUT; udelay(1); } /* select ULPI phy */ writel_relaxed(0x80000000, USB_PORTSC); pdata = mhcd->dev->platform_data; if (pdata && pdata->use_sec_phy) writel_relaxed(readl_relaxed(USB_PHY_CTRL2) | (1<<16), USB_PHY_CTRL2); /* Reset USB PHY after performing USB Link RESET */ usb_phy_reset(mhcd); msleep(100); writel_relaxed(0x0, USB_AHBBURST); writel_relaxed(0x08, USB_AHBMODE); /* Ensure that RESET operation is completed before turning off clock */ mb(); if (!IS_ERR(mhcd->alt_core_clk)) clk_disable_unprepare(mhcd->alt_core_clk); /*rising edge interrupts with Dp rise and fall enabled*/ msm_ulpi_write(mhcd, ULPI_INT_DP, ULPI_USB_INT_EN_RISE); msm_ulpi_write(mhcd, ULPI_INT_DP, ULPI_USB_INT_EN_FALL); /*Clear the PHY interrupts by reading the PHY interrupt latch register*/ msm_ulpi_read(mhcd, ULPI_USB_INT_LATCH); /*disable auto resume*/ msm_ulpi_write(mhcd, ULPI_IFC_CTRL_AUTORESUME, ULPI_CLR(ULPI_IFC_CTRL)); /* Configure USB PHY settings */ msm_ulpi_write(mhcd, 0x6A, 0x81); msm_ulpi_write(mhcd, 0x24, 0x82); return 0; }