Message ID | 1490176456-24813-7-git-send-email-patrice.chotard@st.com |
---|---|
State | Superseded |
Delegated to: | Marek Vasut |
Headers | show |
Hi Patrice, On 22 March 2017 at 03:54, <patrice.chotard@st.com> wrote: > From: Patrice Chotard <patrice.chotard@st.com> > > Add support for on-chip ehci controller available > on STMicrolectronics SoCs. > ehci support will be then available on both type A > USB 2.0 connectors. > > Signed-off-by: Patrice Chotard <patrice.chotard@st.com> > --- > > v2: _ update error messages > _ add remove callback to put core into reset > > > drivers/usb/host/Kconfig | 9 ++++ > drivers/usb/host/Makefile | 1 + > drivers/usb/host/ehci-sti.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 125 insertions(+) > create mode 100644 drivers/usb/host/ehci-sti.c Reviewed-by: Simon Glass <sjg@chromium.org> Please see below. > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > index 5129a57..d66f49e 100644 > --- a/drivers/usb/host/Kconfig > +++ b/drivers/usb/host/Kconfig > @@ -120,6 +120,15 @@ config USB_EHCI_MSM > This driver supports combination of Chipidea USB controller > and Synapsys USB PHY in host mode only. > > +config USB_EHCI_STI > + bool "Support for STMicroelectronics on-chip EHCI USB controller" > + depends on ARCH_STI > + select STI_PHY_USB > + default y > + ---help--- > + Enables support for the on-chip EHCI controller on > + STMicroelectronics SoCs. > + > config USB_EHCI_ZYNQ > bool "Support for Xilinx Zynq on-chip EHCI USB controller" > depends on ARCH_ZYNQ > diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile > index 58c0cf5..303aa32 100644 > --- a/drivers/usb/host/Makefile > +++ b/drivers/usb/host/Makefile > @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o > obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o > obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o > obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o > +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o > obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o > obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o > obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o > diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c > new file mode 100644 > index 0000000..390709d > --- /dev/null > +++ b/drivers/usb/host/ehci-sti.c > @@ -0,0 +1,115 @@ > +/* > + * Copyright (c) 2017 > + * Patrice Chotard <patrice.chotard@st.com> > + * > + * SPDX-License-Identifier: GPL-2.0+ > + */ > + > +#include <common.h> > +#include <asm/io.h> > +#include <dm.h> > +#include <errno.h> > +#include "ehci.h" > +#include <reset-uclass.h> > +#include <usb.h> > + > +DECLARE_GLOBAL_DATA_PTR; > + > +struct sti_ehci_priv { > + struct ehci_ctrl ctrl; > + struct reset_ctl power_ctl; > + struct reset_ctl softreset_ctl; > +}; > + > +static int sti_ehci_probe(struct udevice *dev) > +{ > + struct sti_ehci_priv *priv = dev_get_priv(dev); > + struct ehci_hccr *hccr = priv->ctrl.hccr; > + struct ehci_hcor *hcor; > + struct udevice *dev_phy; > + int ret, phy_node; > + > + hccr = (struct ehci_hccr *)dev_get_addr(dev); > + > + if (hccr == (void *)FDT_ADDR_T_NONE) > + return -EINVAL; > + > + ret = reset_get_by_name(dev, "power", &priv->power_ctl); > + if (ret) { > + error("can't get power for %s (%d)", dev->name, ret); > + return ret; > + } > + > + ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl); > + if (ret) { > + error("can't get soft reset for %s (%d)", dev->name, ret); > + return ret; > + } > + > + ret = reset_deassert(&priv->softreset_ctl); > + if (ret < 0) { > + error("EHCI soft reset deassert failed: %d", ret); > + return ret; > + } > + > + ret = reset_deassert(&priv->power_ctl); > + if (ret < 0) { > + error("EHCI power deassert failed: %d", ret); > + return ret; > + } > + > + /* get phy node */ > + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys"); > + if (phy_node <= 0) { > + error("USB PHY DT node not found.\n"); > + return -ENODEV; > + } > + > + /* probe associated phy */ > + ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); Is it possible to replace the above two calls with uclass_get_device_by_phandle()? > + > + hcor = (struct ehci_hcor *)((phys_addr_t)hccr + > + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); > + > + return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); > +} > + > +static int sti_ehci_remove(struct udevice *dev) > +{ > + struct sti_ehci_priv *priv = dev_get_priv(dev); > + int ret; > + > + ret = ehci_deregister(dev); > + if (ret) > + return ret; > + > + ret = reset_assert(&priv->power_ctl); > + if (ret < 0) { > + error("EHCI power assert failed: %d", ret); > + return ret; > + } > + > + ret = reset_assert(&priv->softreset_ctl); > + if (ret < 0) { > + error("EHCI soft reset assert failed: %d", ret); > + return ret; > + } > + > + return 0; > +} > + > +static const struct udevice_id sti_usb_ids[] = { > + { .compatible = "st,st-ehci-300x" }, > + { } > +}; > + > +U_BOOT_DRIVER(ehci_sti) = { > + .name = "ehci_sti", > + .id = UCLASS_USB, > + .of_match = sti_usb_ids, > + .probe = sti_ehci_probe, > + .remove = sti_ehci_remove, > + .ops = &ehci_usb_ops, > + .priv_auto_alloc_size = sizeof(struct sti_ehci_priv), > + .flags = DM_FLAG_ALLOC_PRIV_DMA, > +}; > -- > 1.9.1 > Regards, Simon
Hi Simon On 04/01/2017 06:20 AM, Simon Glass wrote: > Hi Patrice, > > On 22 March 2017 at 03:54, <patrice.chotard@st.com> wrote: >> From: Patrice Chotard <patrice.chotard@st.com> >> >> Add support for on-chip ehci controller available >> on STMicrolectronics SoCs. >> ehci support will be then available on both type A >> USB 2.0 connectors. >> >> Signed-off-by: Patrice Chotard <patrice.chotard@st.com> >> --- >> >> v2: _ update error messages >> _ add remove callback to put core into reset >> >> >> drivers/usb/host/Kconfig | 9 ++++ >> drivers/usb/host/Makefile | 1 + >> drivers/usb/host/ehci-sti.c | 115 ++++++++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 125 insertions(+) >> create mode 100644 drivers/usb/host/ehci-sti.c > > Reviewed-by: Simon Glass <sjg@chromium.org> > > Please see below. > >> >> diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig >> index 5129a57..d66f49e 100644 >> --- a/drivers/usb/host/Kconfig >> +++ b/drivers/usb/host/Kconfig >> @@ -120,6 +120,15 @@ config USB_EHCI_MSM >> This driver supports combination of Chipidea USB controller >> and Synapsys USB PHY in host mode only. >> >> +config USB_EHCI_STI >> + bool "Support for STMicroelectronics on-chip EHCI USB controller" >> + depends on ARCH_STI >> + select STI_PHY_USB >> + default y >> + ---help--- >> + Enables support for the on-chip EHCI controller on >> + STMicroelectronics SoCs. >> + >> config USB_EHCI_ZYNQ >> bool "Support for Xilinx Zynq on-chip EHCI USB controller" >> depends on ARCH_ZYNQ >> diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile >> index 58c0cf5..303aa32 100644 >> --- a/drivers/usb/host/Makefile >> +++ b/drivers/usb/host/Makefile >> @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o >> obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o >> obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o >> obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o >> +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o >> obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o >> obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o >> obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o >> diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c >> new file mode 100644 >> index 0000000..390709d >> --- /dev/null >> +++ b/drivers/usb/host/ehci-sti.c >> @@ -0,0 +1,115 @@ >> +/* >> + * Copyright (c) 2017 >> + * Patrice Chotard <patrice.chotard@st.com> >> + * >> + * SPDX-License-Identifier: GPL-2.0+ >> + */ >> + >> +#include <common.h> >> +#include <asm/io.h> >> +#include <dm.h> >> +#include <errno.h> >> +#include "ehci.h" >> +#include <reset-uclass.h> >> +#include <usb.h> >> + >> +DECLARE_GLOBAL_DATA_PTR; >> + >> +struct sti_ehci_priv { >> + struct ehci_ctrl ctrl; >> + struct reset_ctl power_ctl; >> + struct reset_ctl softreset_ctl; >> +}; >> + >> +static int sti_ehci_probe(struct udevice *dev) >> +{ >> + struct sti_ehci_priv *priv = dev_get_priv(dev); >> + struct ehci_hccr *hccr = priv->ctrl.hccr; >> + struct ehci_hcor *hcor; >> + struct udevice *dev_phy; >> + int ret, phy_node; >> + >> + hccr = (struct ehci_hccr *)dev_get_addr(dev); >> + >> + if (hccr == (void *)FDT_ADDR_T_NONE) >> + return -EINVAL; >> + >> + ret = reset_get_by_name(dev, "power", &priv->power_ctl); >> + if (ret) { >> + error("can't get power for %s (%d)", dev->name, ret); >> + return ret; >> + } >> + >> + ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl); >> + if (ret) { >> + error("can't get soft reset for %s (%d)", dev->name, ret); >> + return ret; >> + } >> + >> + ret = reset_deassert(&priv->softreset_ctl); >> + if (ret < 0) { >> + error("EHCI soft reset deassert failed: %d", ret); >> + return ret; >> + } >> + >> + ret = reset_deassert(&priv->power_ctl); >> + if (ret < 0) { >> + error("EHCI power deassert failed: %d", ret); >> + return ret; >> + } >> + >> + /* get phy node */ >> + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys"); >> + if (phy_node <= 0) { >> + error("USB PHY DT node not found.\n"); >> + return -ENODEV; >> + } >> + >> + /* probe associated phy */ >> + ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); > > Is it possible to replace the above two calls with > uclass_get_device_by_phandle()? I have send a v3 of this series on 28th April in which i have implemented a simple USB PHY UCLASS as you requested in [1] [1] https://www.mail-archive.com/u-boot@lists.denx.de/msg242330.html Patrice > >> + >> + hcor = (struct ehci_hcor *)((phys_addr_t)hccr + >> + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); >> + >> + return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); >> +} >> + >> +static int sti_ehci_remove(struct udevice *dev) >> +{ >> + struct sti_ehci_priv *priv = dev_get_priv(dev); >> + int ret; >> + >> + ret = ehci_deregister(dev); >> + if (ret) >> + return ret; >> + >> + ret = reset_assert(&priv->power_ctl); >> + if (ret < 0) { >> + error("EHCI power assert failed: %d", ret); >> + return ret; >> + } >> + >> + ret = reset_assert(&priv->softreset_ctl); >> + if (ret < 0) { >> + error("EHCI soft reset assert failed: %d", ret); >> + return ret; >> + } >> + >> + return 0; >> +} >> + >> +static const struct udevice_id sti_usb_ids[] = { >> + { .compatible = "st,st-ehci-300x" }, >> + { } >> +}; >> + >> +U_BOOT_DRIVER(ehci_sti) = { >> + .name = "ehci_sti", >> + .id = UCLASS_USB, >> + .of_match = sti_usb_ids, >> + .probe = sti_ehci_probe, >> + .remove = sti_ehci_remove, >> + .ops = &ehci_usb_ops, >> + .priv_auto_alloc_size = sizeof(struct sti_ehci_priv), >> + .flags = DM_FLAG_ALLOC_PRIV_DMA, >> +}; >> -- >> 1.9.1 >> > > Regards, > Simon >
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 5129a57..d66f49e 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -120,6 +120,15 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only. +config USB_EHCI_STI + bool "Support for STMicroelectronics on-chip EHCI USB controller" + depends on ARCH_STI + select STI_PHY_USB + default y + ---help--- + Enables support for the on-chip EHCI controller on + STMicroelectronics SoCs. + config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 58c0cf5..303aa32 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -46,6 +46,7 @@ obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o obj-$(CONFIG_USB_EHCI_MSM) += ehci-msm.o obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o +obj-$(CONFIG_USB_EHCI_STI) += ehci-sti.o obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o diff --git a/drivers/usb/host/ehci-sti.c b/drivers/usb/host/ehci-sti.c new file mode 100644 index 0000000..390709d --- /dev/null +++ b/drivers/usb/host/ehci-sti.c @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2017 + * Patrice Chotard <patrice.chotard@st.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <dm.h> +#include <errno.h> +#include "ehci.h" +#include <reset-uclass.h> +#include <usb.h> + +DECLARE_GLOBAL_DATA_PTR; + +struct sti_ehci_priv { + struct ehci_ctrl ctrl; + struct reset_ctl power_ctl; + struct reset_ctl softreset_ctl; +}; + +static int sti_ehci_probe(struct udevice *dev) +{ + struct sti_ehci_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr = priv->ctrl.hccr; + struct ehci_hcor *hcor; + struct udevice *dev_phy; + int ret, phy_node; + + hccr = (struct ehci_hccr *)dev_get_addr(dev); + + if (hccr == (void *)FDT_ADDR_T_NONE) + return -EINVAL; + + ret = reset_get_by_name(dev, "power", &priv->power_ctl); + if (ret) { + error("can't get power for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_get_by_name(dev, "softreset", &priv->softreset_ctl); + if (ret) { + error("can't get soft reset for %s (%d)", dev->name, ret); + return ret; + } + + ret = reset_deassert(&priv->softreset_ctl); + if (ret < 0) { + error("EHCI soft reset deassert failed: %d", ret); + return ret; + } + + ret = reset_deassert(&priv->power_ctl); + if (ret < 0) { + error("EHCI power deassert failed: %d", ret); + return ret; + } + + /* get phy node */ + phy_node = fdtdec_lookup_phandle(gd->fdt_blob, dev->of_offset, "phys"); + if (phy_node <= 0) { + error("USB PHY DT node not found.\n"); + return -ENODEV; + } + + /* probe associated phy */ + ret = uclass_get_device_by_of_offset(UCLASS_MISC, phy_node, &dev_phy); + + hcor = (struct ehci_hcor *)((phys_addr_t)hccr + + HC_LENGTH(ehci_readl(&(hccr)->cr_capbase))); + + return ehci_register(dev, hccr, hcor, NULL, 0, USB_INIT_HOST); +} + +static int sti_ehci_remove(struct udevice *dev) +{ + struct sti_ehci_priv *priv = dev_get_priv(dev); + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; + + ret = reset_assert(&priv->power_ctl); + if (ret < 0) { + error("EHCI power assert failed: %d", ret); + return ret; + } + + ret = reset_assert(&priv->softreset_ctl); + if (ret < 0) { + error("EHCI soft reset assert failed: %d", ret); + return ret; + } + + return 0; +} + +static const struct udevice_id sti_usb_ids[] = { + { .compatible = "st,st-ehci-300x" }, + { } +}; + +U_BOOT_DRIVER(ehci_sti) = { + .name = "ehci_sti", + .id = UCLASS_USB, + .of_match = sti_usb_ids, + .probe = sti_ehci_probe, + .remove = sti_ehci_remove, + .ops = &ehci_usb_ops, + .priv_auto_alloc_size = sizeof(struct sti_ehci_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +};