Merge branch 'master' of git://git.denx.de/u-boot-usb

- DWC3 improvements
- i.MX7 EHCI bugfix
This commit is contained in:
Tom Rini 2019-10-25 13:50:51 -04:00
commit 271103ac0b
49 changed files with 384 additions and 274 deletions

View file

@ -857,6 +857,7 @@ M: Bin Meng <bmeng.cn@gmail.com>
S: Maintained
T: git https://gitlab.denx.de/u-boot/custodians/u-boot-usb.git topic-xhci
F: drivers/usb/host/xhci*
F: include/usb/xhci.h
VIDEO
M: Anatolij Gustschin <agust@denx.de>

View file

@ -7,8 +7,40 @@
soc {
u-boot,dm-pre-reloc;
};
aliases {
usb0 = &usb;
usb1 = &usb1;
};
};
&i2c1 {
u-boot,dm-pre-reloc;
};
&usb_phy {
#phy-cells = <0>;
psc-domain = <2>;
};
&usb {
dwc3@2690000 {
phys = <&usb_phy>;
dr_mode = "host";
snps,u2ss_inp3_quirk;
status = "okay";
};
};
&usb1_phy {
#phy-cells = <0>;
psc-domain = <1>;
};
&usb1 {
dwc3@25010000 {
phys = <&usb1_phy>;
dr_mode = "peripheral";
snps,u2ss_inp3_quirk;
status = "okay";
};
};

View file

@ -7,6 +7,10 @@
soc {
u-boot,dm-pre-reloc;
};
aliases {
usb0 = &usb0;
usb1 = &usb1;
};
};
&i2c0 {
@ -16,3 +20,27 @@
&i2c1 {
u-boot,dm-pre-reloc;
};
&usb0_phy {
compatible = "ti,keystone-usbphy";
#phy-cells = <0>;
reg = <0x2620738 24>;
psc-domain = <25>;
};
&usb0 {
phys = <&usb0_phy>;
snps,u2ss_inp3_quirk;
};
&usb1_phy {
compatible = "ti,keystone-usbphy";
#phy-cells = <0>;
reg = <0x2620750 24>;
psc-domain = <26>;
};
&usb1 {
phys = <&usb1_phy>;
snps,u2ss_inp3_quirk;
};

View file

@ -12,3 +12,17 @@
&i2c1 {
u-boot,dm-pre-reloc;
};
&usb_phy {
#phy-cells = <0>;
psc-domain = <2>;
};
&usb {
dwc3@2690000 {
phys = <&usb_phy>;
dr_mode = "host";
snps,u2ss_inp3_quirk;
status = "okay";
};
};

View file

@ -0,0 +1,18 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
*/
&usb_phy {
#phy-cells = <0>;
psc-domain = <2>;
};
&usb {
dwc3@2690000 {
phys = <&usb_phy>;
dr_mode = "host";
snps,u2ss_inp3_quirk;
status = "okay";
};
};

View file

@ -94,7 +94,7 @@ static inline u32 boot_set_bitfield(u32 z, u32 f, u32 x, u32 y)
* Timeout limit on checking PTSTAT. This is the number of times the
* wait function will be called before giving up.
*/
#define PSC_PTSTAT_TIMEOUT_LIMIT 100
#define PSC_PTSTAT_TIMEOUT_LIMIT 100000
u32 psc_get_domain_num(u32 mod_num);
int psc_enable_module(u32 mod_num);

View file

@ -67,20 +67,7 @@ struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
int board_init(void)
{
#if CONFIG_IS_ENABLED(DM_USB)
int rc = psc_enable_module(KS2_LPSC_USB);
if (rc)
puts("Cannot enable USB0 module");
#ifdef KS2_LPSC_USB_1
rc = psc_enable_module(KS2_LPSC_USB_1);
if (rc)
puts("Cannot enable USB1 module");
#endif
#endif
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
return 0;
}

View file

@ -74,7 +74,6 @@ CONFIG_ZYNQ_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -86,6 +86,7 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_USB_DWC2=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207

View file

@ -63,6 +63,7 @@ CONFIG_MII=y
CONFIG_DRIVER_TI_KEYSTONE_NET=y
CONFIG_PHY=y
CONFIG_NOP_PHY=y
CONFIG_KEYSTONE_USB_PHY=y
CONFIG_REMOTEPROC_TI_POWER=y
CONFIG_DM_SERIAL=y
CONFIG_SYS_NS16550=y
@ -73,9 +74,7 @@ CONFIG_USB=y
CONFIG_DM_USB=y
CONFIG_DM_USB_GADGET=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_DOWNLOAD=y

View file

@ -44,6 +44,7 @@ CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e

View file

@ -44,6 +44,7 @@ CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e

View file

@ -88,6 +88,7 @@ CONFIG_USB_OHCI_HCD=y
CONFIG_USB_OHCI_GENERIC=y
CONFIG_USB_DWC2=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_MANUFACTURER="Rockchip"
CONFIG_USB_GADGET_VENDOR_NUM=0x2207

View file

@ -65,6 +65,7 @@ CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x18d1

View file

@ -62,6 +62,7 @@ CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x18d1

View file

@ -44,6 +44,7 @@ CONFIG_DM_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_DWC3=y
# CONFIG_USB_DWC3_GADGET is not set
CONFIG_USB_DWC3_MESON_G12A=y
CONFIG_USB_GADGET=y
CONFIG_USB_GADGET_VENDOR_NUM=0x1b8e

View file

@ -85,7 +85,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -75,7 +75,6 @@ CONFIG_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -72,7 +72,6 @@ CONFIG_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -73,7 +73,6 @@ CONFIG_ZYNQ_SPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -101,7 +101,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -100,7 +100,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -100,7 +100,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -84,7 +84,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -88,7 +88,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -94,7 +94,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -86,7 +86,6 @@ CONFIG_ZYNQMP_GQSPI=y
CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_DWC3=y
CONFIG_USB_XHCI_ZYNQMP=y
CONFIG_USB_DWC3=y
CONFIG_USB_DWC3_GADGET=y
CONFIG_USB_DWC3_GENERIC=y

View file

@ -9,6 +9,7 @@
#include <dm/device.h>
#include <generic-phy.h>
#include <asm/io.h>
#include <asm/arch/psc_defs.h>
/* USB PHY control register offsets */
#define USB_PHY_CTL_UTMI 0x0000
@ -22,15 +23,25 @@
#define PHY_REF_SSP_EN BIT(29)
struct keystone_usb_phy {
u32 psc_domain;
void __iomem *reg;
};
static int keystone_usb_init(struct phy *phy)
{
u32 val;
int rc;
struct udevice *dev = phy->dev;
struct keystone_usb_phy *keystone = dev_get_priv(dev);
/* Release USB from reset */
rc = psc_enable_module(keystone->psc_domain);
if (rc) {
debug("Cannot enable USB module");
return -rc;
}
mdelay(10);
/*
* VBUSVLDEXTSEL has a default value of 1 in BootCfg but shouldn't.
* It should always be cleared because our USB PHY has an onchip VBUS
@ -72,13 +83,24 @@ static int keystone_usb_power_off(struct phy *phy)
static int keystone_usb_exit(struct phy *phy)
{
struct udevice *dev = phy->dev;
struct keystone_usb_phy *keystone = dev_get_priv(dev);
if (psc_disable_module(keystone->psc_domain))
debug("failed to disable USB module!\n");
return 0;
}
static int keystone_usb_phy_probe(struct udevice *dev)
{
int rc;
struct keystone_usb_phy *keystone = dev_get_priv(dev);
rc = dev_read_u32(dev, "psc-domain", &keystone->psc_domain);
if (rc)
return rc;
keystone->reg = dev_remap_addr_index(dev, 0);
if (!keystone->reg) {
pr_err("unable to remap usb phy\n");

View file

@ -7,25 +7,11 @@ config USB_DWC3
if USB_DWC3
choice
bool "DWC3 Mode Selection"
config USB_DWC3_HOST
bool "Host only mode"
depends on USB
help
Select this when you want to use DWC3 in host mode only,
thereby the gadget feature will be regressed.
config USB_DWC3_GADGET
bool "Gadget only mode"
bool "USB Gadget support for DWC3"
default y
depends on USB_GADGET
select USB_GADGET_DUALSPEED
help
Select this when you want to use DWC3 in gadget mode only,
thereby the host feature will be regressed.
endchoice
comment "Platform Glue Driver Support"

View file

@ -581,6 +581,12 @@ static int dwc3_core_init_mode(struct dwc3 *dwc)
return 0;
}
static void dwc3_gadget_run(struct dwc3 *dwc)
{
dwc3_writel(dwc->regs, DWC3_DCTL, DWC3_DCTL_RUN_STOP);
mdelay(100);
}
static void dwc3_core_exit_mode(struct dwc3 *dwc)
{
switch (dwc->dr_mode) {
@ -598,6 +604,13 @@ static void dwc3_core_exit_mode(struct dwc3 *dwc)
/* do nothing */
break;
}
/*
* switch back to peripheral mode
* This enables the phy to enter idle and then, if enabled, suspend.
*/
dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_DEVICE);
dwc3_gadget_run(dwc);
}
#define DWC3_ALIGN_MASK (16 - 1)
@ -694,9 +707,9 @@ int dwc3_uboot_init(struct dwc3_device *dwc3_dev)
return -ENOMEM;
}
if (IS_ENABLED(CONFIG_USB_DWC3_HOST))
if (!IS_ENABLED(CONFIG_USB_DWC3_GADGET))
dwc->dr_mode = USB_DR_MODE_HOST;
else if (IS_ENABLED(CONFIG_USB_DWC3_GADGET))
else if (!IS_ENABLED(CONFIG_USB_HOST))
dwc->dr_mode = USB_DR_MODE_PERIPHERAL;
if (dwc->dr_mode == USB_DR_MODE_UNKNOWN)
@ -874,7 +887,72 @@ int dwc3_shutdown_phy(struct udevice *dev, struct phy *usb_phys, int num_phys)
}
#endif
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
#if CONFIG_IS_ENABLED(DM_USB)
void dwc3_of_parse(struct dwc3 *dwc)
{
const u8 *tmp;
struct udevice *dev = dwc->dev;
u8 lpm_nyet_threshold;
u8 tx_de_emphasis;
u8 hird_threshold;
/* default to highest possible threshold */
lpm_nyet_threshold = 0xff;
/* default to -3.5dB de-emphasis */
tx_de_emphasis = 1;
/*
* default to assert utmi_sleep_n and use maximum allowed HIRD
* threshold value of 0b1100
*/
hird_threshold = 12;
dwc->has_lpm_erratum = dev_read_bool(dev,
"snps,has-lpm-erratum");
tmp = dev_read_u8_array_ptr(dev, "snps,lpm-nyet-threshold", 1);
if (tmp)
lpm_nyet_threshold = *tmp;
dwc->is_utmi_l1_suspend = dev_read_bool(dev,
"snps,is-utmi-l1-suspend");
tmp = dev_read_u8_array_ptr(dev, "snps,hird-threshold", 1);
if (tmp)
hird_threshold = *tmp;
dwc->disable_scramble_quirk = dev_read_bool(dev,
"snps,disable_scramble_quirk");
dwc->u2exit_lfps_quirk = dev_read_bool(dev,
"snps,u2exit_lfps_quirk");
dwc->u2ss_inp3_quirk = dev_read_bool(dev,
"snps,u2ss_inp3_quirk");
dwc->req_p1p2p3_quirk = dev_read_bool(dev,
"snps,req_p1p2p3_quirk");
dwc->del_p1p2p3_quirk = dev_read_bool(dev,
"snps,del_p1p2p3_quirk");
dwc->del_phy_power_chg_quirk = dev_read_bool(dev,
"snps,del_phy_power_chg_quirk");
dwc->lfps_filter_quirk = dev_read_bool(dev,
"snps,lfps_filter_quirk");
dwc->rx_detect_poll_quirk = dev_read_bool(dev,
"snps,rx_detect_poll_quirk");
dwc->dis_u3_susphy_quirk = dev_read_bool(dev,
"snps,dis_u3_susphy_quirk");
dwc->dis_u2_susphy_quirk = dev_read_bool(dev,
"snps,dis_u2_susphy_quirk");
dwc->tx_de_emphasis_quirk = dev_read_bool(dev,
"snps,tx_de_emphasis_quirk");
tmp = dev_read_u8_array_ptr(dev, "snps,tx_de_emphasis", 1);
if (tmp)
tx_de_emphasis = *tmp;
dwc->lpm_nyet_threshold = lpm_nyet_threshold;
dwc->tx_de_emphasis = tx_de_emphasis;
dwc->hird_threshold = hird_threshold
| (dwc->is_utmi_l1_suspend << 4);
}
int dwc3_init(struct dwc3 *dwc)
{
int ret;

View file

@ -991,18 +991,14 @@ struct dwc3_gadget_ep_cmd_params {
/* prototypes */
int dwc3_gadget_resize_tx_fifos(struct dwc3 *dwc);
void dwc3_of_parse(struct dwc3 *dwc);
int dwc3_init(struct dwc3 *dwc);
void dwc3_remove(struct dwc3 *dwc);
#ifdef CONFIG_USB_DWC3_HOST
int dwc3_host_init(struct dwc3 *dwc);
void dwc3_host_exit(struct dwc3 *dwc);
#else
static inline int dwc3_host_init(struct dwc3 *dwc)
{ return 0; }
static inline void dwc3_host_exit(struct dwc3 *dwc)
{ }
#endif
#ifdef CONFIG_USB_DWC3_GADGET
int dwc3_gadget_init(struct dwc3 *dwc);

View file

@ -21,51 +21,60 @@
#include "gadget.h"
#include <reset.h>
#include <clk.h>
#include <usb/xhci.h>
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
struct dwc3_generic_peripheral {
struct dwc3_generic_plat {
fdt_addr_t base;
u32 maximum_speed;
enum usb_dr_mode dr_mode;
};
struct dwc3_generic_priv {
void *base;
struct dwc3 dwc3;
struct phy *phys;
int num_phys;
fdt_addr_t base;
};
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
struct dwc3_generic_host_priv {
struct xhci_ctrl xhci_ctrl;
struct dwc3_generic_priv gen_priv;
};
dwc3_gadget_uboot_handle_interrupt(dwc3);
return 0;
}
static int dwc3_generic_peripheral_probe(struct udevice *dev)
static int dwc3_generic_probe(struct udevice *dev,
struct dwc3_generic_priv *priv)
{
int rc;
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3_generic_plat *plat = dev_get_platdata(dev);
struct dwc3 *dwc3 = &priv->dwc3;
dwc3->dev = dev;
dwc3->maximum_speed = plat->maximum_speed;
dwc3->dr_mode = plat->dr_mode;
#if CONFIG_IS_ENABLED(OF_CONTROL)
dwc3_of_parse(dwc3);
#endif
rc = dwc3_setup_phy(dev, &priv->phys, &priv->num_phys);
if (rc)
return rc;
dwc3->regs = map_physmem(priv->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
dwc3->regs += DWC3_GLOBALS_REGS_START;
dwc3->dev = dev;
priv->base = map_physmem(plat->base, DWC3_OTG_REGS_END, MAP_NOCACHE);
dwc3->regs = priv->base + DWC3_GLOBALS_REGS_START;
rc = dwc3_init(dwc3);
if (rc) {
unmap_physmem(dwc3->regs, MAP_NOCACHE);
unmap_physmem(priv->base, MAP_NOCACHE);
return rc;
}
return 0;
}
static int dwc3_generic_peripheral_remove(struct udevice *dev)
static int dwc3_generic_remove(struct udevice *dev,
struct dwc3_generic_priv *priv)
{
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
dwc3_remove(dwc3);
@ -75,22 +84,21 @@ static int dwc3_generic_peripheral_remove(struct udevice *dev)
return 0;
}
static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
static int dwc3_generic_ofdata_to_platdata(struct udevice *dev)
{
struct dwc3_generic_peripheral *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
struct dwc3_generic_plat *plat = dev_get_platdata(dev);
int node = dev_of_offset(dev);
priv->base = devfdt_get_addr(dev);
plat->base = devfdt_get_addr(dev);
dwc3->maximum_speed = usb_get_maximum_speed(node);
if (dwc3->maximum_speed == USB_SPEED_UNKNOWN) {
pr_err("Invalid usb maximum speed\n");
return -ENODEV;
plat->maximum_speed = usb_get_maximum_speed(node);
if (plat->maximum_speed == USB_SPEED_UNKNOWN) {
pr_info("No USB maximum speed specified. Using super speed\n");
plat->maximum_speed = USB_SPEED_SUPER;
}
dwc3->dr_mode = usb_get_dr_mode(node);
if (dwc3->dr_mode == USB_DR_MODE_UNKNOWN) {
plat->dr_mode = usb_get_dr_mode(node);
if (plat->dr_mode == USB_DR_MODE_UNKNOWN) {
pr_err("Invalid usb mode setup\n");
return -ENODEV;
}
@ -98,13 +106,83 @@ static int dwc3_generic_peripheral_ofdata_to_platdata(struct udevice *dev)
return 0;
}
#if CONFIG_IS_ENABLED(DM_USB_GADGET)
int dm_usb_gadget_handle_interrupts(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
struct dwc3 *dwc3 = &priv->dwc3;
dwc3_gadget_uboot_handle_interrupt(dwc3);
return 0;
}
static int dwc3_generic_peripheral_probe(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
return dwc3_generic_probe(dev, priv);
}
static int dwc3_generic_peripheral_remove(struct udevice *dev)
{
struct dwc3_generic_priv *priv = dev_get_priv(dev);
return dwc3_generic_remove(dev, priv);
}
U_BOOT_DRIVER(dwc3_generic_peripheral) = {
.name = "dwc3-generic-peripheral",
.id = UCLASS_USB_GADGET_GENERIC,
.ofdata_to_platdata = dwc3_generic_peripheral_ofdata_to_platdata,
.ofdata_to_platdata = dwc3_generic_ofdata_to_platdata,
.probe = dwc3_generic_peripheral_probe,
.remove = dwc3_generic_peripheral_remove,
.priv_auto_alloc_size = sizeof(struct dwc3_generic_peripheral),
.priv_auto_alloc_size = sizeof(struct dwc3_generic_priv),
.platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat),
};
#endif
#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
static int dwc3_generic_host_probe(struct udevice *dev)
{
struct xhci_hcor *hcor;
struct xhci_hccr *hccr;
struct dwc3_generic_host_priv *priv = dev_get_priv(dev);
int rc;
rc = dwc3_generic_probe(dev, &priv->gen_priv);
if (rc)
return rc;
hccr = (struct xhci_hccr *)priv->gen_priv.base;
hcor = (struct xhci_hcor *)(priv->gen_priv.base +
HC_LENGTH(xhci_readl(&(hccr)->cr_capbase)));
return xhci_register(dev, hccr, hcor);
}
static int dwc3_generic_host_remove(struct udevice *dev)
{
struct dwc3_generic_host_priv *priv = dev_get_priv(dev);
int rc;
rc = xhci_deregister(dev);
if (rc)
return rc;
return dwc3_generic_remove(dev, &priv->gen_priv);
}
U_BOOT_DRIVER(dwc3_generic_host) = {
.name = "dwc3-generic-host",
.id = UCLASS_USB,
.ofdata_to_platdata = dwc3_generic_ofdata_to_platdata,
.probe = dwc3_generic_host_probe,
.remove = dwc3_generic_host_remove,
.priv_auto_alloc_size = sizeof(struct dwc3_generic_host_priv),
.platdata_auto_alloc_size = sizeof(struct dwc3_generic_plat),
.ops = &xhci_usb_ops,
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};
#endif
@ -228,10 +306,12 @@ static int dwc3_glue_bind(struct udevice *parent)
driver = "dwc3-generic-peripheral";
#endif
break;
#if defined(CONFIG_SPL_USB_HOST_SUPPORT) || !defined(CONFIG_SPL_BUILD)
case USB_DR_MODE_HOST:
debug("%s: dr_mode: HOST\n", __func__);
driver = "xhci-dwc3";
driver = "dwc3-generic-host";
break;
#endif
default:
debug("%s: unsupported dr_mode\n", __func__);
return -ENODEV;

View file

@ -73,13 +73,6 @@ config USB_XHCI_STI
STiH407 family SoCs. This is a driver for the dwc3 to provide the glue logic
to configure the controller.
config USB_XHCI_ZYNQMP
bool "Support for Xilinx ZynqMP on-chip xHCI USB controller"
depends on ARCH_ZYNQMP
depends on DM_USB
help
Enables support for the on-chip xHCI controller on Xilinx ZynqMP SoCs.
config USB_XHCI_DRA7XX_INDEX
int "DRA7XX xHCI USB index"
range 0 1
@ -141,8 +134,8 @@ config USB_EHCI_MX5
Enables support for the on-chip EHCI controller on i.MX5 SoCs.
config USB_EHCI_MX6
bool "Support for i.MX6 on-chip EHCI USB controller"
depends on ARCH_MX6
bool "Support for i.MX6/i.MX7ULP on-chip EHCI USB controller"
depends on ARCH_MX6 || ARCH_MX7ULP
default y
---help---
Enables support for the on-chip EHCI controller on i.MX6 SoCs.
@ -169,7 +162,7 @@ config USB_EHCI_VF
help
Enables support for the on-chip EHCI controller on Vybrid SoCs.
if USB_EHCI_MX7
if USB_EHCI_MX6 || USB_EHCI_MX7
config MXC_USB_OTG_HACTIVE
bool "USB Power pin high active"

View file

@ -48,7 +48,6 @@ obj-$(CONFIG_USB_XHCI_HCD) += xhci.o xhci-mem.o xhci-ring.o
obj-$(CONFIG_USB_XHCI_DWC3) += xhci-dwc3.o
obj-$(CONFIG_USB_XHCI_DWC3_OF_SIMPLE) += dwc3-of-simple.o
obj-$(CONFIG_USB_XHCI_ROCKCHIP) += xhci-rockchip.o
obj-$(CONFIG_USB_XHCI_ZYNQMP) += xhci-zynqmp.o
obj-$(CONFIG_USB_XHCI_EXYNOS) += xhci-exynos5.o
obj-$(CONFIG_USB_XHCI_FSL) += xhci-fsl.o
obj-$(CONFIG_USB_XHCI_MVEBU) += xhci-mvebu.o

View file

@ -64,10 +64,12 @@ DECLARE_GLOBAL_DATA_PTR;
#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
#define UCMD_RESET (1 << 1) /* controller reset */
#if defined(CONFIG_MX6)
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
static const unsigned phy_bases[] = {
USB_PHY0_BASE_ADDR,
#if defined(USB_PHY1_BASE_ADDR)
USB_PHY1_BASE_ADDR,
#endif
};
static void usb_internal_phy_clock_gate(int index, int on)
@ -84,6 +86,20 @@ static void usb_internal_phy_clock_gate(int index, int on)
static void usb_power_config(int index)
{
#if defined(CONFIG_MX7ULP)
struct usbphy_regs __iomem *usbphy =
(struct usbphy_regs __iomem *)USB_PHY0_BASE_ADDR;
if (index > 0)
return;
writel(ANADIG_USB2_CHRG_DETECT_EN_B |
ANADIG_USB2_CHRG_DETECT_CHK_CHRG_B,
&usbphy->usb1_chrg_detect);
scg_enable_usb_pll(true);
#else
struct anatop_regs __iomem *anatop =
(struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
void __iomem *chrg_detect;
@ -123,6 +139,8 @@ static void usb_power_config(int index)
ANADIG_USB2_PLL_480_CTRL_POWER |
ANADIG_USB2_PLL_480_CTRL_EN_USB_CLKS,
pll_480_ctrl_set);
#endif
}
/* Return 0 : host node, <>0 : device mode */
@ -185,6 +203,14 @@ int usb_phy_mode(int port)
return USB_INIT_HOST;
}
#if defined(CONFIG_MX7ULP)
struct usbnc_regs {
u32 ctrl1;
u32 ctrl2;
u32 reserve0[2];
u32 hsic_ctrl;
};
#else
/* Base address for this IP block is 0x02184800 */
struct usbnc_regs {
u32 ctrl[4]; /* otg/host1-3 */
@ -193,6 +219,8 @@ struct usbnc_regs {
u32 otg_phy_ctrl_0;
u32 uh1_phy_ctrl_0;
};
#endif
#elif defined(CONFIG_MX7)
struct usbnc_regs {
u32 ctrl1;
@ -213,20 +241,12 @@ static void usb_power_config(int index)
struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
(0x10000 * index) + USBNC_OFFSET);
void __iomem *phy_cfg2 = (void __iomem *)(&usbnc->phy_cfg2);
void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl1);
/*
* Clear the ACAENB to enable usb_otg_id detection,
* otherwise it is the ACA detection enabled.
*/
clrbits_le32(phy_cfg2, USBNC_PHYCFG2_ACAENB);
/* Set power polarity to high active */
#ifdef CONFIG_MXC_USB_OTG_HACTIVE
setbits_le32(ctrl, UCTRL_PWR_POL);
#else
clrbits_le32(ctrl, UCTRL_PWR_POL);
#endif
}
int usb_phy_mode(int port)
@ -251,7 +271,7 @@ static void usb_oc_config(int index)
struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
USB_OTHERREGS_OFFSET);
void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl[index]);
#elif defined(CONFIG_MX7)
#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
struct usbnc_regs *usbnc = (struct usbnc_regs *)(USB_BASE_ADDR +
(0x10000 * index) + USBNC_OFFSET);
void __iomem *ctrl = (void __iomem *)(&usbnc->ctrl1);
@ -265,6 +285,13 @@ static void usb_oc_config(int index)
#endif
setbits_le32(ctrl, UCTRL_OVER_CUR_DIS);
/* Set power polarity to high active */
#ifdef CONFIG_MXC_USB_OTG_HACTIVE
setbits_le32(ctrl, UCTRL_PWR_POL);
#else
clrbits_le32(ctrl, UCTRL_PWR_POL);
#endif
}
/**
@ -328,7 +355,7 @@ int ehci_mx6_common_init(struct usb_ehci *ehci, int index)
usb_power_config(index);
usb_oc_config(index);
#if defined(CONFIG_MX6)
#if defined(CONFIG_MX6) || defined(CONFIG_MX7ULP)
usb_internal_phy_clock_gate(index, 1);
usb_phy_enable(index, ehci);
#endif
@ -343,7 +370,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
enum usb_init_type type;
#if defined(CONFIG_MX6)
u32 controller_spacing = 0x200;
#elif defined(CONFIG_MX7)
#elif defined(CONFIG_MX7) || defined(CONFIG_MX7ULP)
u32 controller_spacing = 0x10000;
#endif
struct usb_ehci *ehci = (struct usb_ehci *)(USB_BASE_ADDR +
@ -446,7 +473,7 @@ static int ehci_usb_phy_mode(struct udevice *dev)
* About fsl,usbphy, Refer to
* Documentation/devicetree/bindings/usb/ci-hdrc-usb2.txt.
*/
if (is_mx6()) {
if (is_mx6() || is_mx7ulp()) {
phy_off = fdtdec_lookup_phandle(blob,
offset,
"fsl,usbphy");
@ -513,10 +540,11 @@ static int ehci_usb_bind(struct udevice *dev)
* from which it derives offsets in the PHY and ANATOP register sets.
*
* Here we attempt to calculate these indexes from DT information as
* well as we can. The USB controllers on all existing iMX6/iMX7 SoCs
* are placed next to each other, at addresses incremented by 0x200.
* Thus, the index is derived from the multiple of 0x200 offset from
* the first controller address.
* well as we can. The USB controllers on all existing iMX6 SoCs
* are placed next to each other, at addresses incremented by 0x200,
* and iMX7 their addresses are shifted by 0x10000.
* Thus, the index is derived from the multiple of 0x200 (0x10000 for
* iMX7) offset from the first controller address.
*
* However, to complete conversion of this driver to DT probing, the
* following has to be done:
@ -531,10 +559,10 @@ static int ehci_usb_bind(struct udevice *dev)
* With these changes in place, the ad-hoc indexing goes away and
* the driver is fully converted to DT probing.
*/
fdt_size_t size;
fdt_addr_t addr = devfdt_get_addr_size_index(dev, 0, &size);
u32 controller_spacing = is_mx7() ? 0x10000 : 0x200;
fdt_addr_t addr = devfdt_get_addr_index(dev, 0);
dev->req_seq = (addr - USB_BASE_ADDR) / size;
dev->req_seq = (addr - USB_BASE_ADDR) / controller_spacing;
return 0;
}

View file

@ -14,7 +14,7 @@
#include <usb.h>
#include <dwc3-uboot.h>
#include "xhci.h"
#include <usb/xhci.h>
#include <asm/io.h>
#include <linux/usb/dwc3.h>
#include <linux/usb/otg.h>

View file

@ -27,7 +27,7 @@
#include <linux/compat.h>
#include <linux/usb/dwc3.h>
#include "xhci.h"
#include <usb/xhci.h>
/* Declare global data pointer */
DECLARE_GLOBAL_DATA_PTR;

View file

@ -13,7 +13,7 @@
#include <linux/compat.h>
#include <linux/usb/xhci-fsl.h>
#include <linux/usb/dwc3.h>
#include "xhci.h"
#include <usb/xhci.h>
#include <fsl_errata.h>
#include <fsl_usb.h>
#include <dm.h>

View file

@ -21,7 +21,7 @@
#include <asm/cache.h>
#include <linux/errno.h>
#include "xhci.h"
#include <usb/xhci.h>
#define CACHELINE_SIZE CONFIG_SYS_CACHELINE_SIZE
/**

View file

@ -12,7 +12,7 @@
#include <power/regulator.h>
#include <asm/gpio.h>
#include "xhci.h"
#include <usb/xhci.h>
struct mvebu_xhci_platdata {
fdt_addr_t hcd_base;

View file

@ -19,7 +19,7 @@
#include <linux/usb/dwc3.h>
#include <linux/usb/xhci-omap.h>
#include "xhci.h"
#include <usb/xhci.h>
/* Declare global data pointer */
static struct omap_xhci omap;

View file

@ -9,7 +9,7 @@
#include <dm.h>
#include <pci.h>
#include <usb.h>
#include "xhci.h"
#include <usb/xhci.h>
static void xhci_pci_init(struct udevice *dev, struct xhci_hccr **ret_hccr,
struct xhci_hcor **ret_hcor)

View file

@ -12,7 +12,7 @@
#include <usb.h>
#include <wait_bit.h>
#include "xhci.h"
#include <usb/xhci.h>
#include "xhci-rcar-r8a779x_usb3_v3.h"
/* Register Offset */

View file

@ -19,7 +19,7 @@
#include <asm/unaligned.h>
#include <linux/errno.h>
#include "xhci.h"
#include <usb/xhci.h>
/**
* Is this TRB a link TRB or was the last TRB the last TRB in this event ring

View file

@ -13,7 +13,7 @@
#include <linux/usb/dwc3.h>
#include <power/regulator.h>
#include "xhci.h"
#include <usb/xhci.h>
struct rockchip_xhci_platdata {
fdt_addr_t hcd_base;

View file

@ -1,146 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2015 Xilinx, Inc.
*
* Zynq USB HOST xHCI Controller
*
* Author: Siva Durga Prasad Paladugu<sivadur@xilinx.com>
*
* This file was reused from Freescale USB xHCI
*/
#include <common.h>
#include <dm.h>
#include <usb.h>
#include <linux/errno.h>
#include <asm/arch/hardware.h>
#include <linux/compat.h>
#include <linux/usb/dwc3.h>
#include "xhci.h"
/* Declare global data pointer */
/* Default to the ZYNQMP XHCI defines */
#define USB3_PWRCTL_CLK_CMD_MASK 0x3FE000
#define USB3_PWRCTL_CLK_FREQ_MASK 0xFFC
#define USB3_PHY_PARTIAL_RX_POWERON BIT(6)
#define USB3_PHY_RX_POWERON BIT(14)
#define USB3_PHY_TX_POWERON BIT(15)
#define USB3_PHY_TX_RX_POWERON (USB3_PHY_RX_POWERON | USB3_PHY_TX_POWERON)
#define USB3_PWRCTL_CLK_CMD_SHIFT 14
#define USB3_PWRCTL_CLK_FREQ_SHIFT 22
/* USBOTGSS_WRAPPER definitions */
#define USBOTGSS_WRAPRESET BIT(17)
#define USBOTGSS_DMADISABLE BIT(16)
#define USBOTGSS_STANDBYMODE_NO_STANDBY BIT(4)
#define USBOTGSS_STANDBYMODE_SMRT BIT(5)
#define USBOTGSS_STANDBYMODE_SMRT_WKUP (0x3 << 4)
#define USBOTGSS_IDLEMODE_NOIDLE BIT(2)
#define USBOTGSS_IDLEMODE_SMRT BIT(3)
#define USBOTGSS_IDLEMODE_SMRT_WKUP (0x3 << 2)
/* USBOTGSS_IRQENABLE_SET_0 bit */
#define USBOTGSS_COREIRQ_EN BIT(1)
/* USBOTGSS_IRQENABLE_SET_1 bits */
#define USBOTGSS_IRQ_SET_1_IDPULLUP_FALL_EN BIT(1)
#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_FALL_EN BIT(3)
#define USBOTGSS_IRQ_SET_1_CHRGVBUS_FALL_EN BIT(4)
#define USBOTGSS_IRQ_SET_1_DRVVBUS_FALL_EN BIT(5)
#define USBOTGSS_IRQ_SET_1_IDPULLUP_RISE_EN BIT(8)
#define USBOTGSS_IRQ_SET_1_DISCHRGVBUS_RISE_EN BIT(11)
#define USBOTGSS_IRQ_SET_1_CHRGVBUS_RISE_EN BIT(12)
#define USBOTGSS_IRQ_SET_1_DRVVBUS_RISE_EN BIT(13)
#define USBOTGSS_IRQ_SET_1_OEVT_EN BIT(16)
#define USBOTGSS_IRQ_SET_1_DMADISABLECLR_EN BIT(17)
struct zynqmp_xhci {
struct usb_platdata usb_plat;
struct xhci_ctrl ctrl;
struct xhci_hccr *hcd;
struct dwc3 *dwc3_reg;
};
struct zynqmp_xhci_platdata {
fdt_addr_t hcd_base;
};
static int zynqmp_xhci_core_init(struct zynqmp_xhci *zynqmp_xhci)
{
int ret = 0;
ret = dwc3_core_init(zynqmp_xhci->dwc3_reg);
if (ret) {
debug("%s:failed to initialize core\n", __func__);
return ret;
}
/* We are hard-coding DWC3 core to Host Mode */
dwc3_set_mode(zynqmp_xhci->dwc3_reg, DWC3_GCTL_PRTCAP_HOST);
return ret;
}
void xhci_hcd_stop(int index)
{
/*
* Currently zynqmp socs do not support PHY shutdown from
* sw. But this support may be added in future socs.
*/
return;
}
static int xhci_usb_probe(struct udevice *dev)
{
struct zynqmp_xhci_platdata *plat = dev_get_platdata(dev);
struct zynqmp_xhci *ctx = dev_get_priv(dev);
struct xhci_hcor *hcor;
int ret;
ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
ret = zynqmp_xhci_core_init(ctx);
if (ret) {
puts("XHCI: failed to initialize controller\n");
return -EINVAL;
}
hcor = (struct xhci_hcor *)((ulong)ctx->hcd +
HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
return xhci_register(dev, ctx->hcd, hcor);
}
static int xhci_usb_remove(struct udevice *dev)
{
return xhci_deregister(dev);
}
static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
{
struct zynqmp_xhci_platdata *plat = dev_get_platdata(dev);
const void *blob = gd->fdt_blob;
/* Get the base address for XHCI controller from the device node */
plat->hcd_base = fdtdec_get_addr(blob, dev_of_offset(dev), "reg");
if (plat->hcd_base == FDT_ADDR_T_NONE) {
debug("Can't get the XHCI register base address\n");
return -ENXIO;
}
return 0;
}
U_BOOT_DRIVER(dwc3_generic_host) = {
.name = "dwc3-generic-host",
.id = UCLASS_USB,
.ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
.probe = xhci_usb_probe,
.remove = xhci_usb_remove,
.ops = &xhci_usb_ops,
.platdata_auto_alloc_size = sizeof(struct zynqmp_xhci_platdata),
.priv_auto_alloc_size = sizeof(struct zynqmp_xhci),
.flags = DM_FLAG_ALLOC_PRIV_DMA,
};

View file

@ -28,7 +28,7 @@
#include <asm/cache.h>
#include <asm/unaligned.h>
#include <linux/errno.h>
#include "xhci.h"
#include <usb/xhci.h>
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1

View file

@ -19,7 +19,7 @@
#include <linux/usb/dwc3.h>
#include <linux/usb/xhci-omap.h>
#include "../host/xhci.h"
#include <usb/xhci.h>
#ifdef CONFIG_OMAP_USB3PHY1_HOST
struct usb3_dpll_params {