Commit 44e42ae3 authored by Ivan T. Ivanov's avatar Ivan T. Ivanov Committed by Felipe Balbi

usb: phy: msm: Manual PHY and LINK controller VBUS change notification

VBUS is not routed to USB PHY on recent Qualcomm platforms. USB controller
must see VBUS in order to pull-up DP when setting RS bit. Henc configure
USB PHY and LINK registers sense VBUS and enable manual pullup on D+ line.

Cc: Vamsi Krishna <vskrishn@codeaurora.org>
Cc: Mayank Rana <mrana@codeaurora.org>
Signed-off-by: default avatarIvan T. Ivanov <ivan.ivanov@linaro.org>
Signed-off-by: default avatarFelipe Balbi <balbi@ti.com>
parent 591fc116
...@@ -69,6 +69,10 @@ Optional properties: ...@@ -69,6 +69,10 @@ Optional properties:
(no, min, max) where each value represents either a voltage (no, min, max) where each value represents either a voltage
in microvolts or a value corresponding to voltage corner. in microvolts or a value corresponding to voltage corner.
- qcom,manual-pullup: If present, vbus is not routed to USB controller/phy
and controller driver therefore enables pull-up explicitly
before starting controller using usbcmd run/stop bit.
- extcon: phandles to external connector devices. First phandle - extcon: phandles to external connector devices. First phandle
should point to external connector, which provide "USB" should point to external connector, which provide "USB"
cable events, the second should point to external connector cable events, the second should point to external connector
......
...@@ -240,8 +240,14 @@ static void ulpi_init(struct msm_otg *motg) ...@@ -240,8 +240,14 @@ static void ulpi_init(struct msm_otg *motg)
static int msm_phy_notify_disconnect(struct usb_phy *phy, static int msm_phy_notify_disconnect(struct usb_phy *phy,
enum usb_device_speed speed) enum usb_device_speed speed)
{ {
struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
int val; int val;
if (motg->manual_pullup) {
val = ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL;
usb_phy_io_write(phy, val, ULPI_CLR(ULPI_MISC_A));
}
/* /*
* Put the transceiver in non-driving mode. Otherwise host * Put the transceiver in non-driving mode. Otherwise host
* may not detect soft-disconnection. * may not detect soft-disconnection.
...@@ -422,6 +428,24 @@ static int msm_phy_init(struct usb_phy *phy) ...@@ -422,6 +428,24 @@ static int msm_phy_init(struct usb_phy *phy)
ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL); ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL);
} }
if (motg->manual_pullup) {
val = ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT;
ulpi_write(phy, val, ULPI_SET(ULPI_MISC_A));
val = readl(USB_GENCONFIG_2);
val |= GENCONFIG_2_SESS_VLD_CTRL_EN;
writel(val, USB_GENCONFIG_2);
val = readl(USB_USBCMD);
val |= USBCMD_SESS_VLD_CTRL;
writel(val, USB_USBCMD);
val = ulpi_read(phy, ULPI_FUNC_CTRL);
val &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
val |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
ulpi_write(phy, val, ULPI_FUNC_CTRL);
}
if (motg->phy_number) if (motg->phy_number)
writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2); writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
...@@ -1520,6 +1544,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg) ...@@ -1520,6 +1544,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX]; motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX];
} }
motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup");
ext_id = ERR_PTR(-ENODEV); ext_id = ERR_PTR(-ENODEV);
ext_vbus = ERR_PTR(-ENODEV); ext_vbus = ERR_PTR(-ENODEV);
if (of_property_read_bool(node, "extcon")) { if (of_property_read_bool(node, "extcon")) {
......
...@@ -150,6 +150,9 @@ struct msm_usb_cable { ...@@ -150,6 +150,9 @@ struct msm_usb_cable {
* @chg_type: The type of charger attached. * @chg_type: The type of charger attached.
* @dcd_retires: The retry count used to track Data contact * @dcd_retires: The retry count used to track Data contact
* detection process. * detection process.
* @manual_pullup: true if VBUS is not routed to USB controller/phy
* and controller driver therefore enables pull-up explicitly before
* starting controller using usbcmd run/stop bit.
* @vbus: VBUS signal state trakining, using extcon framework * @vbus: VBUS signal state trakining, using extcon framework
* @id: ID signal state trakining, using extcon framework * @id: ID signal state trakining, using extcon framework
*/ */
...@@ -181,6 +184,8 @@ struct msm_otg { ...@@ -181,6 +184,8 @@ struct msm_otg {
struct reset_control *link_rst; struct reset_control *link_rst;
int vdd_levels[3]; int vdd_levels[3];
bool manual_pullup;
struct msm_usb_cable vbus; struct msm_usb_cable vbus;
struct msm_usb_cable id; struct msm_usb_cable id;
}; };
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#define USB_AHBBURST (MSM_USB_BASE + 0x0090) #define USB_AHBBURST (MSM_USB_BASE + 0x0090)
#define USB_AHBMODE (MSM_USB_BASE + 0x0098) #define USB_AHBMODE (MSM_USB_BASE + 0x0098)
#define USB_GENCONFIG_2 (MSM_USB_BASE + 0x00a0)
#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ #define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */
#define USB_USBCMD (MSM_USB_BASE + 0x0140) #define USB_USBCMD (MSM_USB_BASE + 0x0140)
...@@ -30,6 +32,9 @@ ...@@ -30,6 +32,9 @@
#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240) #define USB_PHY_CTRL (MSM_USB_BASE + 0x0240)
#define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278) #define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278)
#define GENCONFIG_2_SESS_VLD_CTRL_EN BIT(7)
#define USBCMD_SESS_VLD_CTRL BIT(25)
#define USBCMD_RESET 2 #define USBCMD_RESET 2
#define USB_USBINTR (MSM_USB_BASE + 0x0148) #define USB_USBINTR (MSM_USB_BASE + 0x0148)
...@@ -50,6 +55,10 @@ ...@@ -50,6 +55,10 @@
#define ULPI_PWR_CLK_MNG_REG 0x88 #define ULPI_PWR_CLK_MNG_REG 0x88
#define OTG_COMP_DISABLE BIT(0) #define OTG_COMP_DISABLE BIT(0)
#define ULPI_MISC_A 0x96
#define ULPI_MISC_A_VBUSVLDEXTSEL BIT(1)
#define ULPI_MISC_A_VBUSVLDEXT BIT(0)
#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */ #define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */
#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */ #define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */
#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */ #define PHY_RETEN (1 << 1) /* PHY retention enable/disable */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment