Skip to contentSkip to conversation

Tegra EHCI driver

PATCH Superseded Benoit Goby 2 participants 8 messages Feb 17, 2011 4 messages not in the archive

Subsystems (5)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore
#0 lore raw

v3 cover Tegra EHCI driver

This patch series adds support for EHCI compliant USB host controllers found in Tegra SoCs. The EHCI driver depends on the Tegra PHY configuration interface that is used by both tegra ehci driver and gadget driver. Tested on 2.6.38rc4.

v2 changes:
* Add ulpi_viewport.c for controllers with a viewport register
* Update tegra usb_phy interface
* Remove tegra_ehci_reset and use ehci_reset or tdi_reset instead
* Select USB_ARCH_HAS_EHCI in tegra/Kconfig instead of usb/Kconfig v3 changes:
* Remove remaining Change-Id from commit messages

Benoit Goby (3):
usb: otg: Add ulpi viewport access ops
ARM: tegra: Add support for Tegra USB PHYs
usb: host: Add EHCI driver for NVIDIA Tegra SoCs

Robert Morell (1):
USB: ehci: tegra: Align DMA transfers to 32 bytes

 arch/arm/mach-tegra/Kconfig                |    3 +
 arch/arm/mach-tegra/Makefile               |    1 +
 arch/arm/mach-tegra/include/mach/usb_phy.h |   86 +++
 arch/arm/mach-tegra/usb_phy.c              |  795 ++++++++++++++++++++++++++++
 drivers/usb/host/Kconfig                   |    8 +
 drivers/usb/host/ehci-hcd.c                |    5 +
 drivers/usb/host/ehci-tegra.c              |  716 +++++++++++++++++++++++++
 drivers/usb/otg/Kconfig                    |    7 +
 drivers/usb/otg/Makefile                   |    1 +
 drivers/usb/otg/ulpi_viewport.c            |   81 +++
 include/linux/tegra_usb.h                  |   35 ++
 include/linux/usb/ulpi.h                   |    5 +
 12 files changed, 1743 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/usb_phy.h
 create mode 100644 arch/arm/mach-tegra/usb_phy.c
 create mode 100644 drivers/usb/host/ehci-tegra.c
 create mode 100644 drivers/usb/otg/ulpi_viewport.c
 create mode 100644 include/linux/tegra_usb.h

--
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1297980904-23466-1-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org

#2 lore raw

PATCH v3 1/4 usb: otg: Add ulpi viewport access ops

Add generic access ops for controllers with a ulpi viewport register (e.g. Chipidea/ARC based controllers).

---
 drivers/usb/otg/Kconfig         |    7 +++
 drivers/usb/otg/Makefile        |    1 +
 drivers/usb/otg/ulpi_viewport.c |   81 +++++++++++++++++++++++++++++++++++++++
 include/linux/usb/ulpi.h        |    5 ++
 4 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/ulpi_viewport.c
drivers/usb/otg/Kconfig +7 -0
index 9ffc823..02952c4 100644
@@ -49,6 +49,13 @@ config USB_ULPI
 	  Enable this to support ULPI connected USB OTG transceivers which
 	  are likely found on embedded boards.
 
+config USB_ULPI_VIEWPORT
+	bool "ULPI Viewport Access Operations"
+	depends on USB_ULPI
+	help
+	  Provides read/write operations to the ULPI phy register set for
+	  controllers with a viewport register (e.g. Chipidea/ARC controllers).
+
 config TWL4030_USB
 	tristate "TWL4030 USB Transceiver Driver"
 	depends on TWL4030_CORE && REGULATOR_TWL4030
drivers/usb/otg/Makefile +1 -0
index a520e71..44581a9 100644
@@ -16,5 +16,6 @@ obj-$(CONFIG_TWL6030_USB)	+= twl6030-usb.o
 obj-$(CONFIG_USB_LANGWELL_OTG)	+= langwell_otg.o
 obj-$(CONFIG_NOP_USB_XCEIV)	+= nop-usb-xceiv.o
 obj-$(CONFIG_USB_ULPI)		+= ulpi.o
+obj-$(CONFIG_USB_ULPI_VIEWPORT)	+= ulpi_viewport.o
 obj-$(CONFIG_USB_MSM_OTG_72K)	+= msm72k_otg.o
 obj-$(CONFIG_AB8500_USB)	+= ab8500-usb.o
drivers/usb/otg/ulpi_viewport.c new file +81 -0

81 lines not on this page · raw message

include/linux/usb/ulpi.h +5 -0
index 82b1507..9595796 100644
@@ -184,4 +184,9 @@
 struct otg_transceiver *otg_ulpi_create(struct otg_io_access_ops *ops,
 					unsigned int flags);
 
+#ifdef CONFIG_USB_ULPI_VIEWPORT
+/* access ops for controllers with a viewport register */
+extern struct otg_io_access_ops ulpi_viewport_access_ops;
+#endif
+
 #endif /* __LINUX_USB_ULPI_H */
Signature · 6 lines
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1297980904-23466-2-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org

#4 lore raw

Re: [PATCH v3 1/4] usb: otg: Add ulpi viewport access ops

Quoted 17 lines · Benoit Goby

Add generic access ops for controllers with a ulpi viewport register (e.g. Chipidea/ARC based controllers).

---
 drivers/usb/otg/Kconfig         |    7 +++
 drivers/usb/otg/Makefile        |    1 +
 drivers/usb/otg/ulpi_viewport.c |   81 +++++++++++++++++++++++++++++++++++++++
 include/linux/usb/ulpi.h        |    5 ++
 4 files changed, 94 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/otg/ulpi_viewport.c
drivers/usb/otg/Kconfig +0 -0
index 9ffc823..02952c4 100644

drivers/usb/otg/Kconfig config USB_ULPI · line 57

Quoted 9 lines
drivers/usb/otg/Kconfig +6 -0
@@ -49,6 +49,13 @@ config USB_ULPI
 	  Enable this to support ULPI connected USB OTG transceivers which
 	  are likely found on embedded boards.
 
+config USB_ULPI_VIEWPORT
+	bool "ULPI Viewport Access Operations"
+	depends on USB_ULPI
+	help
+	  Provides read/write operations to the ULPI phy register set for
+	  controllers with a viewport register (e.g. Chipidea/ARC controllers).

Why would this be a Kconfig option? Why not just always have this option enabled if USB_ULPI is enabled? How will someone know to enable this or not?

And you aren't allowing this to be built as a module, which suggests that you really want this always present, right?

drivers/usb/otg/Kconfig config USB_ULPI · line 60

Quoted 3 lines
drivers/usb/otg/Kconfig +3 -0
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.

Don't include this paragraph unless you promise to keep up to date with the movements of the FSF's office for the next 40+ years. Just drop it, it's pointless and needless.

Quoted 7 lines
drivers/usb/otg/Kconfig +7 -0
+ */
+
+#include <linux/kernel.h>
+#include <linux/usb.h>
+#include <linux/io.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>

drivers/usb/otg/Kconfig config USB_ULPI

Quoted 10 lines
drivers/usb/otg/Kconfig +10 -0
+
+#define ULPI_VIEW_WAKEUP	(1 << 31)
+#define ULPI_VIEW_RUN		(1 << 30)
+#define ULPI_VIEW_WRITE		(1 << 29)
+#define ULPI_VIEW_READ		(0 << 29)
+#define ULPI_VIEW_ADDR(x)	(((x) & 0xff) << 16)
+#define ULPI_VIEW_DATA_READ(x)	(((x) >> 8) & 0xff)
+#define ULPI_VIEW_DATA_WRITE(x)	(((x) & 0xff) << 0)
+
+static int ulpi_viewport_wait(void __iomem *view, u32 mask, u32 res)

What is "res"?

drivers/usb/otg/Kconfig

