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: Ivan T. Ivanov <ivan.ivanov@linaro.org> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
591fc116f3
commit
44e42ae3a3
4 changed files with 44 additions and 0 deletions
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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 {
|
||||||
* @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 {
|
||||||
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 @@
|
||||||
|
|
||||||
#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 @@
|
||||||
#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 @@
|
||||||
#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 */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue