1 // SPDX-License-Identifier: GPL-2.0+
3 * Copyright 2015 Freescale Semiconductor, Inc.
5 * DWC3 controller driver
7 * Author: Ramneek Mehresh<ramneek.mehresh@freescale.com>
13 #include <generic-phy.h>
18 #include <linux/usb/dwc3.h>
19 #include <linux/usb/otg.h>
21 struct xhci_dwc3_platdata
{
26 void dwc3_set_mode(struct dwc3
*dwc3_reg
, u32 mode
)
28 clrsetbits_le32(&dwc3_reg
->g_ctl
,
29 DWC3_GCTL_PRTCAPDIR(DWC3_GCTL_PRTCAP_OTG
),
30 DWC3_GCTL_PRTCAPDIR(mode
));
33 static void dwc3_phy_reset(struct dwc3
*dwc3_reg
)
35 /* Assert USB3 PHY reset */
36 setbits_le32(&dwc3_reg
->g_usb3pipectl
[0], DWC3_GUSB3PIPECTL_PHYSOFTRST
);
38 /* Assert USB2 PHY reset */
39 setbits_le32(&dwc3_reg
->g_usb2phycfg
, DWC3_GUSB2PHYCFG_PHYSOFTRST
);
43 /* Clear USB3 PHY reset */
44 clrbits_le32(&dwc3_reg
->g_usb3pipectl
[0], DWC3_GUSB3PIPECTL_PHYSOFTRST
);
46 /* Clear USB2 PHY reset */
47 clrbits_le32(&dwc3_reg
->g_usb2phycfg
, DWC3_GUSB2PHYCFG_PHYSOFTRST
);
50 void dwc3_core_soft_reset(struct dwc3
*dwc3_reg
)
52 /* Before Resetting PHY, put Core in Reset */
53 setbits_le32(&dwc3_reg
->g_ctl
, DWC3_GCTL_CORESOFTRESET
);
55 /* reset USB3 phy - if required */
56 dwc3_phy_reset(dwc3_reg
);
60 /* After PHYs are stable we can take Core out of reset state */
61 clrbits_le32(&dwc3_reg
->g_ctl
, DWC3_GCTL_CORESOFTRESET
);
64 int dwc3_core_init(struct dwc3
*dwc3_reg
)
68 unsigned int dwc3_hwparams1
;
70 revision
= readl(&dwc3_reg
->g_snpsid
);
71 /* This should read as U3 followed by revision number */
72 if ((revision
& DWC3_GSNPSID_MASK
) != 0x55330000) {
73 puts("this is not a DesignWare USB3 DRD Core\n");
77 dwc3_core_soft_reset(dwc3_reg
);
79 dwc3_hwparams1
= readl(&dwc3_reg
->g_hwparams1
);
81 reg
= readl(&dwc3_reg
->g_ctl
);
82 reg
&= ~DWC3_GCTL_SCALEDOWN_MASK
;
83 reg
&= ~DWC3_GCTL_DISSCRAMBLE
;
84 switch (DWC3_GHWPARAMS1_EN_PWROPT(dwc3_hwparams1
)) {
85 case DWC3_GHWPARAMS1_EN_PWROPT_CLK
:
86 reg
&= ~DWC3_GCTL_DSBLCLKGTNG
;
89 debug("No power optimization available\n");
93 * WORKAROUND: DWC3 revisions <1.90a have a bug
94 * where the device can fail to connect at SuperSpeed
95 * and falls back to high-speed mode which causes
96 * the device to enter a Connect/Disconnect loop
98 if ((revision
& DWC3_REVISION_MASK
) < 0x190a)
99 reg
|= DWC3_GCTL_U2RSTECN
;
101 writel(reg
, &dwc3_reg
->g_ctl
);
106 void dwc3_set_fladj(struct dwc3
*dwc3_reg
, u32 val
)
108 setbits_le32(&dwc3_reg
->g_fladj
, GFLADJ_30MHZ_REG_SEL
|
113 static int xhci_dwc3_setup_phy(struct udevice
*dev
)
115 struct xhci_dwc3_platdata
*plat
= dev_get_platdata(dev
);
118 /* Return if no phy declared */
119 if (!dev_read_prop(dev
, "phys", NULL
))
122 count
= dev_count_phandle_with_args(dev
, "phys", "#phy-cells");
126 plat
->usb_phys
= devm_kcalloc(dev
, count
, sizeof(struct phy
),
131 for (i
= 0; i
< count
; i
++) {
132 ret
= generic_phy_get_by_index(dev
, i
, &plat
->usb_phys
[i
]);
133 if (ret
&& ret
!= -ENOENT
) {
134 pr_err("Failed to get USB PHY%d for %s\n",
142 for (i
= 0; i
< plat
->num_phys
; i
++) {
143 ret
= generic_phy_init(&plat
->usb_phys
[i
]);
145 pr_err("Can't init USB PHY%d for %s\n",
151 for (i
= 0; i
< plat
->num_phys
; i
++) {
152 ret
= generic_phy_power_on(&plat
->usb_phys
[i
]);
154 pr_err("Can't power USB PHY%d for %s\n",
156 goto phys_poweron_err
;
164 generic_phy_power_off(&plat
->usb_phys
[i
]);
166 for (i
= 0; i
< plat
->num_phys
; i
++)
167 generic_phy_exit(&plat
->usb_phys
[i
]);
173 generic_phy_exit(&plat
->usb_phys
[i
]);
178 static int xhci_dwc3_shutdown_phy(struct udevice
*dev
)
180 struct xhci_dwc3_platdata
*plat
= dev_get_platdata(dev
);
183 for (i
= 0; i
< plat
->num_phys
; i
++) {
184 if (!generic_phy_valid(&plat
->usb_phys
[i
]))
187 ret
= generic_phy_power_off(&plat
->usb_phys
[i
]);
188 ret
|= generic_phy_exit(&plat
->usb_phys
[i
]);
190 pr_err("Can't shutdown USB PHY%d for %s\n",
198 static int xhci_dwc3_probe(struct udevice
*dev
)
200 struct xhci_hcor
*hcor
;
201 struct xhci_hccr
*hccr
;
202 struct dwc3
*dwc3_reg
;
203 enum usb_dr_mode dr_mode
;
206 hccr
= (struct xhci_hccr
*)((uintptr_t)dev_read_addr(dev
));
207 hcor
= (struct xhci_hcor
*)((uintptr_t)hccr
+
208 HC_LENGTH(xhci_readl(&(hccr
)->cr_capbase
)));
210 ret
= xhci_dwc3_setup_phy(dev
);
214 dwc3_reg
= (struct dwc3
*)((char *)(hccr
) + DWC3_REG_OFFSET
);
216 dwc3_core_init(dwc3_reg
);
218 dr_mode
= usb_get_dr_mode(dev_of_offset(dev
));
219 if (dr_mode
== USB_DR_MODE_UNKNOWN
)
220 /* by default set dual role mode to HOST */
221 dr_mode
= USB_DR_MODE_HOST
;
223 dwc3_set_mode(dwc3_reg
, dr_mode
);
225 return xhci_register(dev
, hccr
, hcor
);
228 static int xhci_dwc3_remove(struct udevice
*dev
)
230 xhci_dwc3_shutdown_phy(dev
);
232 return xhci_deregister(dev
);
235 static const struct udevice_id xhci_dwc3_ids
[] = {
236 { .compatible
= "snps,dwc3" },
240 U_BOOT_DRIVER(xhci_dwc3
) = {
243 .of_match
= xhci_dwc3_ids
,
244 .probe
= xhci_dwc3_probe
,
245 .remove
= xhci_dwc3_remove
,
246 .ops
= &xhci_usb_ops
,
247 .priv_auto_alloc_size
= sizeof(struct xhci_ctrl
),
248 .platdata_auto_alloc_size
= sizeof(struct xhci_dwc3_platdata
),
249 .flags
= DM_FLAG_ALLOC_PRIV_DMA
,