public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 00/17] sunxi: musb otg controller support
@ 2015-01-11 19:34 Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls Hans de Goede
                   ` (17 more replies)
  0 siblings, 18 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Hi Marek, Ian, et al,

I'm very happy to present this patch series, which is the last pieze of
the puzzle to make it possible for people to use u-boot on sunxi devices
without needing to resort to putting a soldering iron to their tablet :)

With this series sunxi tablet owners can simply plug in a usb keyboard into
the otg port of their tablet (how boring).

Interestingly enough getting the musb code to work on sunxi was quite east,
most of my time went into fixing generic usb / musb issues, which should help
on other boards too :)

This entire series is based on u-boot-sunxi/next and for some of the sunxi
specific patches there will likely be conflicts when applied directly to
master, therefor I would like to suggest the following scheme for getting this
upstream:

1) Add patches 1-5 to u-boot-sunxi/next (once reviewed)
2) Add patches 6-16 to u-boot-usb/next (once reviewed)
3) Get both trees pulled by Tom
4) Add patch 17 to u-boot-sunxi

As for reviewing, Marek can you review patches 3-16 please (so all those
intended for u-boot-usb/next + patch 3-5), and Ian can you review patches 1-5
and 17 please ?

Thanks & Regards,

Hans

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 18:49   ` Ian Campbell
  2015-01-11 19:34 ` [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin Hans de Goede
                   ` (16 subsequent siblings)
  17 siblings, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

The voltage setting code knows it needs to call axp221_init before calling
the various voltage setting functions.

But users of axp utility functions like axp221_get_sid() do not know this,
so the utility functions always call axp221_init() to ensure that the
p2wi / rsb setup magic has been done.

Since doing this repeatedly is quite expensive, add a check to axp221_init
so that it only does the initialization once.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/power/axp221.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 1fda19a..728727b 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -304,9 +304,14 @@ int axp221_set_aldo3(unsigned int mvolt)
 
 int axp221_init(void)
 {
+	/* This cannot be 0 because it is used in SPL before BSS is ready */
+	static int needs_init = 1;
 	u8 axp_chip_id;
 	int ret;
 
+	if (!needs_init)
+		return 0;
+
 	ret = pmic_bus_init();
 	if (ret)
 		return ret;
@@ -318,6 +323,7 @@ int axp221_init(void)
 	if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
 		return -ENODEV;
 
+	needs_init = 0;
 	return 0;
 }
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 18:52   ` Ian Campbell
  2015-01-11 19:34 ` [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg Hans de Goede
                   ` (15 subsequent siblings)
  17 siblings, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

The axp221 / axp223's N_VBUSEN pin can be configured as an output rather
then an input, add axp_drivebus_enable() and _disable() functions to set
the pin in output mode and control it.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/power/axp221.c | 36 ++++++++++++++++++++++++++++++++++++
 include/axp221.h       |  9 +++++++++
 2 files changed, 45 insertions(+)

diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
index 728727b..4c86f09 100644
--- a/drivers/power/axp221.c
+++ b/drivers/power/axp221.c
@@ -353,3 +353,39 @@ int axp221_get_sid(unsigned int *sid)
 
 	return 0;
 }
+
+static int axp_drivebus_setup(void)
+{
+	int ret;
+
+	ret = axp221_init();
+	if (ret)
+		return ret;
+
+	/* Set N_VBUSEN pin to output / DRIVEBUS function */
+	return axp221_clrbits(AXP221_MISC_CTRL, AXP221_MISC_CTRL_N_VBUSEN_FUNC);
+}
+
+int axp_drivebus_enable(void)
+{
+	int ret;
+
+	ret = axp_drivebus_setup();
+	if (ret)
+		return ret;
+
+	/* Set DRIVEBUS high */
+	return axp221_setbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS);
+}
+
+int axp_drivebus_disable(void)
+{
+	int ret;
+
+	ret = axp_drivebus_setup();
+	if (ret)
+		return ret;
+
+	/* Set DRIVEBUS low */
+	return axp221_clrbits(AXP221_VBUS_IPSOUT, AXP221_VBUS_IPSOUT_DRIVEBUS);
+}
diff --git a/include/axp221.h b/include/axp221.h
index e9552f6..e6639f1 100644
--- a/include/axp221.h
+++ b/include/axp221.h
@@ -45,11 +45,18 @@
 #define AXP221_ALDO1_CTRL	0x28
 #define AXP221_ALDO2_CTRL	0x29
 #define AXP221_ALDO3_CTRL	0x2a
+#define AXP221_VBUS_IPSOUT	0x30
+#define AXP221_VBUS_IPSOUT_DRIVEBUS	(1 << 2)
+#define AXP221_MISC_CTRL	0x8f
+#define AXP221_MISC_CTRL_N_VBUSEN_FUNC	(1 << 4)
 #define AXP221_PAGE		0xff
 
 /* Page 1 addresses */
 #define AXP221_SID		0x20
 
+/* We support drivebus control */
+#define AXP_DRIVEBUS
+
 int axp221_set_dcdc1(unsigned int mvolt);
 int axp221_set_dcdc2(unsigned int mvolt);
 int axp221_set_dcdc3(unsigned int mvolt);
@@ -64,3 +71,5 @@ int axp221_set_aldo2(unsigned int mvolt);
 int axp221_set_aldo3(unsigned int mvolt);
 int axp221_init(void);
 int axp221_get_sid(unsigned int *sid);
+int axp_drivebus_enable(void);
+int axp_drivebus_disable(void);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 18:55   ` Ian Campbell
  2015-01-11 19:34 ` [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code Hans de Goede
                   ` (14 subsequent siblings)
  17 siblings, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Most of the usb-controller init code found in ehci-sunxi.c also is necessary
to init the otg usb controller, so move it to a common place.

While at it also update various #ifdefs / defines for sun8i support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/cpu/armv7/sunxi/Makefile             |   1 +
 arch/arm/cpu/armv7/sunxi/usbc.c               | 229 ++++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |   2 +-
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h |   1 +
 arch/arm/include/asm/arch-sunxi/cpu.h         |   4 +-
 arch/arm/include/asm/arch-sunxi/usbc.h        |  20 +++
 drivers/usb/host/ehci-sunxi.c                 | 213 ++----------------------
 include/configs/sun8i.h                       |   5 +
 8 files changed, 269 insertions(+), 206 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/sunxi/usbc.c
 create mode 100644 arch/arm/include/asm/arch-sunxi/usbc.h

diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index 1e89937..1720f7d 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -12,6 +12,7 @@ obj-y	+= board.o
 obj-y	+= clock.o
 obj-y	+= cpu_info.o
 obj-y	+= pinmux.o
+obj-y	+= usbc.o
 obj-$(CONFIG_MACH_SUN6I)	+= prcm.o
 obj-$(CONFIG_MACH_SUN8I)	+= prcm.o
 obj-$(CONFIG_MACH_SUN6I)	+= p2wi.o
diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c
new file mode 100644
index 0000000..621992c
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/usbc.c
@@ -0,0 +1,229 @@
+/*
+ * Sunxi usb-controller code shared between the ehci and musb controllers
+ *
+ * Copyright (C) 2014 Roman Byshko
+ *
+ * Roman Byshko <rbyshko@gmail.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <asm/arch/clock.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/usbc.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <common.h>
+
+#define SUNXI_USB_PMU_IRQ_ENABLE	0x800
+#define SUNXI_USB_CSR			0x404
+#define SUNXI_USB_PASSBY_EN		1
+
+#define SUNXI_EHCI_AHB_ICHR8_EN		(1 << 10)
+#define SUNXI_EHCI_AHB_INCR4_BURST_EN	(1 << 9)
+#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN	(1 << 8)
+#define SUNXI_EHCI_ULPI_BYPASS_EN	(1 << 0)
+
+static struct sunxi_usbc_hcd {
+	struct usb_hcd *hcd;
+	int usb_rst_mask;
+	int ahb_clk_mask;
+	int gpio_vbus;
+	int irq;
+	int id;
+} sunxi_usbc_hcd[] = {
+	{
+		.usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK,
+		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+		.irq = 72,
+#else
+		.irq = 39,
+#endif
+		.id = 1,
+	},
+#if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1)
+	{
+		.usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK,
+		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1,
+#ifdef CONFIG_MACH_SUN6I
+		.irq = 74,
+#else
+		.irq = 40,
+#endif
+		.id = 2,
+	}
+#endif
+};
+
+static int enabled_hcd_count;
+
+void *sunxi_usbc_get_io_base(int index)
+{
+	switch (index) {
+	case 0:
+		return (void *)SUNXI_USB0_BASE;
+	case 1:
+		return (void *)SUNXI_USB1_BASE;
+	case 2:
+		return (void *)SUNXI_USB2_BASE;
+	default:
+		return NULL;
+	}
+}
+
+static int get_vbus_gpio(int index)
+{
+	switch (index) {
+	case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN);
+	case 2: return sunxi_name_to_gpio(CONFIG_USB2_VBUS_PIN);
+	}
+	return -1;
+}
+
+static void usb_phy_write(struct sunxi_usbc_hcd *sunxi_usbc, int addr,
+			  int data, int len)
+{
+	int j = 0, usbc_bit = 0;
+	void *dest = sunxi_usbc_get_io_base(0) + SUNXI_USB_CSR;
+
+	usbc_bit = 1 << (sunxi_usbc->id * 2);
+	for (j = 0; j < len; j++) {
+		/* set the bit address to be written */
+		clrbits_le32(dest, 0xff << 8);
+		setbits_le32(dest, (addr + j) << 8);
+
+		clrbits_le32(dest, usbc_bit);
+		/* set data bit */
+		if (data & 0x1)
+			setbits_le32(dest, 1 << 7);
+		else
+			clrbits_le32(dest, 1 << 7);
+
+		setbits_le32(dest, usbc_bit);
+
+		clrbits_le32(dest, usbc_bit);
+
+		data >>= 1;
+	}
+}
+
+static void sunxi_usb_phy_init(struct sunxi_usbc_hcd *sunxi_usbc)
+{
+	/* The following comments are machine
+	 * translated from Chinese, you have been warned!
+	 */
+
+	/* adjust PHY's magnitude and rate */
+	usb_phy_write(sunxi_usbc, 0x20, 0x14, 5);
+
+	/* threshold adjustment disconnect */
+#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN6I
+	usb_phy_write(sunxi_usbc, 0x2a, 3, 2);
+#else
+	usb_phy_write(sunxi_usbc, 0x2a, 2, 2);
+#endif
+
+	return;
+}
+
+static void sunxi_usb_passby(struct sunxi_usbc_hcd *sunxi_usbc, int enable)
+{
+	unsigned long bits = 0;
+	void *addr = sunxi_usbc_get_io_base(sunxi_usbc->id) +
+		     SUNXI_USB_PMU_IRQ_ENABLE;
+
+	bits = SUNXI_EHCI_AHB_ICHR8_EN |
+		SUNXI_EHCI_AHB_INCR4_BURST_EN |
+		SUNXI_EHCI_AHB_INCRX_ALIGN_EN |
+		SUNXI_EHCI_ULPI_BYPASS_EN;
+
+	if (enable)
+		setbits_le32(addr, bits);
+	else
+		clrbits_le32(addr, bits);
+
+	return;
+}
+
+int sunxi_usbc_request_resources(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+
+	sunxi_usbc->gpio_vbus = get_vbus_gpio(index);
+	if (sunxi_usbc->gpio_vbus != -1)
+		return gpio_request(sunxi_usbc->gpio_vbus, "usbc_vbus");
+
+	return 0;
+}
+
+int sunxi_usbc_free_resources(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+
+	if (sunxi_usbc->gpio_vbus != -1)
+		return gpio_free(sunxi_usbc->gpio_vbus);
+
+	return 0;
+}
+
+void sunxi_usbc_enable(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* enable common PHY only once */
+	if (enabled_hcd_count == 0)
+		setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
+
+	setbits_le32(&ccm->usb_clk_cfg, sunxi_usbc->usb_rst_mask);
+	setbits_le32(&ccm->ahb_gate0, sunxi_usbc->ahb_clk_mask);
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+	setbits_le32(&ccm->ahb_reset0_cfg, sunxi_usbc->ahb_clk_mask);
+#endif
+
+	sunxi_usb_phy_init(sunxi_usbc);
+
+	sunxi_usb_passby(sunxi_usbc, SUNXI_USB_PASSBY_EN);
+
+	enabled_hcd_count++;
+}
+
+void sunxi_usbc_disable(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	sunxi_usb_passby(sunxi_usbc, !SUNXI_USB_PASSBY_EN);
+
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+	clrbits_le32(&ccm->ahb_reset0_cfg, sunxi_usbc->ahb_clk_mask);
+#endif
+	clrbits_le32(&ccm->ahb_gate0, sunxi_usbc->ahb_clk_mask);
+	clrbits_le32(&ccm->usb_clk_cfg, sunxi_usbc->usb_rst_mask);
+
+	/* disable common PHY only once, for the last enabled hcd */
+	if (enabled_hcd_count == 1)
+		clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
+
+	enabled_hcd_count--;
+}
+
+void sunxi_usbc_vbus_enable(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+
+	if (sunxi_usbc->gpio_vbus != -1)
+		gpio_direction_output(sunxi_usbc->gpio_vbus, 1);
+}
+
+void sunxi_usbc_vbus_disable(int index)
+{
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+
+	if (sunxi_usbc->gpio_vbus != -1)
+		gpio_direction_output(sunxi_usbc->gpio_vbus, 0);
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index 70b789e..a6d129c 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -182,7 +182,7 @@ struct sunxi_ccm_reg {
 #define AHB_GATE_OFFSET_USB_EHCI1	3
 #define AHB_GATE_OFFSET_USB_OHCI0	2
 #define AHB_GATE_OFFSET_USB_EHCI0	1
-#define AHB_GATE_OFFSET_USB		0
+#define AHB_GATE_OFFSET_USB0		0
 
 /* ahb clock gate bit offset (second register) */
 #define AHB_GATE_OFFSET_GMAC		17
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index 653f63c..f85f94d 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -204,6 +204,7 @@ struct sunxi_ccm_reg {
 #define AHB_GATE_OFFSET_USB_OHCI0	29
 #define AHB_GATE_OFFSET_USB_EHCI1	27
 #define AHB_GATE_OFFSET_USB_EHCI0	26
+#define AHB_GATE_OFFSET_USB0		24
 #define AHB_GATE_OFFSET_MCTL		14
 #define AHB_GATE_OFFSET_GMAC		17
 #define AHB_GATE_OFFSET_MMC3		11
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
index bcfa00d..82b3d46 100644
--- a/arch/arm/include/asm/arch-sunxi/cpu.h
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -37,7 +37,7 @@
 #define SUNXI_MMC1_BASE			0x01c10000
 #define SUNXI_MMC2_BASE			0x01c11000
 #define SUNXI_MMC3_BASE			0x01c12000
-#ifndef CONFIG_MACH_SUN6I
+#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
 #define SUNXI_USB0_BASE			0x01c13000
 #define SUNXI_USB1_BASE			0x01c14000
 #endif
@@ -45,7 +45,7 @@
 #define SUNXI_HDMI_BASE			0x01c16000
 #define SUNXI_SPI2_BASE			0x01c17000
 #define SUNXI_SATA_BASE			0x01c18000
-#ifndef CONFIG_MACH_SUN6I
+#if !defined CONFIG_MACH_SUN6I && !defined CONFIG_MACH_SUN8I
 #define SUNXI_PATA_BASE			0x01c19000
 #define SUNXI_ACE_BASE			0x01c1a000
 #define SUNXI_TVE1_BASE			0x01c1b000
diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h
new file mode 100644
index 0000000..8d20973
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/usbc.h
@@ -0,0 +1,20 @@
+/*
+ * Sunxi usb-controller code shared between the ehci and musb controllers
+ *
+ * Copyright (C) 2014 Roman Byshko
+ *
+ * Roman Byshko <rbyshko@gmail.com>
+ *
+ * Based on code from
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+void *sunxi_usbc_get_io_base(int index);
+int sunxi_usbc_request_resources(int index);
+int sunxi_usbc_free_resources(int index);
+void sunxi_usbc_enable(int index);
+void sunxi_usbc_disable(int index);
+void sunxi_usbc_vbus_enable(int index);
+void sunxi_usbc_vbus_disable(int index);
diff --git a/drivers/usb/host/ehci-sunxi.c b/drivers/usb/host/ehci-sunxi.c
index cc9a8fa..eda9f69 100644
--- a/drivers/usb/host/ehci-sunxi.c
+++ b/drivers/usb/host/ehci-sunxi.c
@@ -9,199 +9,23 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
-#include <asm/arch/clock.h>
-#include <asm/arch/cpu.h>
-#include <asm/gpio.h>
-#include <asm/io.h>
+#include <asm/arch/usbc.h>
 #include <common.h>
 #include "ehci.h"
 
-#define SUNXI_USB_PMU_IRQ_ENABLE	0x800
-#define SUNXI_USB_CSR			0x404
-#define SUNXI_USB_PASSBY_EN		1
-
-#define SUNXI_EHCI_AHB_ICHR8_EN		(1 << 10)
-#define SUNXI_EHCI_AHB_INCR4_BURST_EN	(1 << 9)
-#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN	(1 << 8)
-#define SUNXI_EHCI_ULPI_BYPASS_EN	(1 << 0)
-
-static struct sunxi_ehci_hcd {
-	struct usb_hcd *hcd;
-	int usb_rst_mask;
-	int ahb_clk_mask;
-	int gpio_vbus;
-	int irq;
-	int id;
-} sunxi_echi_hcd[] = {
-	{
-		.usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK,
-		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
-#ifndef CONFIG_MACH_SUN6I
-		.irq = 39,
-#else
-		.irq = 72,
-#endif
-		.id = 1,
-	},
-#if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1)
-	{
-		.usb_rst_mask = CCM_USB_CTRL_PHY2_RST | CCM_USB_CTRL_PHY2_CLK,
-		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1,
-#ifndef CONFIG_MACH_SUN6I
-		.irq = 40,
-#else
-		.irq = 74,
-#endif
-		.id = 2,
-	}
-#endif
-};
-
-static int enabled_hcd_count;
-
-static void *get_io_base(int hcd_id)
-{
-	switch (hcd_id) {
-	case 0:
-		return (void *)SUNXI_USB0_BASE;
-	case 1:
-		return (void *)SUNXI_USB1_BASE;
-	case 2:
-		return (void *)SUNXI_USB2_BASE;
-	default:
-		return NULL;
-	}
-}
-
-static int get_vbus_gpio(int hcd_id)
-{
-	switch (hcd_id) {
-	case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN);
-	case 2: return sunxi_name_to_gpio(CONFIG_USB2_VBUS_PIN);
-	}
-	return -1;
-}
-
-static void usb_phy_write(struct sunxi_ehci_hcd *sunxi_ehci, int addr,
-			  int data, int len)
-{
-	int j = 0, usbc_bit = 0;
-	void *dest = get_io_base(0) + SUNXI_USB_CSR;
-
-	usbc_bit = 1 << (sunxi_ehci->id * 2);
-	for (j = 0; j < len; j++) {
-		/* set the bit address to be written */
-		clrbits_le32(dest, 0xff << 8);
-		setbits_le32(dest, (addr + j) << 8);
-
-		clrbits_le32(dest, usbc_bit);
-		/* set data bit */
-		if (data & 0x1)
-			setbits_le32(dest, 1 << 7);
-		else
-			clrbits_le32(dest, 1 << 7);
-
-		setbits_le32(dest, usbc_bit);
-
-		clrbits_le32(dest, usbc_bit);
-
-		data >>= 1;
-	}
-}
-
-static void sunxi_usb_phy_init(struct sunxi_ehci_hcd *sunxi_ehci)
-{
-	/* The following comments are machine
-	 * translated from Chinese, you have been warned!
-	 */
-
-	/* adjust PHY's magnitude and rate */
-	usb_phy_write(sunxi_ehci, 0x20, 0x14, 5);
-
-	/* threshold adjustment disconnect */
-#if defined CONFIG_MACH_SUN4I || defined CONFIG_MACH_SUN6I
-	usb_phy_write(sunxi_ehci, 0x2a, 3, 2);
-#else
-	usb_phy_write(sunxi_ehci, 0x2a, 2, 2);
-#endif
-
-	return;
-}
-
-static void sunxi_usb_passby(struct sunxi_ehci_hcd *sunxi_ehci, int enable)
-{
-	unsigned long bits = 0;
-	void *addr = get_io_base(sunxi_ehci->id) + SUNXI_USB_PMU_IRQ_ENABLE;
-
-	bits = SUNXI_EHCI_AHB_ICHR8_EN |
-		SUNXI_EHCI_AHB_INCR4_BURST_EN |
-		SUNXI_EHCI_AHB_INCRX_ALIGN_EN |
-		SUNXI_EHCI_ULPI_BYPASS_EN;
-
-	if (enable)
-		setbits_le32(addr, bits);
-	else
-		clrbits_le32(addr, bits);
-
-	return;
-}
-
-static void sunxi_ehci_enable(struct sunxi_ehci_hcd *sunxi_ehci)
-{
-	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
-	setbits_le32(&ccm->usb_clk_cfg, sunxi_ehci->usb_rst_mask);
-	setbits_le32(&ccm->ahb_gate0, sunxi_ehci->ahb_clk_mask);
-#ifdef CONFIG_MACH_SUN6I
-	setbits_le32(&ccm->ahb_reset0_cfg, sunxi_ehci->ahb_clk_mask);
-#endif
-
-	sunxi_usb_phy_init(sunxi_ehci);
-
-	sunxi_usb_passby(sunxi_ehci, SUNXI_USB_PASSBY_EN);
-
-	if (sunxi_ehci->gpio_vbus != -1)
-		gpio_direction_output(sunxi_ehci->gpio_vbus, 1);
-}
-
-static void sunxi_ehci_disable(struct sunxi_ehci_hcd *sunxi_ehci)
-{
-	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-
-	if (sunxi_ehci->gpio_vbus != -1)
-		gpio_direction_output(sunxi_ehci->gpio_vbus, 0);
-
-	sunxi_usb_passby(sunxi_ehci, !SUNXI_USB_PASSBY_EN);
-
-#ifdef CONFIG_MACH_SUN6I
-	clrbits_le32(&ccm->ahb_reset0_cfg, sunxi_ehci->ahb_clk_mask);
-#endif
-	clrbits_le32(&ccm->ahb_gate0, sunxi_ehci->ahb_clk_mask);
-	clrbits_le32(&ccm->usb_clk_cfg, sunxi_ehci->usb_rst_mask);
-}
-
 int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
 		struct ehci_hcor **hcor)
 {
-	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
 	int err;
 
-	sunxi_ehci->gpio_vbus = get_vbus_gpio(sunxi_ehci->id);
+	err = sunxi_usbc_request_resources(index + 1);
+	if (err)
+		return err;
 
-	/* enable common PHY only once */
-	if (index == 0)
-		setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
+	sunxi_usbc_enable(index + 1);
+	sunxi_usbc_vbus_enable(index + 1);
 
-	if (sunxi_ehci->gpio_vbus != -1) {
-		err = gpio_request(sunxi_ehci->gpio_vbus, "ehci_vbus");
-		if (err)
-			return err;
-	}
-
-	sunxi_ehci_enable(sunxi_ehci);
-
-	*hccr = get_io_base(sunxi_ehci->id);
+	*hccr = sunxi_usbc_get_io_base(index + 1);
 
 	*hcor = (struct ehci_hcor *)((uint32_t) *hccr
 				+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
@@ -210,30 +34,13 @@ int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
 	      (uint32_t)*hccr, (uint32_t)*hcor,
 	      (uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
 
-	enabled_hcd_count++;
-
 	return 0;
 }
 
 int ehci_hcd_stop(int index)
 {
-	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
-	struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
-	int err;
-
-	sunxi_ehci_disable(sunxi_ehci);
-
-	if (sunxi_ehci->gpio_vbus != -1) {
-		err = gpio_free(sunxi_ehci->gpio_vbus);
-		if (err)
-			return err;
-	}
+	sunxi_usbc_vbus_disable(index + 1);
+	sunxi_usbc_disable(index + 1);
 
-	/* disable common PHY only once, for the last enabled hcd */
-	if (enabled_hcd_count == 1)
-		clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
-
-	enabled_hcd_count--;
-
-	return 0;
+	return sunxi_usbc_free_resources(index + 1);
 }
diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h
index 792422d..f16e60b 100644
--- a/include/configs/sun8i.h
+++ b/include/configs/sun8i.h
@@ -16,6 +16,11 @@
 
 #define CONFIG_SYS_PROMPT	"sun8i# "
 
+#ifdef CONFIG_USB_EHCI
+#define CONFIG_USB_EHCI_SUNXI
+#define CONFIG_USB_MAX_CONTROLLER_COUNT	1
+#endif
+
 /*
  * Include common sunxi configuration where most the settings are
  */
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (2 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 18:57   ` Ian Campbell
  2015-01-11 19:34 ` [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin Hans de Goede
                   ` (13 subsequent siblings)
  17 siblings, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/cpu/armv7/sunxi/usbc.c               | 33 ++++++++++++++++++++-------
 arch/arm/include/asm/arch-sunxi/clock_sun4i.h |  4 +++-
 arch/arm/include/asm/arch-sunxi/clock_sun6i.h |  2 ++
 board/sunxi/Kconfig                           |  7 ++++++
 4 files changed, 37 insertions(+), 9 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c
index 621992c..4f11da5 100644
--- a/arch/arm/cpu/armv7/sunxi/usbc.c
+++ b/arch/arm/cpu/armv7/sunxi/usbc.c
@@ -36,6 +36,16 @@ static struct sunxi_usbc_hcd {
 	int id;
 } sunxi_usbc_hcd[] = {
 	{
+		.usb_rst_mask = CCM_USB_CTRL_PHY0_RST | CCM_USB_CTRL_PHY0_CLK,
+		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB0,
+#if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
+		.irq = 71,
+#else
+		.irq = 38,
+#endif
+		.id = 0,
+	},
+	{
 		.usb_rst_mask = CCM_USB_CTRL_PHY1_RST | CCM_USB_CTRL_PHY1_CLK,
 		.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
 #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
@@ -78,6 +88,7 @@ void *sunxi_usbc_get_io_base(int index)
 static int get_vbus_gpio(int index)
 {
 	switch (index) {
+	case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_PIN);
 	case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN);
 	case 2: return sunxi_name_to_gpio(CONFIG_USB2_VBUS_PIN);
 	}
@@ -117,6 +128,10 @@ static void sunxi_usb_phy_init(struct sunxi_usbc_hcd *sunxi_usbc)
 	 * translated from Chinese, you have been warned!
 	 */
 
+	/* Regulation 45 ohms */
+	if (sunxi_usbc->id == 0)
+		usb_phy_write(sunxi_usbc, 0x0c, 0x01, 1);
+
 	/* adjust PHY's magnitude and rate */
 	usb_phy_write(sunxi_usbc, 0x20, 0x14, 5);
 
@@ -151,7 +166,7 @@ static void sunxi_usb_passby(struct sunxi_usbc_hcd *sunxi_usbc, int enable)
 
 int sunxi_usbc_request_resources(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
 	sunxi_usbc->gpio_vbus = get_vbus_gpio(index);
 	if (sunxi_usbc->gpio_vbus != -1)
@@ -162,7 +177,7 @@ int sunxi_usbc_request_resources(int index)
 
 int sunxi_usbc_free_resources(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
 	if (sunxi_usbc->gpio_vbus != -1)
 		return gpio_free(sunxi_usbc->gpio_vbus);
@@ -172,7 +187,7 @@ int sunxi_usbc_free_resources(int index)
 
 void sunxi_usbc_enable(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
 	/* enable common PHY only once */
@@ -187,17 +202,19 @@ void sunxi_usbc_enable(int index)
 
 	sunxi_usb_phy_init(sunxi_usbc);
 
-	sunxi_usb_passby(sunxi_usbc, SUNXI_USB_PASSBY_EN);
+	if (sunxi_usbc->id != 0)
+		sunxi_usb_passby(sunxi_usbc, SUNXI_USB_PASSBY_EN);
 
 	enabled_hcd_count++;
 }
 
 void sunxi_usbc_disable(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
-	sunxi_usb_passby(sunxi_usbc, !SUNXI_USB_PASSBY_EN);
+	if (sunxi_usbc->id != 0)
+		sunxi_usb_passby(sunxi_usbc, !SUNXI_USB_PASSBY_EN);
 
 #if defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I
 	clrbits_le32(&ccm->ahb_reset0_cfg, sunxi_usbc->ahb_clk_mask);
@@ -214,7 +231,7 @@ void sunxi_usbc_disable(int index)
 
 void sunxi_usbc_vbus_enable(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
 	if (sunxi_usbc->gpio_vbus != -1)
 		gpio_direction_output(sunxi_usbc->gpio_vbus, 1);
@@ -222,7 +239,7 @@ void sunxi_usbc_vbus_enable(int index)
 
 void sunxi_usbc_vbus_disable(int index)
 {
-	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index - 1];
+	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
 	if (sunxi_usbc->gpio_vbus != -1)
 		gpio_direction_output(sunxi_usbc->gpio_vbus, 0);
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
index a6d129c..84a9a2b 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun4i.h
@@ -302,10 +302,12 @@ struct sunxi_ccm_reg {
 #define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2)
 #define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2)
 
+#define CCM_USB_CTRL_PHY0_RST (0x1 << 0)
 #define CCM_USB_CTRL_PHY1_RST (0x1 << 1)
 #define CCM_USB_CTRL_PHY2_RST (0x1 << 2)
 #define CCM_USB_CTRL_PHYGATE (0x1 << 8)
-/* These 2 are sun6i only, define them as 0 on sun4i */
+/* These 3 are sun6i only, define them as 0 on sun4i */
+#define CCM_USB_CTRL_PHY0_CLK 0
 #define CCM_USB_CTRL_PHY1_CLK 0
 #define CCM_USB_CTRL_PHY2_CLK 0
 
diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
index f85f94d..4711260 100644
--- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
+++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h
@@ -229,10 +229,12 @@ struct sunxi_ccm_reg {
 #define CCM_MMC_CTRL_PLL6		(0x1 << 24)
 #define CCM_MMC_CTRL_ENABLE		(0x1 << 31)
 
+#define CCM_USB_CTRL_PHY0_RST (0x1 << 0)
 #define CCM_USB_CTRL_PHY1_RST (0x1 << 1)
 #define CCM_USB_CTRL_PHY2_RST (0x1 << 2)
 /* There is no global phy clk gate on sun6i, define as 0 */
 #define CCM_USB_CTRL_PHYGATE 0
+#define CCM_USB_CTRL_PHY0_CLK (0x1 << 8)
 #define CCM_USB_CTRL_PHY1_CLK (0x1 << 9)
 #define CCM_USB_CTRL_PHY2_CLK (0x1 << 10)
 
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index ca68065..bece6b7 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -272,6 +272,13 @@ config MMC_SUNXI_SLOT_EXTRA
 	slot or emmc on mmc1 - mmc3. Setting this to 1, 2 or 3 will enable
 	support for this.
 
+config USB0_VBUS_PIN
+	string "Vbus enable pin for usb0 (otg)"
+	default ""
+	---help---
+	Set the Vbus enable pin for usb0 (otg). This takes a string in the
+	format understood by sunxi_name_to_gpio, e.g. PH1 for pin 1 of port H.
+
 config USB1_VBUS_PIN
 	string "Vbus enable pin for usb1 (ehci0)"
 	default "PH6" if MACH_SUN4I || MACH_SUN7I
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (3 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 18:58   ` Ian Campbell
  2015-01-11 19:34 ` [U-Boot] [PATCH 06/17] usb: Fix usb_kbd_deregister when console-muxing is used Hans de Goede
                   ` (12 subsequent siblings)
  17 siblings, 1 reply; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

The axp221 / axp223's N_VBUSEN pin can be configured as an output rather
then an input, and this is used on some boards to control usb-vbus0, add
support for this.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/cpu/armv7/sunxi/usbc.c | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/arch/arm/cpu/armv7/sunxi/usbc.c b/arch/arm/cpu/armv7/sunxi/usbc.c
index 4f11da5..14de9f9 100644
--- a/arch/arm/cpu/armv7/sunxi/usbc.c
+++ b/arch/arm/cpu/armv7/sunxi/usbc.c
@@ -17,6 +17,15 @@
 #include <asm/gpio.h>
 #include <asm/io.h>
 #include <common.h>
+#ifdef CONFIG_AXP152_POWER
+#include <axp152.h>
+#endif
+#ifdef CONFIG_AXP209_POWER
+#include <axp209.h>
+#endif
+#ifdef CONFIG_AXP221_POWER
+#include <axp221.h>
+#endif
 
 #define SUNXI_USB_PMU_IRQ_ENABLE	0x800
 #define SUNXI_USB_CSR			0x404
@@ -71,6 +80,12 @@ static struct sunxi_usbc_hcd {
 
 static int enabled_hcd_count;
 
+static bool use_axp_drivebus(int index)
+{
+	return index == 0 &&
+	       strcmp(CONFIG_USB0_VBUS_PIN, "axp_drivebus") == 0;
+}
+
 void *sunxi_usbc_get_io_base(int index)
 {
 	switch (index) {
@@ -87,6 +102,9 @@ void *sunxi_usbc_get_io_base(int index)
 
 static int get_vbus_gpio(int index)
 {
+	if (use_axp_drivebus(index))
+		return -1;
+
 	switch (index) {
 	case 0: return sunxi_name_to_gpio(CONFIG_USB0_VBUS_PIN);
 	case 1: return sunxi_name_to_gpio(CONFIG_USB1_VBUS_PIN);
@@ -233,6 +251,10 @@ void sunxi_usbc_vbus_enable(int index)
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
+#ifdef AXP_DRIVEBUS
+	if (use_axp_drivebus(index))
+		axp_drivebus_enable();
+#endif
 	if (sunxi_usbc->gpio_vbus != -1)
 		gpio_direction_output(sunxi_usbc->gpio_vbus, 1);
 }
@@ -241,6 +263,10 @@ void sunxi_usbc_vbus_disable(int index)
 {
 	struct sunxi_usbc_hcd *sunxi_usbc = &sunxi_usbc_hcd[index];
 
+#ifdef AXP_DRIVEBUS
+	if (use_axp_drivebus(index))
+		axp_drivebus_disable();
+#endif
 	if (sunxi_usbc->gpio_vbus != -1)
 		gpio_direction_output(sunxi_usbc->gpio_vbus, 0);
 }
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 06/17] usb: Fix usb_kbd_deregister when console-muxing is used
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (4 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 07/17] usb: Add an interval parameter to create_int_queue Hans de Goede
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

When iomuxing is used we must not only deregister the device with stdio.c,
but also remove the reference to the device in the console_devices array
used by console-muxing. Add a call to iomux_doenv to usb_kbd_deregister to
update console_devices, which will drop the reference.

This fixes the console filling with "Failed to enqueue URB to controller"
messages after a "usb stop force", or when the USB keyboard is gone after a
"usb reset".

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 common/usb_kbd.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index bc7145e..732136e 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -542,6 +542,10 @@ int usb_kbd_deregister(int force)
 		data = usb_kbd_dev->privptr;
 		if (stdio_deregister_dev(dev, force) != 0)
 			return 1;
+#ifdef CONFIG_CONSOLE_MUX
+		if (iomux_doenv(stdin, getenv("stdin")) != 0)
+			return 1;
+#endif
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
 		destroy_int_queue(usb_kbd_dev, data->intq);
 #endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 07/17] usb: Add an interval parameter to create_int_queue
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (5 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 06/17] usb: Fix usb_kbd_deregister when console-muxing is used Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 08/17] usb: Do not log an error when no devices is plugged into a root-hub-less hcd Hans de Goede
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Currently create_int_queue is only implemented by the ehci code, and that
does not honor interrupt intervals, but other drivers which might also want
to implement create_int_queue may honor intervals, so add an interval param.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 common/usb_kbd.c            | 6 ++++--
 drivers/usb/host/ehci-hcd.c | 2 +-
 include/usb.h               | 2 +-
 3 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 732136e..ecc3085 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -332,7 +332,8 @@ static inline void usb_kbd_poll_for_event(struct usb_device *dev)
 		/* We've consumed all queued int packets, create new */
 		destroy_int_queue(dev, data->intq);
 		data->intq = create_int_queue(dev, data->intpipe, 1,
-				      USB_KBD_BOOT_REPORT_SIZE, data->new);
+				      USB_KBD_BOOT_REPORT_SIZE, data->new,
+				      data->intinterval);
 	}
 #endif
 }
@@ -453,7 +454,8 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
 	debug("USB KBD: enable interrupt pipe...\n");
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
 	data->intq = create_int_queue(dev, data->intpipe, 1,
-				      USB_KBD_BOOT_REPORT_SIZE, data->new);
+				      USB_KBD_BOOT_REPORT_SIZE, data->new,
+				      data->intinterval);
 	if (!data->intq) {
 #else
 	if (usb_submit_int_msg(dev, data->intpipe, data->new, data->intpktsize,
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index bc76066..e7a4729 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1148,7 +1148,7 @@ disable_periodic(struct ehci_ctrl *ctrl)
 
 struct int_queue *
 create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
-		 int elementsize, void *buffer)
+		 int elementsize, void *buffer, int interval)
 {
 	struct ehci_ctrl *ctrl = dev->controller;
 	struct int_queue *result = NULL;
diff --git a/include/usb.h b/include/usb.h
index d3c7415..3d33b2d 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -169,7 +169,7 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 
 #ifdef CONFIG_USB_EHCI /* Only the ehci code has pollable int support */
 struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
-	int queuesize, int elementsize, void *buffer);
+	int queuesize, int elementsize, void *buffer, int interval);
 int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
 void *poll_int_queue(struct usb_device *dev, struct int_queue *queue);
 #endif
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 08/17] usb: Do not log an error when no devices is plugged into a root-hub-less hcd
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (6 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 07/17] usb: Add an interval parameter to create_int_queue Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 09/17] musb-new: Add register defines for different reg layout on sunxi Hans de Goede
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Before this commit u-boot would print the following on boot with musb and
no usb device plugged in:

starting USB...
USB0:   Port not available.
USB error: all controllers failed lowlevel init

This commit changes this to:

starting USB...
USB0:   Port not available.

Which is the correct thing to do since the low-level init went fine.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 common/usb.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 736cd9f..1eda099 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -59,6 +59,7 @@ int usb_init(void)
 	void *ctrl;
 	struct usb_device *dev;
 	int i, start_index = 0;
+	int controllers_initialized = 0;
 	int ret;
 
 	dev_index = 0;
@@ -78,6 +79,7 @@ int usb_init(void)
 		ret = usb_lowlevel_init(i, USB_INIT_HOST, &ctrl);
 		if (ret == -ENODEV) {	/* No such device. */
 			puts("Port not available.\n");
+			controllers_initialized++;
 			continue;
 		}
 
@@ -89,6 +91,7 @@ int usb_init(void)
 		 * lowlevel init is OK, now scan the bus for devices
 		 * i.e. search HUBs and configure them
 		 */
+		controllers_initialized++;
 		start_index = dev_index;
 		printf("scanning bus %d for devices... ", i);
 		dev = usb_alloc_new_device(ctrl);
@@ -110,12 +113,10 @@ int usb_init(void)
 
 	debug("scan end\n");
 	/* if we were not able to find at least one working bus, bail out */
-	if (!usb_started) {
+	if (controllers_initialized == 0)
 		puts("USB error: all controllers failed lowlevel init\n");
-		return -1;
-	}
 
-	return 0;
+	return usb_started ? 0 : -1;
 }
 
 /******************************************************************************
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 09/17] musb-new: Add register defines for different reg layout on sunxi
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (7 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 08/17] usb: Do not log an error when no devices is plugged into a root-hub-less hcd Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 10/17] musb-new: Add sunxi musb controller support Hans de Goede
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

The sunxi SoCs also have a musb controller, but with a different register
layout.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_regs.h | 92 ++++++++++++++++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)

diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h
index 03f2655..27e4ed4 100644
--- a/drivers/usb/musb-new/musb_regs.h
+++ b/drivers/usb/musb-new/musb_regs.h
@@ -216,6 +216,9 @@
 
 #ifndef CONFIG_BLACKFIN
 
+/* SUNXI has different reg addresses, but identical r/w functions */
+#ifndef CONFIG_ARCH_SUNXI 
+
 /*
  * Common USB registers
  */
@@ -318,6 +321,85 @@
 #define MUSB_BUSCTL_OFFSET(_epnum, _offset) \
 	(0x80 + (8*(_epnum)) + (_offset))
 
+#else /* CONFIG_ARCH_SUNXI */
+
+/*
+ * Common USB registers
+ */
+
+#define MUSB_FADDR		0x0098
+#define MUSB_POWER		0x0040
+
+#define MUSB_INTRTX		0x0044
+#define MUSB_INTRRX		0x0046
+#define MUSB_INTRTXE		0x0048
+#define MUSB_INTRRXE		0x004A
+#define MUSB_INTRUSB		0x004C
+#define MUSB_INTRUSBE		0x0050
+#define MUSB_FRAME		0x0054
+#define MUSB_INDEX		0x0042
+#define MUSB_TESTMODE		0x007C
+
+/* Get offset for a given FIFO from musb->mregs */
+#define MUSB_FIFO_OFFSET(epnum)	(0x00 + ((epnum) * 4))
+
+/*
+ * Additional Control Registers
+ */
+
+#define MUSB_DEVCTL		0x0041
+
+/* These are always controlled through the INDEX register */
+#define MUSB_TXFIFOSZ		0x0090
+#define MUSB_RXFIFOSZ		0x0094
+#define MUSB_TXFIFOADD		0x0092
+#define MUSB_RXFIFOADD		0x0096
+
+#define MUSB_EPINFO		0x0078
+#define MUSB_RAMINFO		0x0079
+#define MUSB_LINKINFO		0x007A
+#define MUSB_VPLEN		0x007B
+#define MUSB_HS_EOF1		0x007C
+#define MUSB_FS_EOF1		0x007D
+#define MUSB_LS_EOF1		0x007E
+
+/* Offsets to endpoint registers */
+#define MUSB_TXMAXP		0x0080
+#define MUSB_TXCSR		0x0082
+#define MUSB_CSR0		0x0082
+#define MUSB_RXMAXP		0x0084
+#define MUSB_RXCSR		0x0086
+#define MUSB_RXCOUNT		0x0088
+#define MUSB_COUNT0		0x0088
+#define MUSB_TXTYPE		0x008C
+#define MUSB_TYPE0		0x008C
+#define MUSB_TXINTERVAL		0x008D
+#define MUSB_NAKLIMIT0		0x008D
+#define MUSB_RXTYPE		0x008E
+#define MUSB_RXINTERVAL		0x008F
+
+#define MUSB_CONFIGDATA		0x00b0 /* musb_read_configdata adds 0x10 ! */
+#define MUSB_FIFOSIZE		0x0090
+
+/* Offsets to endpoint registers in indexed model (using INDEX register) */
+#define MUSB_INDEXED_OFFSET(_epnum, _offset) (_offset)
+
+#define MUSB_TXCSR_MODE		0x2000
+
+/* "bus control"/target registers, for host side multipoint (external hubs) */
+#define MUSB_TXFUNCADDR		0x0098
+#define MUSB_TXHUBADDR		0x009A
+#define MUSB_TXHUBPORT		0x009B
+
+#define MUSB_RXFUNCADDR		0x009C
+#define MUSB_RXHUBADDR		0x009E
+#define MUSB_RXHUBPORT		0x009F
+
+/* Endpoint is selected with MUSB_INDEX. */
+#define MUSB_BUSCTL_OFFSET(_epnum, _offset) (_offset)
+
+#endif /* CONFIG_ARCH_SUNXI */
+
 static inline void musb_write_txfifosz(void __iomem *mbase, u8 c_size)
 {
 	musb_writeb(mbase, MUSB_TXFIFOSZ, c_size);
@@ -340,7 +422,9 @@ static inline void  musb_write_rxfifoadd(void __iomem *mbase, u16 c_off)
 
 static inline void musb_write_ulpi_buscontrol(void __iomem *mbase, u8 val)
 {
+#ifndef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */
 	musb_writeb(mbase, MUSB_ULPI_BUSCONTROL, val);
+#endif
 }
 
 static inline u8 musb_read_txfifosz(void __iomem *mbase)
@@ -365,7 +449,11 @@ static inline u16  musb_read_rxfifoadd(void __iomem *mbase)
 
 static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase)
 {
+#ifdef CONFIG_ARCH_SUNXI /* No ulpi on sunxi */
+	return 0;
+#else
 	return musb_readb(mbase, MUSB_ULPI_BUSCONTROL);
+#endif
 }
 
 static inline u8 musb_read_configdata(void __iomem *mbase)
@@ -376,7 +464,11 @@ static inline u8 musb_read_configdata(void __iomem *mbase)
 
 static inline u16 musb_read_hwvers(void __iomem *mbase)
 {
+#ifdef CONFIG_ARCH_SUNXI
+	return 0; /* Unknown version */
+#else
 	return musb_readw(mbase, MUSB_HWVERS);
+#endif
 }
 
 static inline void __iomem *musb_read_target_reg_base(u8 i, void __iomem *mbase)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 10/17] musb-new: Add sunxi musb controller support
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (8 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 09/17] musb-new: Add register defines for different reg layout on sunxi Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 11/17] musb-new: Use time based timeouts rather then cpu-cycles based timeouts Hans de Goede
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

This is based on Jussi Kivilinna's work for the linux-sunxi-3.4 kernel to use
the kernels musb driver instead of Allwinners own custom driver.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/Makefile |   1 +
 drivers/usb/musb-new/sunxi.c  | 279 ++++++++++++++++++++++++++++++++++++++++++
 include/usb.h                 |   4 +-
 3 files changed, 282 insertions(+), 2 deletions(-)
 create mode 100644 drivers/usb/musb-new/sunxi.c

diff --git a/drivers/usb/musb-new/Makefile b/drivers/usb/musb-new/Makefile
index 3facf0f..9edeece 100644
--- a/drivers/usb/musb-new/Makefile
+++ b/drivers/usb/musb-new/Makefile
@@ -8,6 +8,7 @@ obj-$(CONFIG_MUSB_HOST) += musb_host.o musb_core.o musb_uboot.o
 obj-$(CONFIG_USB_MUSB_DSPS) += musb_dsps.o
 obj-$(CONFIG_USB_MUSB_AM35X) += am35x.o
 obj-$(CONFIG_USB_MUSB_OMAP2PLUS) += omap2430.o
+obj-$(CONFIG_USB_MUSB_SUNXI) += sunxi.o
 
 ccflags-y := $(call cc-option,-Wno-unused-variable) \
 		$(call cc-option,-Wno-unused-but-set-variable) \
diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c
new file mode 100644
index 0000000..778916d
--- /dev/null
+++ b/drivers/usb/musb-new/sunxi.c
@@ -0,0 +1,279 @@
+/*
+ * Allwinner SUNXI "glue layer"
+ *
+ * Copyright ? 2015 Hans de Goede <hdegoede@redhat.com>
+ * Copyright ? 2013 Jussi Kivilinna <jussi.kivilinna@iki.fi>
+ *
+ * Based on the sw_usb "Allwinner OTG Dual Role Controller" code.
+ *  Copyright 2007-2012 (C) Allwinner Technology Co., Ltd.
+ *  javen <javen@allwinnertech.com>
+ *
+ * Based on the DA8xx "glue layer" code.
+ *  Copyright (c) 2008-2009 MontaVista Software, Inc. <source@mvista.com>
+ *  Copyright (C) 2005-2006 by Texas Instruments
+ *
+ * This file is part of the Inventra Controller Driver for Linux.
+ *
+ * The Inventra Controller Driver for Linux is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU
+ * General Public License version 2 as published by the Free Software
+ * Foundation.
+ *
+ */
+#include <common.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/usbc.h>
+#include "linux-compat.h"
+#include "musb_core.h"
+
+/******************************************************************************
+ ******************************************************************************
+ * From the Allwinner driver
+ ******************************************************************************
+ ******************************************************************************/
+
+/******************************************************************************
+ * From include/sunxi_usb_bsp.h
+ ******************************************************************************/
+
+/* reg offsets */
+#define  USBC_REG_o_ISCR	0x0400
+#define  USBC_REG_o_PHYCTL	0x0404
+#define  USBC_REG_o_PHYBIST	0x0408
+#define  USBC_REG_o_PHYTUNE	0x040c
+
+#define  USBC_REG_o_VEND0	0x0043
+
+/* Interface Status and Control */
+#define  USBC_BP_ISCR_VBUS_VALID_FROM_DATA	30
+#define  USBC_BP_ISCR_VBUS_VALID_FROM_VBUS	29
+#define  USBC_BP_ISCR_EXT_ID_STATUS		28
+#define  USBC_BP_ISCR_EXT_DM_STATUS		27
+#define  USBC_BP_ISCR_EXT_DP_STATUS		26
+#define  USBC_BP_ISCR_MERGED_VBUS_STATUS	25
+#define  USBC_BP_ISCR_MERGED_ID_STATUS		24
+
+#define  USBC_BP_ISCR_ID_PULLUP_EN		17
+#define  USBC_BP_ISCR_DPDM_PULLUP_EN		16
+#define  USBC_BP_ISCR_FORCE_ID			14
+#define  USBC_BP_ISCR_FORCE_VBUS_VALID		12
+#define  USBC_BP_ISCR_VBUS_VALID_SRC		10
+
+#define  USBC_BP_ISCR_HOSC_EN			7
+#define  USBC_BP_ISCR_VBUS_CHANGE_DETECT	6
+#define  USBC_BP_ISCR_ID_CHANGE_DETECT		5
+#define  USBC_BP_ISCR_DPDM_CHANGE_DETECT	4
+#define  USBC_BP_ISCR_IRQ_ENABLE		3
+#define  USBC_BP_ISCR_VBUS_CHANGE_DETECT_EN	2
+#define  USBC_BP_ISCR_ID_CHANGE_DETECT_EN	1
+#define  USBC_BP_ISCR_DPDM_CHANGE_DETECT_EN	0
+
+/******************************************************************************
+ * From usbc/usbc.c
+ ******************************************************************************/
+
+static u32 USBC_WakeUp_ClearChangeDetect(u32 reg_val)
+{
+	u32 temp = reg_val;
+
+	temp &= ~(1 << USBC_BP_ISCR_VBUS_CHANGE_DETECT);
+	temp &= ~(1 << USBC_BP_ISCR_ID_CHANGE_DETECT);
+	temp &= ~(1 << USBC_BP_ISCR_DPDM_CHANGE_DETECT);
+
+	return temp;
+}
+
+static void USBC_EnableIdPullUp(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val |= (1 << USBC_BP_ISCR_ID_PULLUP_EN);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_DisableIdPullUp(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(1 << USBC_BP_ISCR_ID_PULLUP_EN);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_EnableDpDmPullUp(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val |= (1 << USBC_BP_ISCR_DPDM_PULLUP_EN);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_DisableDpDmPullUp(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(1 << USBC_BP_ISCR_DPDM_PULLUP_EN);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceIdToLow(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID);
+	reg_val |= (0x02 << USBC_BP_ISCR_FORCE_ID);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceIdToHigh(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_ID);
+	reg_val |= (0x03 << USBC_BP_ISCR_FORCE_ID);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceVbusValidDisable(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ForceVbusValidToHigh(__iomem void *base)
+{
+	u32 reg_val;
+
+	reg_val = musb_readl(base, USBC_REG_o_ISCR);
+	reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+	reg_val |= (0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID);
+	reg_val = USBC_WakeUp_ClearChangeDetect(reg_val);
+	musb_writel(base, USBC_REG_o_ISCR, reg_val);
+}
+
+static void USBC_ConfigFIFO_Base(void)
+{
+	u32 reg_value;
+
+	/* config usb fifo, 8kb mode */
+	reg_value = readl(SUNXI_SRAMC_BASE + 0x04);
+	reg_value &= ~(0x03 << 0);
+	reg_value |= (1 << 0);
+	writel(reg_value, SUNXI_SRAMC_BASE + 0x04);
+}
+
+/******************************************************************************
+ * MUSB Glue code
+ ******************************************************************************/
+
+static irqreturn_t sunxi_musb_interrupt(int irq, void *__hci)
+{
+	struct musb		*musb = __hci;
+	irqreturn_t		retval = IRQ_NONE;
+
+	/* read and flush interrupts */
+	musb->int_usb = musb_readb(musb->mregs, MUSB_INTRUSB);
+	if (musb->int_usb)
+		musb_writeb(musb->mregs, MUSB_INTRUSB, musb->int_usb);
+	musb->int_tx = musb_readw(musb->mregs, MUSB_INTRTX);
+	if (musb->int_tx)
+		musb_writew(musb->mregs, MUSB_INTRTX, musb->int_tx);
+	musb->int_rx = musb_readw(musb->mregs, MUSB_INTRRX);
+	if (musb->int_rx)
+		musb_writew(musb->mregs, MUSB_INTRRX, musb->int_rx);
+
+	if (musb->int_usb || musb->int_tx || musb->int_rx)
+		retval |= musb_interrupt(musb);
+
+	return retval;
+}
+
+static void sunxi_musb_enable(struct musb *musb)
+{
+	pr_debug("%s():\n", __func__);
+
+	/* select PIO mode */
+	musb_writeb(musb->mregs, USBC_REG_o_VEND0, 0);
+
+	if (is_host_enabled(musb)) {
+		/* port power on */
+		sunxi_usbc_vbus_enable(0);
+	}
+}
+
+static void sunxi_musb_disable(struct musb *musb)
+{
+	pr_debug("%s():\n", __func__);
+
+	/* Put the controller back in a pristane state for "usb reset" */
+	if (musb->is_active) {
+		sunxi_usbc_disable(0);
+		sunxi_usbc_enable(0);
+		musb->is_active = 0;
+	}
+}
+
+static int sunxi_musb_init(struct musb *musb)
+{
+	int err;
+
+	pr_debug("%s():\n", __func__);
+
+	err = sunxi_usbc_request_resources(0);
+	if (err)
+		return err;
+
+	musb->isr = sunxi_musb_interrupt;
+	sunxi_usbc_enable(0);
+
+	USBC_ConfigFIFO_Base();
+	USBC_EnableDpDmPullUp(musb->mregs);
+	USBC_EnableIdPullUp(musb->mregs);
+
+	if (is_host_enabled(musb)) {
+		/* Host mode */
+		USBC_ForceIdToLow(musb->mregs);
+		USBC_ForceVbusValidToHigh(musb->mregs);
+	} else {
+		/* Peripheral mode */
+		USBC_ForceIdToHigh(musb->mregs);
+		USBC_ForceVbusValidDisable(musb->mregs);
+	}
+
+	return 0;
+}
+
+static int sunxi_musb_exit(struct musb *musb)
+{
+	pr_debug("%s():\n", __func__);
+
+	USBC_DisableDpDmPullUp(musb->mregs);
+	USBC_DisableIdPullUp(musb->mregs);
+	sunxi_usbc_vbus_disable(0);
+	sunxi_usbc_disable(0);
+
+	return sunxi_usbc_free_resources(0);
+}
+
+const struct musb_platform_ops sunxi_musb_ops = {
+	.init		= sunxi_musb_init,
+	.exit		= sunxi_musb_exit,
+
+	.enable		= sunxi_musb_enable,
+	.disable	= sunxi_musb_disable,
+};
diff --git a/include/usb.h b/include/usb.h
index 3d33b2d..b921a7f 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -154,8 +154,8 @@ enum usb_init_type {
 	defined(CONFIG_USB_OMAP3) || defined(CONFIG_USB_DA8XX) || \
 	defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
 	defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
-	defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_XHCI) || \
-	defined(CONFIG_USB_DWC2)
+	defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
+	defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2)
 
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 11/17] musb-new: Use time based timeouts rather then cpu-cycles based timeouts
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (9 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 10/17] musb-new: Add sunxi musb controller support Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 12/17] musb-new: Fix interrupt transfers not working Hans de Goede
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

CPU cycle based timeouts are no good, because how long they use depends on
CPU speed. Instead use time based timeouts, and wait one second for a
device connection to show up (per the USB spec), and wait USB_TIMEOUT_MS
for various urbs to complete.

This fixes "usb start" taking for ever when no device is plugged into the
otg port.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_uboot.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 2676f09..f8a0346 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -57,13 +57,11 @@ static struct urb *construct_urb(struct usb_device *dev, int endpoint_type,
 	return &urb;
 }
 
-#define MUSB_HOST_TIMEOUT	0x3ffffff
-
 static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 {
 	struct musb *host = hcd->hcd_priv;
 	int ret;
-	int timeout;
+	unsigned long timeout;
 
 	ret = musb_urb_enqueue(hcd, urb, 0);
 	if (ret < 0) {
@@ -71,12 +69,13 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 		return ret;
 	}
 
-	timeout = MUSB_HOST_TIMEOUT;
+	timeout = get_timer(0) + USB_TIMEOUT_MS(urb->pipe);
 	do {
 		if (ctrlc())
 			return -EIO;
 		host->isr(0, host);
-	} while ((urb->dev->status & USB_ST_NOT_PROC) && --timeout);
+	} while ((urb->dev->status & USB_ST_NOT_PROC) &&
+		 get_timer(0) < timeout);
 
 	return urb->status;
 }
@@ -115,7 +114,8 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 {
 	u8 power;
 	void *mbase;
-	int timeout = MUSB_HOST_TIMEOUT;
+	/* USB spec says it may take up to 1 second for a device to connect */
+	unsigned long timeout = get_timer(0) + 1000;
 
 	if (!host) {
 		printf("MUSB host is not registered\n");
@@ -127,8 +127,8 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	do {
 		if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM)
 			break;
-	} while (--timeout);
-	if (!timeout)
+	} while (get_timer(0) < timeout);
+	if (get_timer(0) >= timeout)
 		return -ENODEV;
 
 	power = musb_readb(mbase, MUSB_POWER);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 12/17] musb-new: Fix interrupt transfers not working
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (10 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 11/17] musb-new: Use time based timeouts rather then cpu-cycles based timeouts Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 13/17] musb-new: Fix reset sequence when in host mode Hans de Goede
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

For bulk and ctrl transfers common/usb.c sets udev->status = USB_ST_NOT_PROC,
but it does not do so for interrupt transfers.

musb_uboot.c: submit_urb() however was waiting for USB_ST_NOT_PROC to become 0,
and thus without anyone setting USB_ST_NOT_PROC would exit immediately for
interrupt urbs, returning the urb status of EINPROGRESS as error.

This commit fixes this, thereby also making usb_kbd.c work together with
musb_new and CONFIG_SYS_USB_EVENT_POLL.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_uboot.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index f8a0346..28500bf 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -74,7 +74,7 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 		if (ctrlc())
 			return -EIO;
 		host->isr(0, host);
-	} while ((urb->dev->status & USB_ST_NOT_PROC) &&
+	} while (urb->status == -EINPROGRESS &&
 		 get_timer(0) < timeout);
 
 	return urb->status;
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 13/17] musb-new: Fix reset sequence when in host mode
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (11 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 12/17] musb-new: Fix interrupt transfers not working Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 14/17] musb-new: Properly remove a transfer from the schedule on timeout Hans de Goede
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

This commit fixes a number of issues with the reset sequence of musb-new
in host mode:

1) Our usb device probe relies on a second device reset being done after the
first descriptors read. Factor the musb reset code into a usb_reset_root_port
function (and add this as an empty define for other controllers), and call
this when a device has no parent.

2) Just like with normal usb controllers there needs to be a delay after
reset, for normal usb controllers, this is handled in hub_port_reset, add a
delay to usb_reset_root_port.

3) Sync the musb reset sequence with the upstream kernel, clear all bits of
power except bits 4-7, and increase the time reset is asserted to 50 ms.

With these fixes an usb keyboard I have now always enumerates properly, where
as earlier it would only enumerare properly once every 5 tries.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 common/usb.c                      |  2 ++
 drivers/usb/musb-new/musb_uboot.c | 31 ++++++++++++++++++++-----------
 include/usb.h                     |  5 +++++
 3 files changed, 27 insertions(+), 11 deletions(-)

diff --git a/common/usb.c b/common/usb.c
index 1eda099..32e15cd 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -970,6 +970,8 @@ int usb_new_device(struct usb_device *dev)
 			printf("\n     Couldn't reset port %i\n", dev->portnr);
 			return 1;
 		}
+	} else {
+		usb_reset_root_port();
 	}
 #endif
 
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 28500bf..dab6f9b 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -110,9 +110,27 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 	return submit_urb(&hcd, urb);
 }
 
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+void usb_reset_root_port(void)
 {
+	void *mbase = host->mregs;
 	u8 power;
+
+	power = musb_readb(mbase, MUSB_POWER);
+	power &= 0xf0;
+	musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
+	mdelay(50);
+	power = musb_readb(mbase, MUSB_POWER);
+	musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
+	host->isr(0, host);
+	host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
+			USB_SPEED_HIGH :
+			(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
+			USB_SPEED_FULL : USB_SPEED_LOW;
+	mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
+}
+
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
 	void *mbase;
 	/* USB spec says it may take up to 1 second for a device to connect */
 	unsigned long timeout = get_timer(0) + 1000;
@@ -131,16 +149,7 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
 	if (get_timer(0) >= timeout)
 		return -ENODEV;
 
-	power = musb_readb(mbase, MUSB_POWER);
-	musb_writeb(mbase, MUSB_POWER, MUSB_POWER_RESET | power);
-	udelay(30000);
-	power = musb_readb(mbase, MUSB_POWER);
-	musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power);
-	host->isr(0, host);
-	host_speed = (musb_readb(mbase, MUSB_POWER) & MUSB_POWER_HSMODE) ?
-			USB_SPEED_HIGH :
-			(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
-			USB_SPEED_FULL : USB_SPEED_LOW;
+	usb_reset_root_port();
 	host->is_active = 1;
 	hcd.hcd_priv = host;
 
diff --git a/include/usb.h b/include/usb.h
index b921a7f..a083591 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -159,6 +159,11 @@ enum usb_init_type {
 
 int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
 int usb_lowlevel_stop(int index);
+#ifdef CONFIG_MUSB_HOST
+void usb_reset_root_port(void);
+#else
+#define usb_reset_root_port()
+#endif
 
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int transfer_len);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 14/17] musb-new: Properly remove a transfer from the schedule on timeout
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (12 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 13/17] musb-new: Fix reset sequence when in host mode Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 15/17] musb-new: Add urb and hep parameters to construct_urb Hans de Goede
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

If a transfer / urb times-out, properly remove it from the schedule, rather
then letting it sit on the ep head. This stops the musb code from getting
confused and refusing to queue further transfers after a timeout.

Tested by unplugging a usb-keyboard, replugging it and doing a usb-reset,
before this commit the keyboard would not work after the usb-reset.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_host.c  | 12 +++++++++---
 drivers/usb/musb-new/musb_host.h  |  1 +
 drivers/usb/musb-new/musb_uboot.c |  3 +++
 drivers/usb/musb-new/usb-compat.h |  1 +
 4 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/drivers/usb/musb-new/musb_host.c b/drivers/usb/musb-new/musb_host.c
index bbcee88..437309c 100644
--- a/drivers/usb/musb-new/musb_host.c
+++ b/drivers/usb/musb-new/musb_host.c
@@ -2130,8 +2130,6 @@ done:
 	return ret;
 }
 
-
-#ifndef __UBOOT__
 /*
  * abort a transfer that's at the head of a hardware queue.
  * called with controller locked, irqs blocked
@@ -2195,7 +2193,14 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
 	return status;
 }
 
-static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status)
+#ifndef __UBOOT__
+static int musb_urb_dequeue(
+#else
+int musb_urb_dequeue(
+#endif
+	struct usb_hcd *hcd,
+	struct urb *urb,
+	int status)
 {
 	struct musb		*musb = hcd_to_musb(hcd);
 	struct musb_qh		*qh;
@@ -2253,6 +2258,7 @@ done:
 	return ret;
 }
 
+#ifndef __UBOOT__
 /* disable an endpoint */
 static void
 musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep)
diff --git a/drivers/usb/musb-new/musb_host.h b/drivers/usb/musb-new/musb_host.h
index ebebe0c..546b4a2 100644
--- a/drivers/usb/musb-new/musb_host.h
+++ b/drivers/usb/musb-new/musb_host.h
@@ -110,5 +110,6 @@ static inline struct urb *next_urb(struct musb_qh *qh)
 
 #ifdef __UBOOT__
 int musb_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags);
+int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status);
 #endif
 #endif				/* _MUSB_HOST_H */
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index dab6f9b..e823ad1 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -77,6 +77,9 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 	} while (urb->status == -EINPROGRESS &&
 		 get_timer(0) < timeout);
 
+	if (urb->status == -EINPROGRESS)
+		musb_urb_dequeue(hcd, urb, -ETIME);
+
 	return urb->status;
 }
 
diff --git a/drivers/usb/musb-new/usb-compat.h b/drivers/usb/musb-new/usb-compat.h
index 27f656f..50bad37 100644
--- a/drivers/usb/musb-new/usb-compat.h
+++ b/drivers/usb/musb-new/usb-compat.h
@@ -48,6 +48,7 @@ struct urb {
 	list_add_tail(&urb->urb_list, &urb->ep->urb_list);	\
 	ret; })
 #define usb_hcd_unlink_urb_from_ep(hcd, urb)	list_del_init(&urb->urb_list)
+#define usb_hcd_check_unlink_urb(hdc, urb, status)	0
 
 static inline void usb_hcd_giveback_urb(struct usb_hcd *hcd,
 					struct urb *urb,
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 15/17] musb-new: Add urb and hep parameters to construct_urb
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (13 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 14/17] musb-new: Properly remove a transfer from the schedule on timeout Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 16/17] musb-new: Add interrupt queue support Hans de Goede
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Make construct_urb take an urb and hep parameter, rather then having it always
operate on the file global urb and hep structs. This is a preperation patch
for adding interrupt queue support.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_uboot.c | 63 +++++++++++++++++++--------------------
 1 file changed, 31 insertions(+), 32 deletions(-)

diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index e823ad1..3f9a98c 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -25,36 +25,35 @@ static void musb_host_complete_urb(struct urb *urb)
 static struct usb_host_endpoint hep;
 static struct urb urb;
 
-static struct urb *construct_urb(struct usb_device *dev, int endpoint_type,
-				unsigned long pipe, void *buffer, int len,
-				struct devrequest *setup, int interval)
+static void construct_urb(struct urb *urb, struct usb_host_endpoint *hep,
+			  struct usb_device *dev, int endpoint_type,
+			  unsigned long pipe, void *buffer, int len,
+			  struct devrequest *setup, int interval)
 {
 	int epnum = usb_pipeendpoint(pipe);
 	int is_in = usb_pipein(pipe);
 
-	memset(&urb, 0, sizeof(struct urb));
-	memset(&hep, 0, sizeof(struct usb_host_endpoint));
-	INIT_LIST_HEAD(&hep.urb_list);
-	INIT_LIST_HEAD(&urb.urb_list);
-	urb.ep = &hep;
-	urb.complete = musb_host_complete_urb;
-	urb.status = -EINPROGRESS;
-	urb.dev = dev;
-	urb.pipe = pipe;
-	urb.transfer_buffer = buffer;
-	urb.transfer_dma = (unsigned long)buffer;
-	urb.transfer_buffer_length = len;
-	urb.setup_packet = (unsigned char *)setup;
-
-	urb.ep->desc.wMaxPacketSize =
+	memset(urb, 0, sizeof(struct urb));
+	memset(hep, 0, sizeof(struct usb_host_endpoint));
+	INIT_LIST_HEAD(&hep->urb_list);
+	INIT_LIST_HEAD(&urb->urb_list);
+	urb->ep = hep;
+	urb->complete = musb_host_complete_urb;
+	urb->status = -EINPROGRESS;
+	urb->dev = dev;
+	urb->pipe = pipe;
+	urb->transfer_buffer = buffer;
+	urb->transfer_dma = (unsigned long)buffer;
+	urb->transfer_buffer_length = len;
+	urb->setup_packet = (unsigned char *)setup;
+
+	urb->ep->desc.wMaxPacketSize =
 		__cpu_to_le16(is_in ? dev->epmaxpacketin[epnum] :
 				dev->epmaxpacketout[epnum]);
-	urb.ep->desc.bmAttributes = endpoint_type;
-	urb.ep->desc.bEndpointAddress =
+	urb->ep->desc.bmAttributes = endpoint_type;
+	urb->ep->desc.bEndpointAddress =
 		(is_in ? USB_DIR_IN : USB_DIR_OUT) | epnum;
-	urb.ep->desc.bInterval = interval;
-
-	return &urb;
+	urb->ep->desc.bInterval = interval;
 }
 
 static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
@@ -86,31 +85,31 @@ static int submit_urb(struct usb_hcd *hcd, struct urb *urb)
 int submit_control_msg(struct usb_device *dev, unsigned long pipe,
 			void *buffer, int len, struct devrequest *setup)
 {
-	struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_CONTROL, pipe,
-					buffer, len, setup, 0);
+	construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_CONTROL, pipe,
+		      buffer, len, setup, 0);
 
 	/* Fix speed for non hub-attached devices */
 	if (!dev->parent)
 		dev->speed = host_speed;
 
-	return submit_urb(&hcd, urb);
+	return submit_urb(&hcd, &urb);
 }
 
 
 int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
 					void *buffer, int len)
 {
-	struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_BULK, pipe,
-					buffer, len, NULL, 0);
-	return submit_urb(&hcd, urb);
+	construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_BULK, pipe,
+		      buffer, len, NULL, 0);
+	return submit_urb(&hcd, &urb);
 }
 
 int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 				void *buffer, int len, int interval)
 {
-	struct urb *urb = construct_urb(dev, USB_ENDPOINT_XFER_INT, pipe,
-					buffer, len, NULL, interval);
-	return submit_urb(&hcd, urb);
+	construct_urb(&urb, &hep, dev, USB_ENDPOINT_XFER_INT, pipe,
+		      buffer, len, NULL, interval);
+	return submit_urb(&hcd, &urb);
 }
 
 void usb_reset_root_port(void)
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 16/17] musb-new: Add interrupt queue support
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (14 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 15/17] musb-new: Add urb and hep parameters to construct_urb Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-11 19:34 ` [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support Hans de Goede
  2015-01-12  2:59 ` [U-Boot] [PATCH 00/17] sunxi: musb otg " Marek Vasut
  17 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Add interrupt queue support, so that a usb keyboard can be used without
causing huge latencies.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 drivers/usb/musb-new/musb_uboot.c | 65 +++++++++++++++++++++++++++++++++++++++
 include/usb.h                     |  3 +-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 3f9a98c..6e58ddf 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -12,6 +12,11 @@
 #include "musb_gadget.h"
 
 #ifdef CONFIG_MUSB_HOST
+struct int_queue {
+	struct usb_host_endpoint hep;
+	struct urb urb;
+};
+
 static struct musb *host;
 static struct usb_hcd hcd;
 static enum usb_device_speed host_speed;
@@ -112,6 +117,66 @@ int submit_int_msg(struct usb_device *dev, unsigned long pipe,
 	return submit_urb(&hcd, &urb);
 }
 
+struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
+	int queuesize, int elementsize, void *buffer, int interval)
+{
+	struct int_queue *queue;
+	int ret, index = usb_pipein(pipe) * 16 + usb_pipeendpoint(pipe);
+
+	if (queuesize != 1) {
+		printf("ERROR musb int-queues only support queuesize 1\n");
+		return NULL;
+	}
+
+	if (dev->int_pending & (1 << index)) {
+		printf("ERROR int-urb is already pending on pipe %lx\n", pipe);
+		return NULL;
+	}
+
+	queue = malloc(sizeof(*queue));
+	if (!queue)
+		return NULL;
+
+	construct_urb(&queue->urb, &queue->hep, dev, USB_ENDPOINT_XFER_INT,
+		      pipe, buffer, elementsize, NULL, interval);
+
+	ret = musb_urb_enqueue(&hcd, &queue->urb, 0);
+	if (ret < 0) {
+		printf("Failed to enqueue URB to controller\n");
+		free(queue);
+		return NULL;
+	}
+
+	dev->int_pending |= 1 << index;
+	return queue;
+}
+
+int destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+	int index = usb_pipein(queue->urb.pipe) * 16 + 
+		    usb_pipeendpoint(queue->urb.pipe);
+
+	if (queue->urb.status == -EINPROGRESS)
+		musb_urb_dequeue(&hcd, &queue->urb, -ETIME);
+
+	dev->int_pending &= ~(1 << index);
+	free(queue);
+	return 0;
+}
+
+void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
+{
+	if (queue->urb.status != -EINPROGRESS)
+		return NULL; /* URB has already completed in a prev. poll */
+
+	host->isr(0, host);
+
+	if (queue->urb.status != -EINPROGRESS)
+		return queue->urb.transfer_buffer; /* Done */
+
+	return NULL; /* URB still pending */
+}
+
 void usb_reset_root_port(void)
 {
 	void *mbase = host->mregs;
diff --git a/include/usb.h b/include/usb.h
index a083591..a8fee0b 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -120,6 +120,7 @@ struct usb_device {
 	 * Each instance needs its own set of data structures.
 	 */
 	unsigned long status;
+	unsigned long int_pending;	/* 1 bit per ep, used by int_queue */
 	int act_len;			/* transfered bytes */
 	int maxchild;			/* Number of ports if hub */
 	int portnr;
@@ -172,7 +173,7 @@ int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
 			int transfer_len, int interval);
 
-#ifdef CONFIG_USB_EHCI /* Only the ehci code has pollable int support */
+#if defined CONFIG_USB_EHCI || defined CONFIG_MUSB_HOST
 struct int_queue *create_int_queue(struct usb_device *dev, unsigned long pipe,
 	int queuesize, int elementsize, void *buffer, int interval);
 int destroy_int_queue(struct usb_device *dev, struct int_queue *queue);
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (15 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 16/17] musb-new: Add interrupt queue support Hans de Goede
@ 2015-01-11 19:34 ` Hans de Goede
  2015-01-13 19:59   ` Ian Campbell
  2015-01-31  2:54   ` Siarhei Siamashka
  2015-01-12  2:59 ` [U-Boot] [PATCH 00/17] sunxi: musb otg " Marek Vasut
  17 siblings, 2 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-11 19:34 UTC (permalink / raw)
  To: u-boot

Hookup OTG USB controller support and enable the otg controller + USB-keyb
on various tablets.

This allows tablet owners to interact with u-boot without needing to solder
a serial console onto their tablet PCB.

Signed-off-by: Hans de Goede <hdegoede@redhat.com>
---
 arch/arm/include/asm/arch-sunxi/usbc.h |  2 ++
 board/sunxi/Kconfig                    |  9 +++++++++
 board/sunxi/board.c                    | 25 +++++++++++++++++++++++++
 configs/Ippo_q8h_v1_2_defconfig        |  3 ++-
 configs/Ippo_q8h_v5_defconfig          |  3 ++-
 include/configs/sunxi-common.h         | 10 +++++++++-
 6 files changed, 49 insertions(+), 3 deletions(-)

diff --git a/arch/arm/include/asm/arch-sunxi/usbc.h b/arch/arm/include/asm/arch-sunxi/usbc.h
index 8d20973..cb538cd 100644
--- a/arch/arm/include/asm/arch-sunxi/usbc.h
+++ b/arch/arm/include/asm/arch-sunxi/usbc.h
@@ -11,6 +11,8 @@
  * SPDX-License-Identifier:	GPL-2.0+
  */
 
+extern const struct musb_platform_ops sunxi_musb_ops;
+
 void *sunxi_usbc_get_io_base(int index);
 int sunxi_usbc_request_resources(int index);
 int sunxi_usbc_free_resources(int index);
diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig
index bece6b7..89c51a2 100644
--- a/board/sunxi/Kconfig
+++ b/board/sunxi/Kconfig
@@ -391,6 +391,15 @@ config VIDEO_LCD_PANEL_HITACHI_TX18D42VM
 endchoice
 
 
+config USB_MUSB_SUNXI
+	bool "Enable sunxi OTG / DRC USB controller in host mode"
+	default n
+	---help---
+	Say y here to enable support for the sunxi OTG / DRC USB controller
+	used on almost all sunxi boards. Note currently u-boot can only have
+	one usb host controller enabled at a time, so enabling this on boards
+	which also use the ehci host controller will result in build errors.
+
 config USB_KEYBOARD
 	boolean "Enable USB keyboard support"
 	default y
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 7d6d075..569ac84 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -28,7 +28,9 @@
 #include <asm/arch/dram.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/mmc.h>
+#include <asm/arch/usbc.h>
 #include <asm/io.h>
+#include <linux/usb/musb.h>
 #include <net.h>
 
 DECLARE_GLOBAL_DATA_PTR;
@@ -208,6 +210,26 @@ void sunxi_board_init(void)
 }
 #endif
 
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
+static struct musb_hdrc_config musb_config = {
+	.multipoint     = 1,
+	.dyn_fifo       = 1,
+	.num_eps        = 6,
+	.ram_bits       = 11,
+};
+
+static struct musb_hdrc_platform_data musb_plat = {
+#if defined(CONFIG_MUSB_HOST)
+	.mode           = MUSB_HOST,
+#else
+	.mode		= MUSB_PERIPHERAL,
+#endif
+	.config         = &musb_config,
+	.power          = 250,
+	.platform_ops	= &sunxi_musb_ops,
+};
+#endif
+
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
@@ -227,6 +249,9 @@ int misc_init_r(void)
 		eth_setenv_enetaddr("ethaddr", mac_addr);
 	}
 
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
+	musb_register(&musb_plat, NULL, (void *)SUNXI_USB0_BASE);
+#endif
 	return 0;
 }
 #endif
diff --git a/configs/Ippo_q8h_v1_2_defconfig b/configs/Ippo_q8h_v1_2_defconfig
index 0447b06..3e6d3cc 100644
--- a/configs/Ippo_q8h_v1_2_defconfig
+++ b/configs/Ippo_q8h_v1_2_defconfig
@@ -1,11 +1,12 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v1.2.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="axp_drivebus"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:167,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="PH7"
 CONFIG_VIDEO_LCD_BL_EN="PH6"
 CONFIG_VIDEO_LCD_BL_PWM="PH0"
-CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN8I=y
diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig
index 4e82bf9..b96985e 100644
--- a/configs/Ippo_q8h_v5_defconfig
+++ b/configs/Ippo_q8h_v5_defconfig
@@ -1,11 +1,12 @@
 CONFIG_SPL=y
 CONFIG_SYS_EXTRA_OPTIONS="CONS_INDEX=5"
 CONFIG_FDTFILE="sun8i-a23-ippo-q8h-v5.dtb"
+CONFIG_USB_MUSB_SUNXI=y
+CONFIG_USB0_VBUS_PIN="axp_drivebus"
 CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:168,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0"
 CONFIG_VIDEO_LCD_POWER="PH7"
 CONFIG_VIDEO_LCD_BL_EN="PH6"
 CONFIG_VIDEO_LCD_BL_PWM="PH0"
-CONFIG_USB_KEYBOARD=n
 +S:CONFIG_ARM=y
 +S:CONFIG_ARCH_SUNXI=y
 +S:CONFIG_MACH_SUN8I=y
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 64d379a..121bcf4 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -247,8 +247,16 @@
 #endif
 
 #ifdef CONFIG_USB_EHCI
-#define CONFIG_CMD_USB
 #define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
+#endif
+
+#ifdef CONFIG_USB_MUSB_SUNXI
+#define CONFIG_MUSB_HOST
+#define CONFIG_MUSB_PIO_ONLY
+#endif
+
+#if defined CONFIG_USB_EHCI || defined CONFIG_USB_MUSB_SUNXI
+#define CONFIG_CMD_USB
 #define CONFIG_USB_STORAGE
 #endif
 
-- 
2.1.0

