[U-Boot] [PATCH 0/5] dm: usb: Start of sunxi support

This series adds a few starts for sunxi driver model support for USB. I don't intend to finish it, but hopefully it helps things get going.
Simon Glass (5): dm: sunxi: gpio: Add temporary implementation of name_to_gpio() dm: sunxi: gpio: Rename GPIOs to include a 'P' prefix dm: gpio: Remove default declaration of name_to_gpio() dm: usb: Add more debugging in ehci-hcd.c WIP: sunxi: Start of driver model USB implementation
common/cmd_gpio.c | 7 +++++ drivers/gpio/sunxi_gpio.c | 18 +++++++++-- drivers/usb/host/ehci-hcd.c | 16 +++++++--- drivers/usb/host/ehci-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+), 7 deletions(-)

Until sunxi moves to device tree (e.g. for USB) we need to convert named GPIOs to numbers. Add a function to do this.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/gpio/sunxi_gpio.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index cf5c624..e459895 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -172,6 +172,17 @@ int sunxi_name_to_gpio(const char *name) #endif
#ifdef CONFIG_DM_GPIO +/* TODO(sjg@chromium.org): Remove this function and use device tree */ +int sunxi_name_to_gpio(const char *name) +{ + unsigned int gpio; + int ret; + + ret = gpio_lookup_name(name, NULL, NULL, &gpio); + + return ret ? ret : gpio; +} + static int sunxi_gpio_direction_input(struct udevice *dev, unsigned offset) { struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);

By convention, sunxi GPIOs are named PA1, PA2 instead of A1, A2. Change the driver model GPIO driver for sunxi to use these names.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/gpio/sunxi_gpio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index e459895..89209df 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -260,10 +260,11 @@ static char *gpio_bank_name(int bank) { char *name;
- name = malloc(2); + name = malloc(3); if (name) { - name[0] = 'A' + bank; - name[1] = '\0'; + name[0] = 'P'; + name[1] = 'A' + bank; + name[2] = '\0'; }
return name;

With driver model we should not use this function. Drivers should use device tree to find their GPIOs.
Signed-off-by: Simon Glass sjg@chromium.org ---
common/cmd_gpio.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/common/cmd_gpio.c b/common/cmd_gpio.c index 65d6df4..9dae011 100644 --- a/common/cmd_gpio.c +++ b/common/cmd_gpio.c @@ -12,10 +12,17 @@ #include <dm.h> #include <asm/gpio.h>
+/* + * Don't use this function with driver model. Use gpio_request_by_name() and + * similar. We should use a struct gpio_desc for GPIOs for specifying a GPIO, + * not an integer. + */ +#ifndef CONFIG_DM_GPIO __weak int name_to_gpio(const char *name) { return simple_strtoul(name, NULL, 10); } +#endif
enum gpio_cmd { GPIO_INPUT,

Add some debugging to detect init failure.
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/usb/host/ehci-hcd.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index bd9861d..066e7c5 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1140,26 +1140,34 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller) ctrl->ops = default_ehci_ops;
rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor); - if (rc) + if (rc) { + debug("%s: ehci_hcd_init failed, rc=%d\n", __func__, rc); return rc; + } if (init == USB_INIT_DEVICE) goto done;
/* EHCI spec section 4.1 */ - if (ehci_reset(ctrl)) + if (ehci_reset(ctrl)) { + debug("%s: ehci_reset failed\n", __func__); return -1; + }
#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET) rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor); - if (rc) + if (rc) { + debug("%s: ehci_hcd_init2 failed, rc=%d\n", __func__, rc); return rc; + } #endif #ifdef CONFIG_USB_EHCI_FARADAY tweaks |= EHCI_TWEAK_NO_INIT_CF; #endif rc = ehci_common_init(ctrl, tweaks); - if (rc) + if (rc) { + debug("%s: ehci_common_init failed, rc=%d\n", __func__, rc); return rc; + }
ctrl->rootdev = 0; done:

On Saturday, April 18, 2015 at 07:33:46 PM, Simon Glass wrote:
Add some debugging to detect init failure.
Signed-off-by: Simon Glass sjg@chromium.org
Reviewed-by: Marek Vasut marex@denx.de
Best regards, Marek Vasut

This just has a few starting points. Work remaining:
- Get GPIOs from the device tree correctly, and claim them - Perhaps create a USB phy class and driver for sunxi - Perhaps allow USB ports to be specified by some sort of peripherals ID instead of an index?
Signed-off-by: Simon Glass sjg@chromium.org ---
drivers/usb/host/ehci-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+)
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c index eda9f69..5b92edf 100644 --- a/drivers/usb/host/ehci-sunxi.c +++ b/drivers/usb/host/ehci-sunxi.c @@ -11,8 +11,15 @@
#include <asm/arch/usbc.h> #include <common.h> +#include <asm/gpio.h> #include "ehci.h"
+struct ehci_sunxi_priv { + struct gpio_desc vbus_gpio; +}; + +#ifndef CONFIG_DM_USB + int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr, struct ehci_hcor **hcor) { @@ -44,3 +51,67 @@ int ehci_hcd_stop(int index)
return sunxi_usbc_free_resources(index + 1); } +#endif + +#ifdef CONFIG_DM_USB +static int ehci_usb_ofdata_to_platdata(struct udevice *dev) +{ + return 0; +} + +static int ehci_usb_probe(struct udevice *dev) +{ + struct usb_platdata *plat = dev_get_platdata(dev); + struct ehci_sunxi_priv *priv = dev_get_priv(dev); + struct ehci_hccr *hccr; + struct ehci_hcor *hcor; + static bool clk_done; + int ret; + + /* TODO: Need to get this from the correct node */ + ret = gpio_request_by_name(dev, "gpio", &priv->vbus_gpio, GPIOD_IS_OUT); + if (ret) + return ret; + + hccr = (struct ehci_hccr *)&priv->reg->cap_length; + hcor = (struct ehci_hcor *)&priv->reg->usb_cmd; + if (!clk_done) { + config_clock(get_pll_timing(&fdt_usb_controllers[priv->type])); + clk_done = true; + } + + return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0, + plat->init_type); +} + +static int ehci_usb_remove(struct udevice *dev) +{ + int ret; + + ret = ehci_deregister(dev); + if (ret) + return ret; + + /* TODO: free GPIOs */ + + return 0; +} + +static const struct udevice_id ehci_usb_ids[] = { + { .compatible = "allwinner,sun7i-a20-ehci", }, + { } +}; + +U_BOOT_DRIVER(usb_ehci) = { + .name = "ehci_sunxi", + .id = UCLASS_USB, + .of_match = ehci_usb_ids, + .ofdata_to_platdata = ehci_usb_ofdata_to_platdata, + .probe = ehci_usb_probe, + .remove = ehci_usb_remove, + .ops = &ehci_usb_ops, + .platdata_auto_alloc_size = sizeof(struct usb_platdata), + .priv_auto_alloc_size = sizeof(struct ehci_sunxi_priv), + .flags = DM_FLAG_ALLOC_PRIV_DMA, +}; +#endif

Hi Simon,
On 18-04-15 19:33, Simon Glass wrote:
This series adds a few starts for sunxi driver model support for USB. I don't intend to finish it, but hopefully it helps things get going.
Simon Glass (5): dm: sunxi: gpio: Add temporary implementation of name_to_gpio() dm: sunxi: gpio: Rename GPIOs to include a 'P' prefix dm: gpio: Remove default declaration of name_to_gpio() dm: usb: Add more debugging in ehci-hcd.c WIP: sunxi: Start of driver model USB implementation
Thanks, I'll try to pick this series up once I'm done with my current sunxi dm efforts, which are to basically move all the sunxi boards to the device-model, so that we can stop putting #ifdef CONFIG_DM... blocks into sunxi specific code, and instead simply always device-model everywhere for sunxi.
Regards,
Hans

Hi Hans,
On 18 April 2015 at 15:50, Hans de Goede hdegoede@redhat.com wrote:
Hi Simon,
On 18-04-15 19:33, Simon Glass wrote:
This series adds a few starts for sunxi driver model support for USB. I don't intend to finish it, but hopefully it helps things get going.
Simon Glass (5): dm: sunxi: gpio: Add temporary implementation of name_to_gpio() dm: sunxi: gpio: Rename GPIOs to include a 'P' prefix dm: gpio: Remove default declaration of name_to_gpio() dm: usb: Add more debugging in ehci-hcd.c WIP: sunxi: Start of driver model USB implementation
Thanks, I'll try to pick this series up once I'm done with my current sunxi dm efforts, which are to basically move all the sunxi boards to the device-model, so that we can stop putting #ifdef CONFIG_DM... blocks into sunxi specific code, and instead simply always device-model everywhere for sunxi.
Sounds great!
Regards, Simon
participants (3)
-
Hans de Goede
-
Marek Vasut
-
Simon Glass