Commit 92454e47bcec875490f3238d674fdc3e6c012b70
Committed by
Tom Rini
1 parent
2df573e6a5
Exists in
smarc_8mq_lf_v2020.04
and in
11 other branches
phy: db410c: Add MSM USB PHY driver
Add a PHY driver for the Qualcomm dragonboard 410c which allows switching on/off and resetting the phy connected to the EHCI controllers and USBHS controller. Signed-off-by: Ramon Fried <ramon.fried@gmail.com>
Showing 4 changed files with 119 additions and 0 deletions Side-by-side Diff
MAINTAINERS
drivers/phy/Kconfig
... | ... | @@ -139,5 +139,13 @@ |
139 | 139 | This is the generic phy driver for the Amlogic Meson GXL |
140 | 140 | USB2 and USB3 PHYS. |
141 | 141 | |
142 | +config MSM8916_USB_PHY | |
143 | + bool "Qualcomm MSM8916 USB PHY support" | |
144 | + depends on PHY | |
145 | + help | |
146 | + Support the USB PHY in msm8916 | |
147 | + | |
148 | + This PHY is found on qualcomm dragonboard410c development board. | |
149 | + | |
142 | 150 | endmenu |
drivers/phy/Makefile
drivers/phy/msm8916-usbh-phy.c
1 | +// SPDX-License-Identifier: GPL-2.0+ | |
2 | +/* | |
3 | + * Copyright (C) 2018 Ramon Fried <ramon.fried@gmail.com> | |
4 | + */ | |
5 | + | |
6 | +#include <common.h> | |
7 | +#include <dm.h> | |
8 | +#include <generic-phy.h> | |
9 | +#include <usb/ehci-ci.h> | |
10 | +#include <usb/ulpi.h> | |
11 | +#include <asm/io.h> | |
12 | + | |
13 | +/* PHY viewport regs */ | |
14 | +#define ULPI_MISC_A_READ 0x96 | |
15 | +#define ULPI_MISC_A_SET 0x97 | |
16 | +#define ULPI_MISC_A_CLEAR 0x98 | |
17 | +#define ULPI_MISC_A_VBUSVLDEXT BIT(0) | |
18 | +#define ULPI_MISC_A_VBUSVLDEXTSEL BIT(1) | |
19 | +#define GEN2_SESS_VLD_CTRL_EN BIT(7) | |
20 | +#define SESS_VLD_CTRL BIT(25) | |
21 | + | |
22 | +struct msm_phy_priv { | |
23 | + void __iomem *regs; | |
24 | + struct usb_ehci *ehci; /* Start of IP core*/ | |
25 | + struct ulpi_viewport ulpi_vp; /* ULPI Viewport */ | |
26 | +}; | |
27 | + | |
28 | +static int msm_phy_power_on(struct phy *phy) | |
29 | +{ | |
30 | + struct msm_phy_priv *priv = dev_get_priv(phy->dev); | |
31 | + | |
32 | + /* Select and enable external configuration with USB PHY */ | |
33 | + ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_SET, | |
34 | + ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); | |
35 | + | |
36 | + return 0; | |
37 | +} | |
38 | + | |
39 | +static int msm_phy_power_off(struct phy *phy) | |
40 | +{ | |
41 | + struct msm_phy_priv *priv = dev_get_priv(phy->dev); | |
42 | + | |
43 | + /* Disable VBUS mimicing in the controller. */ | |
44 | + ulpi_write(&priv->ulpi_vp, (u8 *)ULPI_MISC_A_CLEAR, | |
45 | + ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT); | |
46 | + return 0; | |
47 | +} | |
48 | + | |
49 | +static int msm_phy_reset(struct phy *phy) | |
50 | +{ | |
51 | + struct msm_phy_priv *p = dev_get_priv(phy->dev); | |
52 | + | |
53 | + /* select ULPI phy */ | |
54 | + writel(PORT_PTS_ULPI, &p->ehci->portsc); | |
55 | + | |
56 | + /* Enable sess_vld */ | |
57 | + setbits_le32(&p->ehci->genconfig2, GEN2_SESS_VLD_CTRL_EN); | |
58 | + | |
59 | + /* Enable external vbus configuration in the LINK */ | |
60 | + setbits_le32(&p->ehci->usbcmd, SESS_VLD_CTRL); | |
61 | + | |
62 | + /* USB_OTG_HS_AHB_BURST */ | |
63 | + writel(0x0, &p->ehci->sbuscfg); | |
64 | + | |
65 | + /* USB_OTG_HS_AHB_MODE: HPROT_MODE */ | |
66 | + /* Bus access related config. */ | |
67 | + writel(0x08, &p->ehci->sbusmode); | |
68 | + | |
69 | + return 0; | |
70 | +} | |
71 | + | |
72 | +static int msm_phy_probe(struct udevice *dev) | |
73 | +{ | |
74 | + struct msm_phy_priv *priv = dev_get_priv(dev); | |
75 | + | |
76 | + priv->regs = dev_remap_addr(dev); | |
77 | + if (!priv->regs) | |
78 | + return -EINVAL; | |
79 | + | |
80 | + priv->ehci = (struct usb_ehci *)priv->regs; | |
81 | + priv->ulpi_vp.port_num = 0; | |
82 | + | |
83 | + /* Warning: this will not work if viewport address is > 64 bit due to | |
84 | + * ULPI design. | |
85 | + */ | |
86 | + priv->ulpi_vp.viewport_addr = (phys_addr_t)&priv->ehci->ulpi_viewpoint; | |
87 | + | |
88 | + return 0; | |
89 | +} | |
90 | + | |
91 | +static struct phy_ops msm_phy_ops = { | |
92 | + .power_on = msm_phy_power_on, | |
93 | + .power_off = msm_phy_power_off, | |
94 | + .reset = msm_phy_reset, | |
95 | +}; | |
96 | + | |
97 | +static const struct udevice_id msm_phy_ids[] = { | |
98 | + { .compatible = "qcom,apq8016-usbphy" }, | |
99 | + { } | |
100 | +}; | |
101 | + | |
102 | +U_BOOT_DRIVER(msm8916_usbphy) = { | |
103 | + .name = "msm8916_usbphy", | |
104 | + .id = UCLASS_PHY, | |
105 | + .of_match = msm_phy_ids, | |
106 | + .ops = &msm_phy_ops, | |
107 | + .probe = msm_phy_probe, | |
108 | + .priv_auto_alloc_size = sizeof(struct msm_phy_priv), | |
109 | +}; |