On Mon, Apr 29, 2019 at 4:54 AM Marek Vasut <ma...@denx.de> wrote: > > On 4/28/19 11:45 PM, Adam Ford wrote: > > This patch reuses some former code for the hawkboard, combines it > > with some some similar DM_USB compatible code for the OHCI driver, > > and enables the use of the da850's OHCI controller with DM_USB > > compatibility. > > > > Signed-off-by: Adam Ford <aford...@gmail.com> > > > > diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig > > index 0fbc115801..0d8ab3b651 100644 > > --- a/drivers/usb/host/Kconfig > > +++ b/drivers/usb/host/Kconfig > > @@ -239,6 +239,11 @@ config USB_OHCI_GENERIC > > ---help--- > > Enables support for generic OHCI controller. > > > > +config USB_OHCI_DA8XX > > + bool "Support for da850 OHCI USB controller" > > + help > > + Enable support for the da850 USB controller. > > + > > endif # USB_OHCI_HCD > > > > config USB_UHCI_HCD > > diff --git a/drivers/usb/host/ohci-da8xx.c b/drivers/usb/host/ohci-da8xx.c > > index 47ad3f34d5..0f38791973 100644 > > --- a/drivers/usb/host/ohci-da8xx.c > > +++ b/drivers/usb/host/ohci-da8xx.c > > @@ -4,9 +4,63 @@ > > */ > > > > #include <common.h> > > - > > +#include <asm/io.h> > > +#include <clk.h> > > +#include <dm.h> > > +#include <dm/ofnode.h> > > +#include <generic-phy.h> > > +#include <reset.h> > > +#include "ohci.h" > > #include <asm/arch/da8xx-usb.h> > > > > +struct da8xx_ohci { > > + ohci_t ohci; > > + struct clk *clocks; /* clock list */ > > + struct phy phy; > > + int clock_count; /* number of clock in clock list */ > > +}; > > + > > +static int usb_phy_on(void) > > +{ > > + u32 timeout; > > + u32 cfgchip2; > > + > > + cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); > > + > > + cfgchip2 &= ~(CFGCHIP2_RESET | CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | > > + CFGCHIP2_OTGMODE | CFGCHIP2_REFFREQ | > > + CFGCHIP2_USB1PHYCLKMUX); > > + cfgchip2 |= CFGCHIP2_SESENDEN | CFGCHIP2_VBDTCTEN | > > CFGCHIP2_PHY_PLLON | > > + CFGCHIP2_REFFREQ_24MHZ | CFGCHIP2_USB2PHYCLKMUX | > > + CFGCHIP2_USB1SUSPENDM; > > + > > + writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); > > + > > + /* wait until the usb phy pll locks */ > > + timeout = 0x7FFFFFF; > > + > > + while (timeout--) { > > Use get_timer() for the timeout. > > > + if (readl(&davinci_syscfg_regs->cfgchip2) & CFGCHIP2_PHYCLKGD) > > + return 1; > > + } > > + > > + /* USB phy was not turned on */ > > + return 0; > > +} > > + > > +static void usb_phy_off(void) > > +{ > > + u32 cfgchip2; > > + > > + /* > > + * Power down the on-chip PHY. > > + */ > > + cfgchip2 = readl(&davinci_syscfg_regs->cfgchip2); > > + cfgchip2 &= ~(CFGCHIP2_PHY_PLLON | CFGCHIP2_USB1SUSPENDM); > > + cfgchip2 |= CFGCHIP2_PHYPWRDN | CFGCHIP2_OTGPWRDN | CFGCHIP2_RESET; > > + writel(cfgchip2, &davinci_syscfg_regs->cfgchip2); > > clrsetbits
Marek - I will be submitting a V2 with your suggestions. It seems like some of the segments are going to be applied, do you want just do a V2 on the this one, or re-submit the whole series? > > > +} > > + > > int usb_cpu_init(void) > > { > > /* enable psc for usb2.0 */ > > @@ -37,3 +91,94 @@ int usb_cpu_init_fail(void) > > { > > return usb_cpu_stop(); > > } > > + > > +#if CONFIG_IS_ENABLED(DM_USB) > > +static int ohci_da8xx_probe(struct udevice *dev) > > +{ > > + struct ohci_regs *regs = (struct ohci_regs *)devfdt_get_addr(dev); > > + struct da8xx_ohci *priv = dev_get_priv(dev); > > + int i, err, ret, clock_nb; > > + > > + err = 0; > > + priv->clock_count = 0; > > + clock_nb = dev_count_phandle_with_args(dev, "clocks", "#clock-cells"); > > + if (clock_nb > 0) { > > + priv->clocks = devm_kcalloc(dev, clock_nb, sizeof(struct clk), > > + GFP_KERNEL); > > + if (!priv->clocks) > > + return -ENOMEM; > > clk_enable_bulk() > > > + for (i = 0; i < clock_nb; i++) { > > + err = clk_get_by_index(dev, i, &priv->clocks[i]); > > + if (err < 0) > > + break; > > + > > + err = clk_enable(&priv->clocks[i]); > > + if (err) { > > + dev_err(dev, "failed to enable clock %d\n", > > i); > > + clk_free(&priv->clocks[i]); > > + goto clk_err; > > + } > > + priv->clock_count++; > > + } > > + } else if (clock_nb != -ENOENT) { > > + dev_err(dev, "failed to get clock phandle(%d)\n", clock_nb); > > + return clock_nb; > > + } > > + > > + err = usb_cpu_init(); > > + > > + if (err) > > + goto clk_err; > > + > > + err = ohci_register(dev, regs); > > + if (err) > > + goto phy_err; > > + > > + return 0; > > + > > +phy_err: > > + ret = usb_cpu_stop(); > > + if (ret) > > + dev_err(dev, "failed to shutdown usb phy\n"); > > + > > +clk_err: > > + ret = clk_release_all(priv->clocks, priv->clock_count); > > + if (ret) > > + dev_err(dev, "failed to disable all clocks\n"); > > + > > + return err; > > +} > > + > > +static int ohci_da8xx_remove(struct udevice *dev) > > +{ > > + struct da8xx_ohci *priv = dev_get_priv(dev); > > + int ret; > > + > > + ret = ohci_deregister(dev); > > + if (ret) > > + return ret; > > + > > + ret = usb_cpu_stop(); > > + if (ret) > > + return ret; > > + > > + return clk_release_all(priv->clocks, priv->clock_count); > > +} > > + > > +static const struct udevice_id da8xx_ohci_ids[] = { > > + { .compatible = "ti,da830-ohci" }, > > + { } > > +}; > > + > > +U_BOOT_DRIVER(ohci_generic) = { > > + .name = "ohci-da8xx", > > + .id = UCLASS_USB, > > + .of_match = da8xx_ohci_ids, > > + .probe = ohci_da8xx_probe, > > + .remove = ohci_da8xx_remove, > > + .ops = &ohci_usb_ops, > > + .priv_auto_alloc_size = sizeof(struct da8xx_ohci), > > + .flags = DM_FLAG_ALLOC_PRIV_DMA, > > +}; > > +#endif > > > > > -- > Best regards, > Marek Vasut _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot