Skip to contentSkip to conversation

dm: usb: Start of sunxi support

PATCH New Simon Glass 3 participants 9 messages Apr 18, 2015 – Apr 21, 2015

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

cover 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(-)
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#1 lore raw

PATCH 1/5 dm: sunxi: gpio: Add temporary implementation of name_to_gpio()

Until sunxi moves to device tree (e.g. for USB) we need to convert named GPIOs to numbers. Add a function to do this.

---

 drivers/gpio/sunxi_gpio.c | 11 +++++++++++
 1 file changed, 11 insertions(+)
drivers/gpio/sunxi_gpio.c +11 -0
index cf5c624..e459895 100644
@@ -172,6 +172,17 @@ int sunxi_name_to_gpio(const char *name)
 #endif
 
 #ifdef CONFIG_DM_GPIO
+/* TODO(sjg at 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);
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#2 lore raw

PATCH 2/5 dm: sunxi: gpio: Rename GPIOs to include a 'P' prefix

In reply to Simon Glass

By convention, sunxi GPIOs are named PA1, PA2 instead of A1, A2. Change the driver model GPIO driver for sunxi to use these names.

---

 drivers/gpio/sunxi_gpio.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/gpio/sunxi_gpio.c +4 -3
index e459895..89209df 100644
@@ -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;
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#3 lore raw

PATCH 3/5 dm: gpio: Remove default declaration of name_to_gpio()

In reply to Simon Glass

With driver model we should not use this function. Drivers should use device tree to find their GPIOs.

---

 common/cmd_gpio.c | 7 +++++++
 1 file changed, 7 insertions(+)
common/cmd_gpio.c +7 -0
index 65d6df4..9dae011 100644
@@ -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,
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#4 lore raw

PATCH 4/5 dm: usb: Add more debugging in ehci-hcd.c

In reply to Simon Glass

Add some debugging to detect init failure.

---

 drivers/usb/host/ehci-hcd.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/usb/host/ehci-hcd.c +12 -4
index bd9861d..066e7c5 100644
@@ -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:
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#6 lore raw

PATCH 5/5 WIP: sunxi: Start of driver model USB implementation

In reply to Simon Glass

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?

---

 drivers/usb/host/ehci-sunxi.c | 71 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 71 insertions(+)
drivers/usb/host/ehci-sunxi.c +71 -0
index eda9f69..5b92edf 100644
@@ -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
Signature · 1 line
2.2.0.rc0.207.ga3a616c
#7 lore raw

cover dm: usb: Start of sunxi support

In reply to Simon Glass

Hi Simon,

Quoted 10 lines · Simon Glass

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

#8 lore raw

cover dm: usb: Start of sunxi support

Hi Hans,

Quoted 16 lines · Hans de Goede

Hi Simon,

Quoted 11 lines · Simon Glass

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

Quoted 5 lines

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