Skip to content

Commit 44e42ae

Browse files
Ivan T. IvanovFelipe Balbi
authored andcommitted
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 <[email protected]> Cc: Mayank Rana <[email protected]> Signed-off-by: Ivan T. Ivanov <[email protected]> Signed-off-by: Felipe Balbi <[email protected]>
1 parent 591fc11 commit 44e42ae

File tree

4 files changed

+44
-0
lines changed

4 files changed

+44
-0
lines changed

Documentation/devicetree/bindings/usb/msm-hsusb.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,10 @@ Optional properties:
6969
(no, min, max) where each value represents either a voltage
7070
in microvolts or a value corresponding to voltage corner.
7171

72+
- qcom,manual-pullup: If present, vbus is not routed to USB controller/phy
73+
and controller driver therefore enables pull-up explicitly
74+
before starting controller using usbcmd run/stop bit.
75+
7276
- extcon: phandles to external connector devices. First phandle
7377
should point to external connector, which provide "USB"
7478
cable events, the second should point to external connector

drivers/usb/phy/phy-msm-usb.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,8 +240,14 @@ static void ulpi_init(struct msm_otg *motg)
240240
static int msm_phy_notify_disconnect(struct usb_phy *phy,
241241
enum usb_device_speed speed)
242242
{
243+
struct msm_otg *motg = container_of(phy, struct msm_otg, phy);
243244
int val;
244245

246+
if (motg->manual_pullup) {
247+
val = ULPI_MISC_A_VBUSVLDEXT | ULPI_MISC_A_VBUSVLDEXTSEL;
248+
usb_phy_io_write(phy, val, ULPI_CLR(ULPI_MISC_A));
249+
}
250+
245251
/*
246252
* Put the transceiver in non-driving mode. Otherwise host
247253
* may not detect soft-disconnection.
@@ -422,6 +428,24 @@ static int msm_phy_init(struct usb_phy *phy)
422428
ulpi_write(phy, ulpi_val, ULPI_USB_INT_EN_FALL);
423429
}
424430

431+
if (motg->manual_pullup) {
432+
val = ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT;
433+
ulpi_write(phy, val, ULPI_SET(ULPI_MISC_A));
434+
435+
val = readl(USB_GENCONFIG_2);
436+
val |= GENCONFIG_2_SESS_VLD_CTRL_EN;
437+
writel(val, USB_GENCONFIG_2);
438+
439+
val = readl(USB_USBCMD);
440+
val |= USBCMD_SESS_VLD_CTRL;
441+
writel(val, USB_USBCMD);
442+
443+
val = ulpi_read(phy, ULPI_FUNC_CTRL);
444+
val &= ~ULPI_FUNC_CTRL_OPMODE_MASK;
445+
val |= ULPI_FUNC_CTRL_OPMODE_NORMAL;
446+
ulpi_write(phy, val, ULPI_FUNC_CTRL);
447+
}
448+
425449
if (motg->phy_number)
426450
writel(readl(USB_PHY_CTRL2) | BIT(16), USB_PHY_CTRL2);
427451

@@ -1520,6 +1544,8 @@ static int msm_otg_read_dt(struct platform_device *pdev, struct msm_otg *motg)
15201544
motg->vdd_levels[VDD_LEVEL_MAX] = tmp[VDD_LEVEL_MAX];
15211545
}
15221546

1547+
motg->manual_pullup = of_property_read_bool(node, "qcom,manual-pullup");
1548+
15231549
ext_id = ERR_PTR(-ENODEV);
15241550
ext_vbus = ERR_PTR(-ENODEV);
15251551
if (of_property_read_bool(node, "extcon")) {

include/linux/usb/msm_hsusb.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ struct msm_usb_cable {
150150
* @chg_type: The type of charger attached.
151151
* @dcd_retires: The retry count used to track Data contact
152152
* detection process.
153+
* @manual_pullup: true if VBUS is not routed to USB controller/phy
154+
* and controller driver therefore enables pull-up explicitly before
155+
* starting controller using usbcmd run/stop bit.
153156
* @vbus: VBUS signal state trakining, using extcon framework
154157
* @id: ID signal state trakining, using extcon framework
155158
*/
@@ -181,6 +184,8 @@ struct msm_otg {
181184
struct reset_control *link_rst;
182185
int vdd_levels[3];
183186

187+
bool manual_pullup;
188+
184189
struct msm_usb_cable vbus;
185190
struct msm_usb_cable id;
186191
};

include/linux/usb/msm_hsusb_hw.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121

2222
#define USB_AHBBURST (MSM_USB_BASE + 0x0090)
2323
#define USB_AHBMODE (MSM_USB_BASE + 0x0098)
24+
#define USB_GENCONFIG_2 (MSM_USB_BASE + 0x00a0)
25+
2426
#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */
2527

2628
#define USB_USBCMD (MSM_USB_BASE + 0x0140)
@@ -30,6 +32,9 @@
3032
#define USB_PHY_CTRL (MSM_USB_BASE + 0x0240)
3133
#define USB_PHY_CTRL2 (MSM_USB_BASE + 0x0278)
3234

35+
#define GENCONFIG_2_SESS_VLD_CTRL_EN BIT(7)
36+
#define USBCMD_SESS_VLD_CTRL BIT(25)
37+
3338
#define USBCMD_RESET 2
3439
#define USB_USBINTR (MSM_USB_BASE + 0x0148)
3540

@@ -50,6 +55,10 @@
5055
#define ULPI_PWR_CLK_MNG_REG 0x88
5156
#define OTG_COMP_DISABLE BIT(0)
5257

58+
#define ULPI_MISC_A 0x96
59+
#define ULPI_MISC_A_VBUSVLDEXTSEL BIT(1)
60+
#define ULPI_MISC_A_VBUSVLDEXT BIT(0)
61+
5362
#define ASYNC_INTR_CTRL (1 << 29) /* Enable async interrupt */
5463
#define ULPI_STP_CTRL (1 << 30) /* Block communication with PHY */
5564
#define PHY_RETEN (1 << 1) /* PHY retention enable/disable */

0 commit comments

Comments
 (0)