Loading drivers/usb/phy/phy-msm-qusb-v2.c +82 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ /* QUSB2PHY_PWR_CTRL1 register related bits */ #define PWR_CTRL1_POWR_DOWN BIT(0) #define CLAMP_N_EN BIT(1) /* QUSB2PHY_PLL_COMMON_STATUS_ONE register related bits */ #define CORE_READY_STATUS BIT(0) Loading Loading @@ -69,6 +70,10 @@ /* STAT5 register bits */ #define VSTATUS_PLL_LOCK_STATUS_MASK BIT(0) /* DEBUG_CTRL4 register bits */ #define FORCED_UTMI_DPPULLDOWN BIT(2) #define FORCED_UTMI_DMPULLDOWN BIT(3) enum qusb_phy_reg { PORT_TUNE1, PLL_COMMON_STATUS_ONE, Loading @@ -79,6 +84,8 @@ enum qusb_phy_reg { BIAS_CTRL_2, DEBUG_CTRL1, DEBUG_CTRL2, DEBUG_CTRL3, DEBUG_CTRL4, STAT5, USB2_PHY_REG_MAX, }; Loading Loading @@ -396,6 +403,25 @@ static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, } } static void msm_usb_write_readback(void __iomem *base, u32 offset, const u32 mask, u32 val) { u32 write_val, tmp = readl_relaxed(base + offset); tmp &= ~mask; /* retain other bits */ write_val = tmp | val; writel_relaxed(write_val, base + offset); /* Read back to see if val was written */ tmp = readl_relaxed(base + offset); tmp &= mask; /* clear other bits */ if (tmp != val) pr_err("%s: write: %x to QSCRATCH: %x FAILED\n", __func__, val, offset); } static void qusb_phy_reset(struct qusb_phy *qphy) { int ret; Loading Loading @@ -736,6 +762,61 @@ static int qusb_phy_notify_disconnect(struct usb_phy *phy, return 0; } static int msm_qusb_phy_drive_dp_pulse(struct usb_phy *phy, unsigned int interval_ms) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); int ret; ret = qusb_phy_enable_power(qphy); if (ret < 0) { dev_dbg(qphy->phy.dev, "dpdm regulator enable failed:%d\n", ret); return ret; } qusb_phy_enable_clocks(qphy, true); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], PWR_CTRL1_POWR_DOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DPPULLDOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DMPULLDOWN, FORCED_UTMI_DMPULLDOWN); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3], 0xd1, 0xd1); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], CLAMP_N_EN, CLAMP_N_EN); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_HIGH_SEL, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_EN, DPSE_INTR_EN); msleep(interval_ms); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_HIGH_SEL | DPSE_INTR_EN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3], 0xd1, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DPPULLDOWN | FORCED_UTMI_DMPULLDOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], PWR_CTRL1_POWR_DOWN | CLAMP_N_EN, 0x00); msleep(20); qusb_phy_enable_clocks(qphy, false); ret = qusb_phy_disable_power(qphy); if (ret < 0) { dev_dbg(qphy->phy.dev, "dpdm regulator disable failed:%d\n", ret); } return 0; } static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev) { int ret = 0; Loading Loading @@ -1133,6 +1214,7 @@ static int qusb_phy_probe(struct platform_device *pdev) qphy->phy.type = USB_PHY_TYPE_USB2; qphy->phy.notify_connect = qusb_phy_notify_connect; qphy->phy.notify_disconnect = qusb_phy_notify_disconnect; qphy->phy.drive_dp_pulse = msm_qusb_phy_drive_dp_pulse; ret = usb_add_phy_dev(&qphy->phy); if (ret) Loading Loading
drivers/usb/phy/phy-msm-qusb-v2.c +82 −0 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ /* QUSB2PHY_PWR_CTRL1 register related bits */ #define PWR_CTRL1_POWR_DOWN BIT(0) #define CLAMP_N_EN BIT(1) /* QUSB2PHY_PLL_COMMON_STATUS_ONE register related bits */ #define CORE_READY_STATUS BIT(0) Loading Loading @@ -69,6 +70,10 @@ /* STAT5 register bits */ #define VSTATUS_PLL_LOCK_STATUS_MASK BIT(0) /* DEBUG_CTRL4 register bits */ #define FORCED_UTMI_DPPULLDOWN BIT(2) #define FORCED_UTMI_DMPULLDOWN BIT(3) enum qusb_phy_reg { PORT_TUNE1, PLL_COMMON_STATUS_ONE, Loading @@ -79,6 +84,8 @@ enum qusb_phy_reg { BIAS_CTRL_2, DEBUG_CTRL1, DEBUG_CTRL2, DEBUG_CTRL3, DEBUG_CTRL4, STAT5, USB2_PHY_REG_MAX, }; Loading Loading @@ -396,6 +403,25 @@ static void qusb_phy_write_seq(void __iomem *base, u32 *seq, int cnt, } } static void msm_usb_write_readback(void __iomem *base, u32 offset, const u32 mask, u32 val) { u32 write_val, tmp = readl_relaxed(base + offset); tmp &= ~mask; /* retain other bits */ write_val = tmp | val; writel_relaxed(write_val, base + offset); /* Read back to see if val was written */ tmp = readl_relaxed(base + offset); tmp &= mask; /* clear other bits */ if (tmp != val) pr_err("%s: write: %x to QSCRATCH: %x FAILED\n", __func__, val, offset); } static void qusb_phy_reset(struct qusb_phy *qphy) { int ret; Loading Loading @@ -736,6 +762,61 @@ static int qusb_phy_notify_disconnect(struct usb_phy *phy, return 0; } static int msm_qusb_phy_drive_dp_pulse(struct usb_phy *phy, unsigned int interval_ms) { struct qusb_phy *qphy = container_of(phy, struct qusb_phy, phy); int ret; ret = qusb_phy_enable_power(qphy); if (ret < 0) { dev_dbg(qphy->phy.dev, "dpdm regulator enable failed:%d\n", ret); return ret; } qusb_phy_enable_clocks(qphy, true); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], PWR_CTRL1_POWR_DOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DPPULLDOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DMPULLDOWN, FORCED_UTMI_DMPULLDOWN); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3], 0xd1, 0xd1); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], CLAMP_N_EN, CLAMP_N_EN); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_HIGH_SEL, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_EN, DPSE_INTR_EN); msleep(interval_ms); msm_usb_write_readback(qphy->base, qphy->phy_reg[INTR_CTRL], DPSE_INTR_HIGH_SEL | DPSE_INTR_EN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL3], 0xd1, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[DEBUG_CTRL4], FORCED_UTMI_DPPULLDOWN | FORCED_UTMI_DMPULLDOWN, 0x00); msm_usb_write_readback(qphy->base, qphy->phy_reg[PWR_CTRL1], PWR_CTRL1_POWR_DOWN | CLAMP_N_EN, 0x00); msleep(20); qusb_phy_enable_clocks(qphy, false); ret = qusb_phy_disable_power(qphy); if (ret < 0) { dev_dbg(qphy->phy.dev, "dpdm regulator disable failed:%d\n", ret); } return 0; } static int qusb_phy_dpdm_regulator_enable(struct regulator_dev *rdev) { int ret = 0; Loading Loading @@ -1133,6 +1214,7 @@ static int qusb_phy_probe(struct platform_device *pdev) qphy->phy.type = USB_PHY_TYPE_USB2; qphy->phy.notify_connect = qusb_phy_notify_connect; qphy->phy.notify_disconnect = qusb_phy_notify_disconnect; qphy->phy.drive_dp_pulse = msm_qusb_phy_drive_dp_pulse; ret = usb_add_phy_dev(&qphy->phy); if (ret) Loading