Quoted 2 lines
drivers/usb/otg/Kconfig +2 -0
+{
+	unsigned long timeout = 2000;

That's not a timeout, it's a loop count, don't lie.

drivers/usb/otg/Kconfig

Quoted 5 lines
drivers/usb/otg/Kconfig +5 -0
+
+	while (timeout--) {
+		if ((readl(view) & mask) == res)
+			return 0;
+		cpu_relax();

Ick, if you get a faster processor, you just burned through this loop faster. Make it a "real" timeout based on a time value, not just "how fast can my processor do nothing". Otherwise this code will break in 2 years and you will not know why.

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): [email protected]

#6 lore raw

Re: [PATCH v3 1/4] usb: otg: Add ulpi viewport access ops

Quoted 9 lines · Greg KH
Quoted 8 lines · Benoit Goby
drivers/usb/otg/Kconfig +0 -0
index 9ffc823..02952c4 100644
@@ -49,6 +49,13 @@ config USB_ULPI

        Enable this to support ULPI connected USB OTG transceivers which are likely found on embedded boards.

Quoted 11 lines
Quoted 6 lines

+config USB_ULPI_VIEWPORT
+     bool "ULPI Viewport Access Operations"
+     depends on USB_ULPI
+     help
+       Provides read/write operations to the ULPI phy register set for
+       controllers with a viewport register (e.g. Chipidea/ARC controllers).

Why would this be a Kconfig option?  Why not just always have this option enabled if USB_ULPI is enabled?  How will someone know to enable this or not?

This is not part of the ulpi spec. You may have a ulpi phy but have a controller that does not have a viewport register. I will remove the Kconfig option. Drivers that depend on it should select it, it does not need to be user configurable.

Thanks,
Benoit
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#7 lore raw

PATCH v3 2/4 ARM: tegra: Add support for Tegra USB PHYs

In reply to a message not in the archive

Interface used by Tegra's gadget driver and ehci driver to power on and configure the USB PHYs.

---
 arch/arm/mach-tegra/Kconfig                |    3 +
 arch/arm/mach-tegra/Makefile               |    1 +
 arch/arm/mach-tegra/include/mach/usb_phy.h |   86 +++
 arch/arm/mach-tegra/usb_phy.c              |  795 ++++++++++++++++++++++++++++
 4 files changed, 885 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-tegra/include/mach/usb_phy.h
 create mode 100644 arch/arm/mach-tegra/usb_phy.c
arch/arm/mach-tegra/Kconfig +3 -0
index acd9552..394b3c7 100644
@@ -10,6 +10,9 @@ config ARCH_TEGRA_2x_SOC
 	select CPU_V7
 	select ARM_GIC
 	select ARCH_REQUIRE_GPIOLIB
+	select USB_ARCH_HAS_EHCI if USB_SUPPORT
+	select USB_ULPI if USB_SUPPORT
+	select USB_ULPI_VIEWPORT if USB_SUPPORT
 	help
 	  Support for NVIDIA Tegra AP20 and T20 processors, based on the
 	  ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
arch/arm/mach-tegra/Makefile +1 -0
index cdbc68e..38b66a8 100644
@@ -15,6 +15,7 @@ obj-$(CONFIG_HOTPLUG_CPU)               += hotplug.o
 obj-$(CONFIG_TEGRA_SYSTEM_DMA)		+= dma.o
 obj-$(CONFIG_CPU_FREQ)                  += cpu-tegra.o
 obj-$(CONFIG_TEGRA_PCI)			+= pcie.o
+obj-$(CONFIG_USB_SUPPORT)		+= usb_phy.o
 
 obj-${CONFIG_MACH_HARMONY}              += board-harmony.o
 obj-${CONFIG_MACH_HARMONY}              += board-harmony-pinmux.o
arch/arm/mach-tegra/include/mach/usb_phy.h new file +86 -0

86 lines not on this page · raw message

arch/arm/mach-tegra/usb_phy.c new file +795 -0

795 lines not on this page · raw message

Signature · 6 lines
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
#8 lore raw

PATCH v3 3/4 usb: host: Add EHCI driver for NVIDIA Tegra SoCs

In reply to a message not in the archive
---
 drivers/usb/host/Kconfig      |    8 +
 drivers/usb/host/ehci-hcd.c   |    5 +
 drivers/usb/host/ehci-tegra.c |  626 +++++++++++++++++++++++++++++++++++++++++
 include/linux/tegra_usb.h     |   35 +++
 4 files changed, 674 insertions(+), 0 deletions(-)
 create mode 100644 drivers/usb/host/ehci-tegra.c
 create mode 100644 include/linux/tegra_usb.h
drivers/usb/host/Kconfig +8 -0
index 0e6afa2..f93133c 100644
@@ -154,6 +154,14 @@ config USB_EHCI_MSM
 	  This driver is not supported on boards like trout which
 	  has an external PHY.
 
+config USB_EHCI_TEGRA
+       boolean "NVIDIA Tegra HCD support"
+       depends on USB_EHCI_HCD && ARCH_TEGRA
+       select USB_EHCI_ROOT_HUB_TT
+       help
+         This driver enables support for the internal USB Host Controller
+         found in NVIDIA Tegra SoCs. The Tegra controller is EHCI compliant.
+
 config USB_EHCI_HCD_PPC_OF
 	bool "EHCI support for PPC USB controller on OF platform bus"
 	depends on USB_EHCI_HCD && PPC_OF
drivers/usb/host/ehci-hcd.c +5 -0
index 4c77a81..c9eb96d 100644
@@ -1259,6 +1259,11 @@ MODULE_LICENSE ("GPL");
 #define PLATFORM_DRIVER		ehci_msm_driver
 #endif
 
+#ifdef CONFIG_USB_EHCI_TEGRA
+#include "ehci-tegra.c"
+#define PLATFORM_DRIVER		tegra_ehci_driver
+#endif
+
 #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
     !defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
     !defined(XILINX_OF_PLATFORM_DRIVER)
drivers/usb/host/ehci-tegra.c new file +626 -0

626 lines not on this page · raw message

include/linux/tegra_usb.h new file +35 -0
new file mode 100644
index 0000000..2947ed2
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+#ifndef _TEGRA_USB_H_
+#define _TEGRA_USB_H_
+
+enum tegra_usb_operating_modes {
+	TEGRA_USB_DEVICE,
+	TEGRA_USB_HOST,
+	TEGRA_USB_OTG,
+};
+
+struct tegra_ehci_platform_data {
+	enum tegra_usb_operating_modes operating_mode;
+	/* power down the phy on bus suspend */
+	int power_down_on_bus_suspend;
+	void *phy_config;
+};
+
+#endif /* _TEGRA_USB_H_ */
Signature · 6 lines
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

A message that is not in the archive (sent off-list or not yet received): 1297980904-23466-4-git-send-email-benoit-z5hGa2qSFaRBDgjK7y7TUQ@public.gmane.org

#10 lore raw

Re: [PATCH v3 3/4] usb: host: Add EHCI driver for NVIDIA Tegra SoCs

Quoted 1 line · Benoit Goby

No changelog comment saying what this is, what it does, or even why one would want this?

Come on, you can do better, please redo. At the very least, use the same wording you have in your Kconfig entry, but to do that would be just phoning it in...

thanks,

greg k-h
--
To unsubscribe from this list: send the line "unsubscribe linux-tegra" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#11 lore raw

PATCH v3 4/4 USB: ehci: tegra: Align DMA transfers to 32 bytes

In reply to a message not in the archive

From: Robert Morell <[email protected]>

The Tegra2 USB controller doesn't properly deal with misaligned DMA buffers, causing corruption. This is especially prevalent with USB network adapters, where skbuff alignment is often in the middle of a 4-byte dword.

To avoid this, allocate a temporary buffer for the DMA if the provided buffer isn't sufficiently aligned.

---
 drivers/usb/host/ehci-tegra.c |   90 +++++++++++++++++++++++++++++++++++++++++
 1 files changed, 90 insertions(+), 0 deletions(-)
drivers/usb/host/ehci-tegra.c +90 -0
index 5c5ee91..c64d629 100644
@@ -28,6 +28,8 @@
 
 #define TEGRA_USB_PORTSC1_PTC(x)	(((x) & 0xf) << 16)
 
+#define TEGRA_USB_DMA_ALIGN 32
+
 struct tegra_ehci_hcd {
 	struct ehci_hcd *ehci;
 	struct tegra_usb_phy *phy;
@@ -388,6 +390,92 @@ static int tegra_ehci_bus_resume(struct usb_hcd *hcd)
 }
 #endif
 
+struct temp_buffer {
+	void *kmalloc_ptr;
+	void *old_xfer_buffer;
+	u8 data[0];
+};
+
+static void free_temp_buffer(struct urb *urb)
+{
+	enum dma_data_direction dir;
+	struct temp_buffer *temp;
+
+	if (!(urb->transfer_flags & URB_ALIGNED_TEMP_BUFFER))
+		return;
+
+	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+	temp = container_of(urb->transfer_buffer, struct temp_buffer,
+			    data);
+
+	if (dir == DMA_FROM_DEVICE)
+		memcpy(temp->old_xfer_buffer, temp->data,
+		       urb->transfer_buffer_length);
+	urb->transfer_buffer = temp->old_xfer_buffer;
+	kfree(temp->kmalloc_ptr);
+
+	urb->transfer_flags &= ~URB_ALIGNED_TEMP_BUFFER;
+}
+
+static int alloc_temp_buffer(struct urb *urb, gfp_t mem_flags)
+{
+	enum dma_data_direction dir;
+	struct temp_buffer *temp, *kmalloc_ptr;
+	size_t kmalloc_size;
+
+	if (urb->num_sgs || urb->sg ||
+	    urb->transfer_buffer_length == 0 ||
+	    !((uintptr_t)urb->transfer_buffer & (TEGRA_USB_DMA_ALIGN - 1)))
+		return 0;
+
+	dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE;
+
+	/* Allocate a buffer with enough padding for alignment */
+	kmalloc_size = urb->transfer_buffer_length +
+		sizeof(struct temp_buffer) + TEGRA_USB_DMA_ALIGN - 1;
+
+	kmalloc_ptr = kmalloc(kmalloc_size, mem_flags);
+	if (!kmalloc_ptr)
+		return -ENOMEM;
+
+	/* Position our struct temp_buffer such that data is aligned */
+	temp = PTR_ALIGN(kmalloc_ptr + 1, TEGRA_USB_DMA_ALIGN) - 1;
+
+	temp->kmalloc_ptr = kmalloc_ptr;
+	temp->old_xfer_buffer = urb->transfer_buffer;
+	if (dir == DMA_TO_DEVICE)
+		memcpy(temp->data, urb->transfer_buffer,
+		       urb->transfer_buffer_length);
+	urb->transfer_buffer = temp->data;
+
+	urb->transfer_flags |= URB_ALIGNED_TEMP_BUFFER;
+
+	return 0;
+}
+
+static int tegra_ehci_map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb,
+				      gfp_t mem_flags)
+{
+	int ret;
+
+	ret = alloc_temp_buffer(urb, mem_flags);
+	if (ret)
+		return ret;
+
+	ret = usb_hcd_map_urb_for_dma(hcd, urb, mem_flags);
+	if (ret)
+		free_temp_buffer(urb);
+
+	return ret;
+}
+
+static void tegra_ehci_unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb)
+{
+	usb_hcd_unmap_urb_for_dma(hcd, urb);
+	free_temp_buffer(urb);
+}
+
 static const struct hc_driver tegra_ehci_hc_driver = {
 	.description		= hcd_name,
 	.product_desc		= "Tegra EHCI Host Controller",
@@ -403,6 +491,8 @@ static const struct hc_driver tegra_ehci_hc_driver = {
 	.shutdown		= tegra_ehci_shutdown,
 	.urb_enqueue		= ehci_urb_enqueue,
 	.urb_dequeue		= ehci_urb_dequeue,
+	.map_urb_for_dma	= tegra_ehci_map_urb_for_dma,
+	.unmap_urb_for_dma	= tegra_ehci_unmap_urb_for_dma,
 	.endpoint_disable	= ehci_endpoint_disable,
 	.endpoint_reset		= ehci_endpoint_reset,
 	.get_frame_number	= ehci_get_frame,
Signature · 6 lines
1.7.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html