diff options
author | Tom Rini <trini@konsulko.com> | 2020-04-28 10:08:47 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2020-04-28 10:08:47 -0400 |
commit | 5266ccf957e999d128978328737103f6e522c977 (patch) | |
tree | a50e6260bbc76c6fe86be09901d217e1ab192188 | |
parent | b4778ae94a42a86b34166606cd88c8dfc9899897 (diff) | |
parent | f3bc736e41bd9f3dd4aafe564eb8df9c279b09c4 (diff) | |
download | u-boot-5266ccf957e999d128978328737103f6e522c977.tar.gz |
Merge branch 'master' of git://git.denx.de/u-boot-usb
- DWC2/DWC3 improvements
- Assorted bugfixes
-rw-r--r-- | drivers/usb/gadget/ether.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/dwc2.c | 100 | ||||
-rw-r--r-- | drivers/usb/host/dwc3-sti-glue.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ehci-hcd.c | 9 | ||||
-rw-r--r-- | include/clk.h | 102 |
5 files changed, 193 insertions, 23 deletions
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index a118283984..8533abfd93 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -2472,8 +2472,7 @@ static int _usb_eth_send(struct ether_priv *priv, void *packet, int length) } usb_gadget_handle_interrupts(0); } - if (rndis_pkt) - free(rndis_pkt); + free(rndis_pkt); return 0; drop: diff --git a/drivers/usb/host/dwc2.c b/drivers/usb/host/dwc2.c index e4efaf1e59..f25ed2dab0 100644 --- a/drivers/usb/host/dwc2.c +++ b/drivers/usb/host/dwc2.c @@ -5,13 +5,15 @@ */ #include <common.h> +#include <clk.h> #include <cpu_func.h> #include <dm.h> #include <errno.h> -#include <usb.h> +#include <generic-phy.h> #include <malloc.h> #include <memalign.h> #include <phys2bus.h> +#include <usb.h> #include <usbroothubdes.h> #include <wait_bit.h> #include <asm/io.h> @@ -37,6 +39,8 @@ struct dwc2_priv { #ifdef CONFIG_DM_REGULATOR struct udevice *vbus_supply; #endif + struct phy phy; + struct clk_bulk clks; #else uint8_t *aligned_buffer; uint8_t *status_buffer; @@ -1147,6 +1151,8 @@ static int dwc2_reset(struct udevice *dev) return ret; } + /* force reset to clear all IP register */ + reset_assert_bulk(&priv->resets); ret = reset_deassert_bulk(&priv->resets); if (ret) { reset_release_bulk(&priv->resets); @@ -1213,6 +1219,8 @@ static int dwc2_init_common(struct udevice *dev, struct dwc2_priv *priv) if (readl(®s->gintsts) & DWC2_GINTSTS_CURMODE_HOST) mdelay(1000); + printf("USB DWC2\n"); + return 0; } @@ -1322,13 +1330,95 @@ static int dwc2_usb_ofdata_to_platdata(struct udevice *dev) return 0; } +static int dwc2_setup_phy(struct udevice *dev) +{ + struct dwc2_priv *priv = dev_get_priv(dev); + int ret; + + ret = generic_phy_get_by_index(dev, 0, &priv->phy); + if (ret) { + if (ret == -ENOENT) + return 0; /* no PHY, nothing to do */ + dev_err(dev, "Failed to get USB PHY: %d.\n", ret); + return ret; + } + + ret = generic_phy_init(&priv->phy); + if (ret) { + dev_dbg(dev, "Failed to init USB PHY: %d.\n", ret); + return ret; + } + + ret = generic_phy_power_on(&priv->phy); + if (ret) { + dev_dbg(dev, "Failed to power on USB PHY: %d.\n", ret); + generic_phy_exit(&priv->phy); + return ret; + } + + return 0; +} + +static int dwc2_shutdown_phy(struct udevice *dev) +{ + struct dwc2_priv *priv = dev_get_priv(dev); + int ret; + + /* PHY is not valid when generic_phy_get_by_index() = -ENOENT */ + if (!generic_phy_valid(&priv->phy)) + return 0; /* no PHY, nothing to do */ + + ret = generic_phy_power_off(&priv->phy); + if (ret) { + dev_dbg(dev, "Failed to power off USB PHY: %d.\n", ret); + return ret; + } + + ret = generic_phy_exit(&priv->phy); + if (ret) { + dev_dbg(dev, "Failed to power off USB PHY: %d.\n", ret); + return ret; + } + + return 0; +} + +static int dwc2_clk_init(struct udevice *dev) +{ + struct dwc2_priv *priv = dev_get_priv(dev); + int ret; + + ret = clk_get_bulk(dev, &priv->clks); + if (ret == -ENOSYS || ret == -ENOENT) + return 0; + if (ret) + return ret; + + ret = clk_enable_bulk(&priv->clks); + if (ret) { + clk_release_bulk(&priv->clks); + return ret; + } + + return 0; +} + static int dwc2_usb_probe(struct udevice *dev) { struct dwc2_priv *priv = dev_get_priv(dev); struct usb_bus_priv *bus_priv = dev_get_uclass_priv(dev); + int ret; bus_priv->desc_before_addr = true; + ret = dwc2_clk_init(dev); + if (ret) + return ret; + + ret = dwc2_setup_phy(dev); + if (ret) + return ret; + return dwc2_init_common(dev, priv); } @@ -1341,9 +1431,17 @@ static int dwc2_usb_remove(struct udevice *dev) if (ret) return ret; + ret = dwc2_shutdown_phy(dev); + if (ret) { + dev_dbg(dev, "Failed to shutdown USB PHY: %d.\n", ret); + return ret; + } + dwc2_uninit_common(priv->regs); reset_release_bulk(&priv->resets); + clk_disable_bulk(&priv->clks); + clk_release_bulk(&priv->clks); return 0; } diff --git a/drivers/usb/host/dwc3-sti-glue.c b/drivers/usb/host/dwc3-sti-glue.c index c99a1985cc..99d4e29414 100644 --- a/drivers/usb/host/dwc3-sti-glue.c +++ b/drivers/usb/host/dwc3-sti-glue.c @@ -239,7 +239,7 @@ static const struct udevice_id sti_dwc3_glue_ids[] = { U_BOOT_DRIVER(dwc3_sti_glue) = { .name = "dwc3_sti_glue", - .id = UCLASS_MISC, + .id = UCLASS_NOP, .of_match = sti_dwc3_glue_ids, .ofdata_to_platdata = sti_dwc3_glue_ofdata_to_platdata, .probe = sti_dwc3_glue_probe, diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 1edb344d0f..a2a85db1e7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1413,13 +1413,10 @@ static struct int_queue *_ehci_create_int_queue(struct usb_device *dev, debug("Exit create_int_queue\n"); return result; fail3: - if (result->tds) - free(result->tds); + free(result->tds); fail2: - if (result->first) - free(result->first); - if (result) - free(result); + free(result->first); + free(result); fail1: return NULL; } diff --git a/include/clk.h b/include/clk.h index 3336301815..60c4b7d075 100644 --- a/include/clk.h +++ b/include/clk.h @@ -9,6 +9,7 @@ #define _CLK_H_ #include <dm/ofnode.h> +#include <linux/err.h> #include <linux/errno.h> #include <linux/types.h> @@ -312,6 +313,7 @@ static inline int clk_release_bulk(struct clk_bulk *bulk) return clk_release_all(bulk->clks, bulk->count); } +#if CONFIG_IS_ENABLED(CLK) /** * clk_request - Request a clock by provider-specific ID. * @@ -433,19 +435,6 @@ int clk_disable_bulk(struct clk_bulk *bulk); */ bool clk_is_match(const struct clk *p, const struct clk *q); -int soc_clk_dump(void); - -/** - * clk_valid() - check if clk is valid - * - * @clk: the clock to check - * @return true if valid, or false - */ -static inline bool clk_valid(struct clk *clk) -{ - return clk && !!clk->dev; -} - /** * clk_get_by_id() - Get the clock by its ID * @@ -465,6 +454,93 @@ int clk_get_by_id(ulong id, struct clk **clkp); * @return true on binded, or false on no */ bool clk_dev_binded(struct clk *clk); + +#else /* CONFIG_IS_ENABLED(CLK) */ + +static inline int clk_request(struct udevice *dev, struct clk *clk) +{ + return -ENOSYS; +} + +static inline int clk_free(struct clk *clk) +{ + return 0; +} + +static inline ulong clk_get_rate(struct clk *clk) +{ + return -ENOSYS; +} + +static inline struct clk *clk_get_parent(struct clk *clk) +{ + return ERR_PTR(-ENOSYS); +} + +static inline long long clk_get_parent_rate(struct clk *clk) +{ + return -ENOSYS; +} + +static inline ulong clk_set_rate(struct clk *clk, ulong rate) +{ + return -ENOSYS; +} + +static inline int clk_set_parent(struct clk *clk, struct clk *parent) +{ + return -ENOSYS; +} + +static inline int clk_enable(struct clk *clk) +{ + return 0; +} + +static inline int clk_enable_bulk(struct clk_bulk *bulk) +{ + return 0; +} + +static inline int clk_disable(struct clk *clk) +{ + return 0; +} + +static inline int clk_disable_bulk(struct clk_bulk *bulk) +{ + return 0; +} + +static inline bool clk_is_match(const struct clk *p, const struct clk *q) +{ + return false; +} + +static inline int clk_get_by_id(ulong id, struct clk **clkp) +{ + return -ENOSYS; +} + +static inline bool clk_dev_binded(struct clk *clk) +{ + return false; +} +#endif /* CONFIG_IS_ENABLED(CLK) */ + +/** + * clk_valid() - check if clk is valid + * + * @clk: the clock to check + * @return true if valid, or false + */ +static inline bool clk_valid(struct clk *clk) +{ + return clk && !!clk->dev; +} + +int soc_clk_dump(void); + #endif #define clk_prepare_enable(clk) clk_enable(clk) |