Message ID | 20190428214528.935-4-aford173@gmail.com |
---|---|
State | Superseded |
Delegated to: | Tom Rini |
Headers | show |
Series | [U-Boot,1/4] usb: ohci: Re-enable commented out delay | expand |
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 <aford173@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 > +} > + > 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 >
On Mon, Apr 29, 2019 at 4:54 AM Marek Vasut <marex@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 <aford173@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
On 4/30/19 11:24 AM, Adam Ford wrote: > On Mon, Apr 29, 2019 at 4:54 AM Marek Vasut <marex@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 <aford173@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? Just 3/4 and 4/4 is enough. Rebase on u-boot-usb/master and make sure not to drop $subject from the cover letter (this series has it empty, which made me almost miss it)
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--) { + 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); +} + 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; + + 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
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 <aford173@gmail.com>