^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 00/17] sunxi: musb otg controller support
  2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
                   ` (16 preceding siblings ...)
  2015-01-11 19:34 ` [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support Hans de Goede
@ 2015-01-12  2:59 ` Marek Vasut
  17 siblings, 0 replies; 31+ messages in thread
From: Marek Vasut @ 2015-01-12  2:59 UTC (permalink / raw)
  To: u-boot

On Sunday, January 11, 2015 at 08:34:38 PM, Hans de Goede wrote:
> Hi Marek, Ian, et al,
> 
> I'm very happy to present this patch series, which is the last pieze of
> the puzzle to make it possible for people to use u-boot on sunxi devices
> without needing to resort to putting a soldering iron to their tablet :)
> 
> With this series sunxi tablet owners can simply plug in a usb keyboard into
> the otg port of their tablet (how boring).
> 
> Interestingly enough getting the musb code to work on sunxi was quite east,
> most of my time went into fixing generic usb / musb issues, which should
> help on other boards too :)
> 
> This entire series is based on u-boot-sunxi/next and for some of the sunxi
> specific patches there will likely be conflicts when applied directly to
> master, therefor I would like to suggest the following scheme for getting
> this upstream:
> 
> 1) Add patches 1-5 to u-boot-sunxi/next (once reviewed)
> 2) Add patches 6-16 to u-boot-usb/next (once reviewed)

Applied 6-16 to u-boot-usb/next (V2 of 07 is applied instead).

Thanks!

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls
  2015-01-11 19:34 ` [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls Hans de Goede
@ 2015-01-13 18:49   ` Ian Campbell
  2015-01-14  8:21     ` Hans de Goede
  0 siblings, 1 reply; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 18:49 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
> The voltage setting code knows it needs to call axp221_init before calling
> the various voltage setting functions.
> 
> But users of axp utility functions like axp221_get_sid() do not know this,
> so the utility functions always call axp221_init() to ensure that the
> p2wi / rsb setup magic has been done.
> 
> Since doing this repeatedly is quite expensive, add a check to axp221_init
> so that it only does the initialization once.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>

> ---
>  drivers/power/axp221.c | 6 ++++++
>  1 file changed, 6 insertions(+)
> 
> diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
> index 1fda19a..728727b 100644
> --- a/drivers/power/axp221.c
> +++ b/drivers/power/axp221.c
> @@ -304,9 +304,14 @@ int axp221_set_aldo3(unsigned int mvolt)
>  
>  int axp221_init(void)
>  {
> +	/* This cannot be 0 because it is used in SPL before BSS is ready */
> +	static int needs_init = 1;
>  	u8 axp_chip_id;
>  	int ret;
>  
> +	if (!needs_init)
> +		return 0;
> +
>  	ret = pmic_bus_init();
>  	if (ret)
>  		return ret;
> @@ -318,6 +323,7 @@ int axp221_init(void)
>  	if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
>  		return -ENODEV;
>  
> +	needs_init = 0;
>  	return 0;
>  }
>  

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin
  2015-01-11 19:34 ` [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin Hans de Goede
@ 2015-01-13 18:52   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 18:52 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg
  2015-01-11 19:34 ` [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg Hans de Goede
@ 2015-01-13 18:55   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 18:55 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
> Most of the usb-controller init code found in ehci-sunxi.c also is necessary
> to init the otg usb controller, so move it to a common place.
> 
> While at it also update various #ifdefs / defines for sun8i support.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

On the assumption that the code motion is really just that:
Acked-by: Ian Campbell <ijc@hellion.org.uk>

(I general prefer code motion patch to be just that, with precursor
refactoring patch etc, but nevermind).

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code
  2015-01-11 19:34 ` [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code Hans de Goede
@ 2015-01-13 18:57   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 18:57 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin
  2015-01-11 19:34 ` [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin Hans de Goede
@ 2015-01-13 18:58   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 18:58 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
> The axp221 / axp223's N_VBUSEN pin can be configured as an output rather
> then an input, and this is used on some boards to control usb-vbus0, add
> support for this.
> 
> Signed-off-by: Hans de Goede <hdegoede@redhat.com>

I wonder if we should expose this as a pseudo-gpio? Anyway, this'll do
for starters:

Acked-by: Ian Campbell <ijc@hellion.org.uk>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-01-11 19:34 ` [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support Hans de Goede
@ 2015-01-13 19:59   ` Ian Campbell
  2015-01-14  7:48     ` Hans de Goede
  2015-01-31  2:54   ` Siarhei Siamashka
  1 sibling, 1 reply; 31+ messages in thread
From: Ian Campbell @ 2015-01-13 19:59 UTC (permalink / raw)
  To: u-boot

On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
> Hookup OTG USB controller support and enable the otg controller + USB-keyb
> on various tablets.
> 
> This allows tablet owners to interact with u-boot without needing to solder
> a serial console onto their tablet PCB.

Looks good, except I can't for the life of me find where
CONFIG_MUSB_GADGET is ever set for a sunxi platform.

I suspect it's just there in preparation for some future gadget mode
work (what we care about here is host mode), is that right?

If so: Acked-by: Ian Campbell <ijc@hellion.org.uk>

> +#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)

Not just #ifdef CONFIG_USB_MUSB_SUNXI? (Ack either way)

Ian.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-01-13 19:59   ` Ian Campbell
@ 2015-01-14  7:48     ` Hans de Goede
  0 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-14  7:48 UTC (permalink / raw)
  To: u-boot

Hi,

On 13-01-15 20:59, Ian Campbell wrote:
> On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
>> Hookup OTG USB controller support and enable the otg controller + USB-keyb
>> on various tablets.
>>
>> This allows tablet owners to interact with u-boot without needing to solder
>> a serial console onto their tablet PCB.
>
> Looks good, except I can't for the life of me find where
> CONFIG_MUSB_GADGET is ever set for a sunxi platform.
>
> I suspect it's just there in preparation for some future gadget mode
> work (what we care about here is host mode), is that right?

Right, in theory we have everything in place for gadget mode when this
patch-set lands and all someone needs to do is add a Kconfig option
for it. Note I do not plan to work on that ATM, only so much hours
in a day, etc. but I do invite others who are interested in this
to take a look at the gadget stuff and patches are welcome :)

>
> If so: Acked-by: Ian Campbell <ijc@hellion.org.uk>
>
>> +#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_MUSB_GADGET)
>
> Not just #ifdef CONFIG_USB_MUSB_SUNXI? (Ack either way)

This is the construct the other MUSB users use in their board code,
but yes either would work.

Regards,

Hans

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls
  2015-01-13 18:49   ` Ian Campbell
@ 2015-01-14  8:21     ` Hans de Goede
  0 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-01-14  8:21 UTC (permalink / raw)
  To: u-boot

Hi,

On 13-01-15 19:49, Ian Campbell wrote:
> On Sun, 2015-01-11 at 20:34 +0100, Hans de Goede wrote:
>> The voltage setting code knows it needs to call axp221_init before calling
>> the various voltage setting functions.
>>
>> But users of axp utility functions like axp221_get_sid() do not know this,
>> so the utility functions always call axp221_init() to ensure that the
>> p2wi / rsb setup magic has been done.
>>
>> Since doing this repeatedly is quite expensive, add a check to axp221_init
>> so that it only does the initialization once.
>>
>> Signed-off-by: Hans de Goede <hdegoede@redhat.com>
> Acked-by: Ian Campbell <ijc@hellion.org.uk>

Thanks for the reviews. I've queued up the first 5 patches of this series
in u-boot-sunxi/next. I'll likely send a pull-req with everything we've in next
later today.

Regards,

Hans

>
>> ---
>>   drivers/power/axp221.c | 6 ++++++
>>   1 file changed, 6 insertions(+)
>>
>> diff --git a/drivers/power/axp221.c b/drivers/power/axp221.c
>> index 1fda19a..728727b 100644
>> --- a/drivers/power/axp221.c
>> +++ b/drivers/power/axp221.c
>> @@ -304,9 +304,14 @@ int axp221_set_aldo3(unsigned int mvolt)
>>
>>   int axp221_init(void)
>>   {
>> +	/* This cannot be 0 because it is used in SPL before BSS is ready */
>> +	static int needs_init = 1;
>>   	u8 axp_chip_id;
>>   	int ret;
>>
>> +	if (!needs_init)
>> +		return 0;
>> +
>>   	ret = pmic_bus_init();
>>   	if (ret)
>>   		return ret;
>> @@ -318,6 +323,7 @@ int axp221_init(void)
>>   	if (!(axp_chip_id == 0x6 || axp_chip_id == 0x7 || axp_chip_id == 0x17))
>>   		return -ENODEV;
>>
>> +	needs_init = 0;
>>   	return 0;
>>   }
>>
>
>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-01-11 19:34 ` [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support Hans de Goede
  2015-01-13 19:59   ` Ian Campbell
@ 2015-01-31  2:54   ` Siarhei Siamashka
  2015-02-09  3:54     ` Siarhei Siamashka
  1 sibling, 1 reply; 31+ messages in thread
From: Siarhei Siamashka @ 2015-01-31  2:54 UTC (permalink / raw)
  To: u-boot

On Sun, 11 Jan 2015 20:34:55 +0100
Hans de Goede <hdegoede@redhat.com> wrote:

> Hookup OTG USB controller support and enable the otg controller + USB-keyb
> on various tablets.
> 
> This allows tablet owners to interact with u-boot without needing to solder
> a serial console onto their tablet PCB.

Thanks. Works great on my Primo73 and Primo81 tablets. However I have
just one naive question before happily taking it into use by default.

Is the hardcoded otg host mode (without checking the id pin) always
safe? For example, what happens if somebody connects a charger instead
of a usb keyboard to the tablet?

-- 
Best regards,
Siarhei Siamashka

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-01-31  2:54   ` Siarhei Siamashka
@ 2015-02-09  3:54     ` Siarhei Siamashka
  2015-02-09 22:10       ` Michal Suchanek
  0 siblings, 1 reply; 31+ messages in thread
From: Siarhei Siamashka @ 2015-02-09  3:54 UTC (permalink / raw)
  To: u-boot

On Sat, 31 Jan 2015 04:54:47 +0200
Siarhei Siamashka <siarhei.siamashka@gmail.com> wrote:

> On Sun, 11 Jan 2015 20:34:55 +0100
> Hans de Goede <hdegoede@redhat.com> wrote:
> 
> > Hookup OTG USB controller support and enable the otg controller + USB-keyb
> > on various tablets.
> > 
> > This allows tablet owners to interact with u-boot without needing to solder
> > a serial console onto their tablet PCB.
> 
> Thanks. Works great on my Primo73 and Primo81 tablets. However I have
> just one naive question before happily taking it into use by default.
> 
> Is the hardcoded otg host mode (without checking the id pin) always
> safe? For example, what happens if somebody connects a charger instead
> of a usb keyboard to the tablet?

So, does anyone have any idea if it is theoretically safe to have two
USB hosts connected to each other and both driving VBUS at +5V?

A somewhat realistic scenario is booting an Allwinner tablet over
USB using the FEL mode. Is it a good idea for such tablet to have
CONFIG_USB_MUSB_SUNXI=y and CONFIG_USB0_VBUS_PIN="axp_drivebus"
in defconfig?

-- 
Best regards,
Siarhei Siamashka

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-02-09  3:54     ` Siarhei Siamashka
@ 2015-02-09 22:10       ` Michal Suchanek
  2015-02-10  8:24         ` Hans de Goede
  0 siblings, 1 reply; 31+ messages in thread
From: Michal Suchanek @ 2015-02-09 22:10 UTC (permalink / raw)
  To: u-boot

On 9 February 2015 at 04:54, Siarhei Siamashka
<siarhei.siamashka@gmail.com> wrote:
> On Sat, 31 Jan 2015 04:54:47 +0200
> Siarhei Siamashka <siarhei.siamashka@gmail.com> wrote:
>
>> On Sun, 11 Jan 2015 20:34:55 +0100
>> Hans de Goede <hdegoede@redhat.com> wrote:
>>
>> > Hookup OTG USB controller support and enable the otg controller + USB-keyb
>> > on various tablets.
>> >
>> > This allows tablet owners to interact with u-boot without needing to solder
>> > a serial console onto their tablet PCB.
>>
>> Thanks. Works great on my Primo73 and Primo81 tablets. However I have
>> just one naive question before happily taking it into use by default.
>>
>> Is the hardcoded otg host mode (without checking the id pin) always
>> safe? For example, what happens if somebody connects a charger instead
>> of a usb keyboard to the tablet?
>
> So, does anyone have any idea if it is theoretically safe to have two
> USB hosts connected to each other and both driving VBUS at +5V?
>
> A somewhat realistic scenario is booting an Allwinner tablet over
> USB using the FEL mode. Is it a good idea for such tablet to have
> CONFIG_USB_MUSB_SUNXI=y and CONFIG_USB0_VBUS_PIN="axp_drivebus"
> in defconfig?
>

From my past experiments with some non-standard-compliant cables which
allow connecting a tablet with a PC without telling the tablet to go
OTG mode it seems the tablet battery is drained really quick in this
case.

There is a protocol for telling the tablet not to power the bus (or
telling the PC not to power it for that matter) but both sides have to
support matching part of the protocol. Either way, ideal case is that
tablet gets power form PC or powered hub even in host mode which is
not standards-compliant and obviously does not work with stuff like
keyboards.

However, it should be possible to detect that there is bus power at
the moment a device is connected and not power the device in that case
regardless of usb mode negotiated after the connection.

Thanks

Michal

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support
  2015-02-09 22:10       ` Michal Suchanek
@ 2015-02-10  8:24         ` Hans de Goede
  0 siblings, 0 replies; 31+ messages in thread
From: Hans de Goede @ 2015-02-10  8:24 UTC (permalink / raw)
  To: u-boot

Hi,

On 09-02-15 23:10, Michal Suchanek wrote:
> On 9 February 2015 at 04:54, Siarhei Siamashka
> <siarhei.siamashka@gmail.com> wrote:
>> On Sat, 31 Jan 2015 04:54:47 +0200
>> Siarhei Siamashka <siarhei.siamashka@gmail.com> wrote:
>>
>>> On Sun, 11 Jan 2015 20:34:55 +0100
>>> Hans de Goede <hdegoede@redhat.com> wrote:
>>>
>>>> Hookup OTG USB controller support and enable the otg controller + USB-keyb
>>>> on various tablets.
>>>>
>>>> This allows tablet owners to interact with u-boot without needing to solder
>>>> a serial console onto their tablet PCB.
>>>
>>> Thanks. Works great on my Primo73 and Primo81 tablets. However I have
>>> just one naive question before happily taking it into use by default.
>>>
>>> Is the hardcoded otg host mode (without checking the id pin) always
>>> safe? For example, what happens if somebody connects a charger instead
>>> of a usb keyboard to the tablet?
>>
>> So, does anyone have any idea if it is theoretically safe to have two
>> USB hosts connected to each other and both driving VBUS at +5V?
>>
>> A somewhat realistic scenario is booting an Allwinner tablet over
>> USB using the FEL mode. Is it a good idea for such tablet to have
>> CONFIG_USB_MUSB_SUNXI=y and CONFIG_USB0_VBUS_PIN="axp_drivebus"
>> in defconfig?
>>
>
>  From my past experiments with some non-standard-compliant cables which
> allow connecting a tablet with a PC without telling the tablet to go
> OTG mode it seems the tablet battery is drained really quick in this
> case.
>
> There is a protocol for telling the tablet not to power the bus (or
> telling the PC not to power it for that matter) but both sides have to
> support matching part of the protocol. Either way, ideal case is that
> tablet gets power form PC or powered hub even in host mode which is
> not standards-compliant and obviously does not work with stuff like
> keyboards.
>
> However, it should be possible to detect that there is bus power at
> the moment a device is connected and not power the device in that case
> regardless of usb mode negotiated after the connection.

Right, I've fixing this on my todo list, the plan is to add vbus_det
support, and first check if there is an external vbus before enabling
vbus.

Regards,

Hans

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2015-02-10  8:24 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-01-11 19:34 [U-Boot] [PATCH 00/17] sunxi: musb otg controller support Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 01/17] sunxi: axp221: Protect axp221_init against multiple calls Hans de Goede
2015-01-13 18:49   ` Ian Campbell
2015-01-14  8:21     ` Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 02/17] sunxi: axp221: Add support for controlling the drivebus pin Hans de Goede
2015-01-13 18:52   ` Ian Campbell
2015-01-11 19:34 ` [U-Boot] [PATCH 03/17] sunxi: Move usb-controller init code out of ehci-sunxi.c for reuse for otg Hans de Goede
2015-01-13 18:55   ` Ian Campbell
2015-01-11 19:34 ` [U-Boot] [PATCH 04/17] sunxi: usbc: Add support for usb0 to the common usbc code Hans de Goede
2015-01-13 18:57   ` Ian Campbell
2015-01-11 19:34 ` [U-Boot] [PATCH 05/17] sunxi: usbc: Add support for usb-vbus0 controller by axp drivebus pin Hans de Goede
2015-01-13 18:58   ` Ian Campbell
2015-01-11 19:34 ` [U-Boot] [PATCH 06/17] usb: Fix usb_kbd_deregister when console-muxing is used Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 07/17] usb: Add an interval parameter to create_int_queue Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 08/17] usb: Do not log an error when no devices is plugged into a root-hub-less hcd Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 09/17] musb-new: Add register defines for different reg layout on sunxi Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 10/17] musb-new: Add sunxi musb controller support Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 11/17] musb-new: Use time based timeouts rather then cpu-cycles based timeouts Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 12/17] musb-new: Fix interrupt transfers not working Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 13/17] musb-new: Fix reset sequence when in host mode Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 14/17] musb-new: Properly remove a transfer from the schedule on timeout Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 15/17] musb-new: Add urb and hep parameters to construct_urb Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 16/17] musb-new: Add interrupt queue support Hans de Goede
2015-01-11 19:34 ` [U-Boot] [PATCH 17/17] sunxi: Hookup OTG USB controller support Hans de Goede
2015-01-13 19:59   ` Ian Campbell
2015-01-14  7:48     ` Hans de Goede
2015-01-31  2:54   ` Siarhei Siamashka
2015-02-09  3:54     ` Siarhei Siamashka
2015-02-09 22:10       ` Michal Suchanek
2015-02-10  8:24         ` Hans de Goede
2015-01-12  2:59 ` [U-Boot] [PATCH 00/17] sunxi: musb otg " Marek Vasut

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox