From: Dinh Nguyen <[email protected]>
This patch is part of enabling USB for Freescale MX51 Babbage HW. This
patch updates the iomux pins for USB, and gpio line for reset the
USB hub on the MX51 Babbage HW.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/plat-mxc/include/mach/iomux-mx51.h | 33 ++++++++++++++++----------
1 files changed, 20 insertions(+), 13 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
index b4f975e..80528cc 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2009-2010 Amit Kucheria <[email protected]>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
@@ -37,6 +38,11 @@ typedef enum iomux_config {
PAD_CTL_SRE_FAST)
#define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
PAD_CTL_SRE_FAST)
+#define MX51_USBH1_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
+ PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_GPIO_PAD_CTRL (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
+ PAD_CTL_SRE_FAST)
/*
* The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
@@ -208,18 +214,19 @@ typedef enum iomux_config {
#define MX51_PAD_KEY_COL3__KEY_COL3 IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_KEY_COL4__KEY_COL4 IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_KEY_COL5__KEY_COL5 IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_25__USBH1_CLK IOMUX_PAD(0x678, 0x278, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_26__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_27__USBH1_STP IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_28__USBH1_NXT IOMUX_PAD(0x684, 0x284, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_11__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_12__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_13__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_14__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_15__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_16__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_17__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_18__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DIR__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__USBH1_STP IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__GPIO_1_27 IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_GPIO, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_NXT__USBH1_NXT IOMUX_PAD(0x684, 0x284, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_GPIO_3_0__DI1_PIN11 IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_GPIO_3_1__DI1_PIN12 IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_GPIO_3_2__DI1_PIN13 IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
@@ -299,7 +306,7 @@ typedef enum iomux_config {
#define MX51_PAD_GPIO_1_4__GPIO1_4 IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_GPIO_1_5__GPIO1_5 IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
#define MX51_PAD_GPIO_1_6__GPIO1_6 IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_7__GPIO1_7 IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
#define MX51_PAD_GPIO_1_8__GPIO1_8 IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, \
(PAD_CTL_SRE_SLOW | PAD_CTL_DSE_MED | PAD_CTL_PUS_100K_UP | PAD_CTL_HYS))
#define MX51_PAD_GPIO_1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
Update mx51_defconfig to include USB EHCI by default.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/configs/mx51_defconfig | 17 ++++++++++++++++-
1 files changed, 16 insertions(+), 1 deletions(-)
diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig
index c88e952..a708fd6 100644
--- a/arch/arm/configs/mx51_defconfig
+++ b/arch/arm/configs/mx51_defconfig
@@ -809,7 +809,22 @@ CONFIG_SSB_POSSIBLE=y
CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MXC=y
+
+
CONFIG_MMC=y
# CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
This patch adds new register bit defines for the USB HW on Freescale
SoCs.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/plat-mxc/include/mach/mxc_ehci.h | 48 +++++++++++++++++++++++++++++
1 files changed, 48 insertions(+), 0 deletions(-)
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
index 4b9b836..c5b1e7b 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -1,6 +1,30 @@
#ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H
#define __INCLUDE_ASM_ARCH_MXC_EHCI_H
+#define USBOTG_OFFSET 0
+#define USBH1_OFFSET 0x200
+#define USBH2_OFFSET 0x400
+#define USBH3_OFFSET 0x600
+#define USBOTHER_REGS_OFFSET 0x800
+
+#define USBCMD_OFFSET 0x140
+
+#define ULPI_VIEWPORT_OFFSET 0x170
+#define PORTSC_OFFSET 0x184
+#define USBMODE_OFFSET 0x1a8
+#define USBMODE_CM_HOST 3
+
+#define USBCTRL_OFFSET 0
+#define USB_PHY_CTR_FUNC_OFFSET 0x8
+#define USB_PHY_CTR_FUNC2_OFFSET 0xc
+#define USB_CTRL_1_OFFSET 0x10
+
+
+/* USBCMD */
+#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
+#define UCMD_RESET (1 << 1) /* controller reset */
+#define UCMD_ITC_NO_THRESHOLD (~(0xff << 16)) /* Interrupt Threshold Control */
+
/* values for portsc field */
#define MXC_EHCI_PHY_LOW_POWER_SUSPEND (1 << 23)
#define MXC_EHCI_FORCE_FS (1 << 24)
@@ -26,6 +50,30 @@
#define MXC_EHCI_IPPUE_DOWN (1 << 8)
#define MXC_EHCI_IPPUE_UP (1 << 9)
+/* USB_CTRL */
+#define UCTRL_OUIE (1 << 28) /* OTG ULPI intr enable */
+#define UCTRL_OWIE (1 << 27) /* OTG wakeup intr enable */
+#define UCTRL_OBPVAL_RXDP (1 << 26) /* OTG RxDp status in bypass mode */
+#define UCTRL_OBPVAL_RXDM (1 << 25) /* OTG RxDm status in bypass mode */
+#define UCTRL_OPM (1 << 24) /* OTG power mask */
+#define UCTRL_H1UIE (1 << 12) /* Host1 ULPI interrupt enable */
+#define UCTRL_H1WIE (1 << 11) /* HOST1 wakeup intr enable */
+#define UCTRL_H1PM (1 << 8) /* HOST1 power mask */
+
+/* USB_PHY_CTRL_FUNC */
+#define USB_UTMI_PHYCTRL_OC_DIS (1 << 8) /* OTG Disable Overcurrent Event */
+#define USB_UH1_OC_DIS (1 << 5) /* UH1 Disable Overcurrent Event */
+
+/* USB_CTRL_1 */
+#define USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+#define USB_CTRL_UH2_EXT_CLK_EN (1 << 26)
+
+/* USB_PHY_CTRL_FUNC2*/
+#define USB_UTMI_PHYCTRL2_PLLDIV_MASK 0x3
+#define USB_UTMI_PHYCTRL2_PLLDIV_SHIFT 0
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_MASK 0x3
+#define USB_UTMI_PHYCTRL2_HSDEVSEL_SHIFT 19
+
struct mxc_usbh_platform_data {
int (*init)(struct platform_device *pdev);
int (*exit)(struct platform_device *pdev);
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
This patch is part of enabling USB for Freescale MX51 Babbage HW. This
patch adds device structures for USB Host1 and OTG port, and adds
clocking information for USB HW.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/mach-mx5/clock-mx51.c | 8 ++++++
arch/arm/mach-mx5/devices.c | 49 ++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-mx5/devices.h | 2 +
3 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
index 1ee6ce4..1fe40e1 100644
--- a/arch/arm/mach-mx5/clock-mx51.c
+++ b/arch/arm/mach-mx5/clock-mx51.c
@@ -762,6 +762,10 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
NULL, NULL, &ipg_clk, NULL);
+/* USB */
+DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET,
+ NULL, NULL, &pll3_sw_clk, NULL);
+
/* FEC */
DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
NULL, NULL, &ipg_clk, NULL);
@@ -779,6 +783,10 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
+ _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk)
};
static void clk_tree_init(void)
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
index 5070ae1..4b456d5 100644
--- a/arch/arm/mach-mx5/devices.c
+++ b/arch/arm/mach-mx5/devices.c
@@ -12,6 +12,7 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/dma-mapping.h>
#include <mach/hardware.h>
#include <mach/imx-uart.h>
#include <mach/irqs.h>
@@ -92,6 +93,54 @@ struct platform_device mxc_fec_device = {
.resource = mxc_fec_resources,
};
+static u64 usb_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource usbotg_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR,
+ .end = MX51_OTG_BASE_ADDR + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbdr_host_device = {
+ .name = "mxc-ehci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(usbotg_resources),
+ .resource = usbotg_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource usbh1_resources[] = {
+ {
+ .start = MX51_OTG_BASE_ADDR + 0x200,
+ .end = MX51_OTG_BASE_ADDR + 0x200 + 0x1ff,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MX51_MXC_INT_USB_H1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device mxc_usbh1_device = {
+ .name = "mxc-ehci",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(usbh1_resources),
+ .resource = usbh1_resources,
+ .dev = {
+ .dma_mask = &usb_dma_mask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
static struct mxc_gpio_port mxc_gpio_ports[] = {
{
.chip.label = "gpio-0",
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
index f339ab8..6497764 100644
--- a/arch/arm/mach-mx5/devices.h
+++ b/arch/arm/mach-mx5/devices.h
@@ -2,3 +2,5 @@ extern struct platform_device mxc_uart_device0;
extern struct platform_device mxc_uart_device1;
extern struct platform_device mxc_uart_device2;
extern struct platform_device mxc_fec_device;
+extern struct platform_device mxc_usbdr_host_device;
+extern struct platform_device mxc_usbh1_device;
\ No newline at end of file
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
-Stops and resets USB HW
-Sets some specific PHY settings
-Stop and restart the USB HW.
Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/plat-mxc/ehci.c | 128 ++++++++++++++++++++++++++++-
arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
2 files changed, 127 insertions(+), 3 deletions(-)
diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
index cb0b638..35ff1c1 100644
--- a/arch/arm/plat-mxc/ehci.c
+++ b/arch/arm/plat-mxc/ehci.c
@@ -1,5 +1,6 @@
/*
* Copyright (c) 2009 Daniel Mack <[email protected]>
+ * Copyright (C) 2010 Freescale Semiconductor, 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
@@ -18,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/delay.h>
#include <mach/hardware.h>
#include <mach/mxc_ehci.h>
@@ -50,9 +52,14 @@
#define MX35_H1_TLL_BIT (1 << 5)
#define MX35_H1_USBTE_BIT (1 << 4)
-int mxc_set_usbcontrol(int port, unsigned int flags)
+int mxc_intialize_usb_hw(int port, unsigned int flags)
{
unsigned int v;
+ void __iomem *usb_base;
+ u32 usbotg_base;
+ u32 usbother_base;
+ int timeout;
+ int ret = 0;
#ifdef CONFIG_ARCH_MX3
if (cpu_is_mx31()) {
v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
@@ -186,9 +193,126 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
return 0;
}
#endif /* CONFIG_MACH_MX27 */
+#ifdef CONFIG_ARCH_MX51
+ if (cpu_is_mx51()) {
+ usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+
+ switch (port) {
+ case 0: /* OTG port */
+ usbotg_base = (u32)usb_base + USBOTG_OFFSET;
+ break;
+ case 1: /* Host 1 port */
+ usbotg_base = (u32)usb_base + USBH1_OFFSET;
+ break;
+ default:
+ printk(KERN_ERR"%s no such port %d\n", __func__, port);
+ ret = -ENOENT;
+ goto error;
+ }
+ usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
+
+ /* Stop then Reset */
+ v = __raw_readl(usbotg_base + USBCMD_OFFSET);
+ v &= ~UCMD_RUN_STOP;
+ __raw_writel(v, usbotg_base + USBCMD_OFFSET);
+ timeout = 0x100000;
+ while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RUN_STOP)
+ cpu_relax();
+ if (!timeout) {
+ printk(KERN_ERR "%s could not stop usb hardware\n", __func__);
+ ret = -ETIMEDOUT;
+ goto error;
+ }
+
+ v = __raw_readl(usbotg_base + USBCMD_OFFSET);
+ v |= UCMD_RESET;
+ __raw_writel(v, usbotg_base + USBCMD_OFFSET);
+ timeout = 0x100000;
+ while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RESET)
+ cpu_relax();
+ if (!timeout) {
+ printk(KERN_ERR "%s could not reset usb hardware\n", __func__);
+ ret = -ETIMEDOUT;
+ goto error;
+ }
+
+ switch (port) {
+ case 0: /*OTG port */
+ v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC_OFFSET);
+ v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used */
+ __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC_OFFSET);
+
+ v = __raw_readl(usbother_base + USBCTRL_OFFSET);
+ v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG wakeup/power mask disable */
+ __raw_writel(v, usbother_base + USBCTRL_OFFSET);
+
+ /* Set the PHY clock to 19.2MHz */
+ v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
+ v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
+ v |= 0x01;
+ __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
+ break;
+ case 1: /* Host 1 */
+ /*Host ULPI */
+ v = __raw_readl(usbother_base + USB_CTRL_1_OFFSET);
+ __raw_writel(v | USB_CTRL_UH1_EXT_CLK_EN, usbother_base + USB_CTRL_1_OFFSET);
+
+ v = __raw_readl(usbother_base + USBCTRL_OFFSET);
+ v &= ~(UCTRL_H1WIE | UCTRL_H1UIE);/* HOST1 wakeup/ULPI intr disable */
+ v |= UCTRL_H1PM; /* HOST1 power mask */
+ __raw_writel(v, usbother_base + USBCTRL_OFFSET);
+
+ v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC_OFFSET);
+ v |= USB_UH1_OC_DIS; /* OC is not used */
+ __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC_OFFSET);
+
+ v = __raw_readl(usbotg_base + USBCMD_OFFSET);
+ /* Interrupt Threshold Control:Immediate (no threshold) */
+ v &= UCMD_ITC_NO_THRESHOLD;
+ __raw_writel(v, usbotg_base + USBCMD_OFFSET);
+ break;
+ }
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ /* Stop then Reset */
+ v = __raw_readl(usbotg_base + USBCMD_OFFSET);
+ v &= ~UCMD_RUN_STOP;
+ __raw_writel(v, usbotg_base + USBCMD_OFFSET);
+ timeout = 0x100000;
+ while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RUN_STOP)
+ cpu_relax();
+ if (!timeout) {
+ printk(KERN_ERR "%s could not stop usb hardware\n", __func__);
+ ret = -ETIMEDOUT;
+ goto error;
+ }
+
+ v = __raw_readl(usbotg_base + USBCMD_OFFSET);
+ v |= UCMD_RESET;
+ __raw_writel(v, usbotg_base + USBCMD_OFFSET);
+ timeout = 0x100000;
+ while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RESET)
+ cpu_relax();
+ if (!timeout) {
+ printk(KERN_ERR "%s could not reset usb hardware\n", __func__);
+ ret = -ETIMEDOUT;
+ goto error;
+ }
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+error:
+ iounmap(usb_base);
+ return ret;
+ }
+#endif
printk(KERN_WARNING
"%s() unable to setup USBCONTROL for this CPU\n", __func__);
return -EINVAL;
}
-EXPORT_SYMBOL(mxc_set_usbcontrol);
+EXPORT_SYMBOL(mxc_intialize_usb_hw);
diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
index c5b1e7b..e61feac 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
@@ -83,7 +83,7 @@ struct mxc_usbh_platform_data {
struct otg_transceiver *otg;
};
-int mxc_set_usbcontrol(int port, unsigned int flags);
+int mxc_intialize_usb_hw(int port, unsigned int flags);
#endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
This patch enables USB host functionality for Host1 and OTG port on
Freescale MX51 Babbage HW. This patch contains the board specific
HW initialization of the USB HW.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
arch/arm/mach-mx5/board-mx51_babbage.c | 81 ++++++++++++++++++++++++++++++++
1 files changed, 81 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
index ee67a71..617f4e2 100644
--- a/arch/arm/mach-mx5/board-mx51_babbage.c
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -12,11 +12,14 @@
#include <linux/init.h>
#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/imx-uart.h>
#include <mach/iomux-mx51.h>
+#include <mach/mxc_ehci.h>
#include <asm/irq.h>
#include <asm/setup.h>
@@ -26,6 +29,9 @@
#include "devices.h"
+#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */
+#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */
+
static struct platform_device *devices[] __initdata = {
&mxc_fec_device,
};
@@ -46,6 +52,22 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_EIM_D26__UART3_TXD,
MX51_PAD_EIM_D27__UART3_RTS,
MX51_PAD_EIM_D24__UART3_CTS,
+
+ /* USB HOST1 */
+ MX51_PAD_USBH1_CLK__USBH1_CLK,
+ MX51_PAD_USBH1_DIR__USBH1_DIR,
+ MX51_PAD_USBH1_NXT__USBH1_NXT,
+ MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+ MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+ MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+ MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+ MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+ MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+ MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+ MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+
+ /* USB HUB reset line*/
+ MX51_PAD_GPIO_1_7__GPIO1_7,
};
/* Serial ports */
@@ -66,15 +88,74 @@ static inline void mxc_init_imx_uart(void)
}
#endif /* SERIAL_IMX */
+static int gpio_usbh1_active(void)
+{
+ struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27;
+ int ret;
+
+ /* Set USBH1_STP to GPIO and toggle it */
+ mxc_iomux_v3_setup_pad(&usbh1stp_gpio);
+ ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp");
+
+ if (ret) {
+ pr_debug("failed to get MX51_PAD_USBH1_STP__GPIO_1_27: %d\n", ret);
+ return ret;
+ }
+ gpio_direction_output(BABBAGE_USBH1_STP, 0);
+ gpio_set_value(BABBAGE_USBH1_STP, 1);
+ msleep(100);
+ gpio_free(BABBAGE_USBH1_STP);
+ return 0;
+}
+
+static inline void babbage_usbhub_reset(void)
+{
+ int ret;
+
+ /* Bring USB hub out of reset */
+ ret = gpio_request(BABBAGE_USB_HUB_RESET, "GPIO1_7");
+ if (ret) {
+ printk(KERN_ERR"failed to get GPIO_USB_HUB_RESET: %d\n", ret);
+ return;
+ }
+ gpio_direction_output(BABBAGE_USB_HUB_RESET, 0);
+
+ /* USB HUB RESET - De-assert USB HUB RESET_N */
+ msleep(1);
+ gpio_set_value(BABBAGE_USB_HUB_RESET, 0);
+ msleep(1);
+ gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+ .portsc = MXC_EHCI_UTMI_16BIT,
+ .flags = MXC_EHCI_INTERNAL_PHY,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+ .portsc = MXC_EHCI_MODE_ULPI,
+ .flags = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
/*
* Board specific initialization.
*/
static void __init mxc_board_init(void)
{
+ struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+
mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
ARRAY_SIZE(mx51babbage_pads));
mxc_init_imx_uart();
platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+
+ gpio_usbh1_active();
+ mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+ /* setback USBH1_STP to be function */
+ mxc_iomux_v3_setup_pad(&usbh1stp);
+ babbage_usbhub_reset();
}
static void __init mx51_babbage_timer_init(void)
--
1.6.0.4
From: Dinh Nguyen <[email protected]>
The placing of the function needs to be before setting the USBMODE
register to host, since a reset and start is done in
mxc_initialize_usb_hw.
This patch applies to 2.6.34-rc4.
Signed-off-by: Dinh Nguyen <[email protected]>
---
drivers/usb/host/ehci-mxc.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c
index ead59f4..7091b20 100644
--- a/drivers/usb/host/ehci-mxc.c
+++ b/drivers/usb/host/ehci-mxc.c
@@ -191,6 +191,11 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
clk_enable(priv->ahbclk);
}
+ /* setup specific usb hw */
+ ret = mxc_intialize_usb_hw(pdev->id, pdata->flags);
+ if (ret < 0)
+ goto err_init;
+
/* set USBMODE to host mode */
temp = readl(hcd->regs + USBMODE_OFFSET);
writel(temp | USBMODE_CM_HOST, hcd->regs + USBMODE_OFFSET);
@@ -199,11 +204,6 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
writel(pdata->portsc, hcd->regs + PORTSC_OFFSET);
mdelay(10);
- /* setup USBCONTROL. */
- ret = mxc_set_usbcontrol(pdev->id, pdata->flags);
- if (ret < 0)
- goto err_init;
-
/* Initialize the transceiver */
if (pdata->otg) {
pdata->otg->io_priv = hcd->regs + ULPI_VIEWPORT_OFFSET;
--
1.6.0.4
On Fri, Apr 16, 2010 at 02:16:09PM -0500, [email protected] wrote:
> This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
> -Stops and resets USB HW
> -Sets some specific PHY settings
> -Stop and restart the USB HW.
> Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
>
> This patch applies to 2.6.34-rc4.
Yes, the whole series looks _much_ better now, thanks!
Some minor things below.
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> arch/arm/plat-mxc/ehci.c | 128 ++++++++++++++++++++++++++++-
> arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
> 2 files changed, 127 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
> index cb0b638..35ff1c1 100644
> --- a/arch/arm/plat-mxc/ehci.c
> +++ b/arch/arm/plat-mxc/ehci.c
> @@ -1,5 +1,6 @@
> /*
> * Copyright (c) 2009 Daniel Mack <[email protected]>
> + * Copyright (C) 2010 Freescale Semiconductor, 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
> @@ -18,6 +19,7 @@
>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/delay.h>
>
> #include <mach/hardware.h>
> #include <mach/mxc_ehci.h>
> @@ -50,9 +52,14 @@
> #define MX35_H1_TLL_BIT (1 << 5)
> #define MX35_H1_USBTE_BIT (1 << 4)
>
> -int mxc_set_usbcontrol(int port, unsigned int flags)
> +int mxc_intialize_usb_hw(int port, unsigned int flags)
This patch and the next one should be merged into one. The reason is
that you rename a function here and the next patch follows that change.
Especially when bisecting, this can lead to uncompilable checkouts of
the tree when stopping in the middle.
> {
> unsigned int v;
> + void __iomem *usb_base;
> + u32 usbotg_base;
> + u32 usbother_base;
> + int timeout;
> + int ret = 0;
As you only use these variable in the MX51 case, ...
> #ifdef CONFIG_ARCH_MX3
> if (cpu_is_mx31()) {
> v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
> @@ -186,9 +193,126 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
> return 0;
> }
> #endif /* CONFIG_MACH_MX27 */
> +#ifdef CONFIG_ARCH_MX51
> + if (cpu_is_mx51()) {
... they can be local -> here.
> + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
> +
> + switch (port) {
> + case 0: /* OTG port */
> + usbotg_base = (u32)usb_base + USBOTG_OFFSET;
> + break;
> + case 1: /* Host 1 port */
> + usbotg_base = (u32)usb_base + USBH1_OFFSET;
> + break;
> + default:
> + printk(KERN_ERR"%s no such port %d\n", __func__, port);
> + ret = -ENOENT;
> + goto error;
> + }
> + usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
That cast shouldn't be needed.
> + /* Stop then Reset */
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v &= ~UCMD_RUN_STOP;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RUN_STOP)
> + cpu_relax();
I'm thinking whether this __raw_readl/timeout procedure could be
factored out to some static inline function?
Also, the timeout seem _huge_.
> + if (!timeout) {
> + printk(KERN_ERR "%s could not stop usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v |= UCMD_RESET;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RESET)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not reset usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + switch (port) {
> + case 0: /*OTG port */
> + v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> + v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used */
> + __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> +
> + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> + v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG wakeup/power mask disable */
> + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> +
> + /* Set the PHY clock to 19.2MHz */
> + v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
> + v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
> + v |= 0x01;
> + __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
> + break;
> + case 1: /* Host 1 */
> + /*Host ULPI */
> + v = __raw_readl(usbother_base + USB_CTRL_1_OFFSET);
> + __raw_writel(v | USB_CTRL_UH1_EXT_CLK_EN, usbother_base + USB_CTRL_1_OFFSET);
> +
> + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> + v &= ~(UCTRL_H1WIE | UCTRL_H1UIE);/* HOST1 wakeup/ULPI intr disable */
> + v |= UCTRL_H1PM; /* HOST1 power mask */
> + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> +
> + v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> + v |= USB_UH1_OC_DIS; /* OC is not used */
> + __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> +
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + /* Interrupt Threshold Control:Immediate (no threshold) */
> + v &= UCMD_ITC_NO_THRESHOLD;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + break;
> + }
> +
> + /* need to reset the controller here so that the ID pin
> + * is correctly detected.
> + */
> + /* Stop then Reset */
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v &= ~UCMD_RUN_STOP;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RUN_STOP)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not stop usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v |= UCMD_RESET;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RESET)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not reset usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + /* allow controller to reset, and leave time for
> + * the ULPI transceiver to reset too.
> + */
> + msleep(100);
> +error:
> + iounmap(usb_base);
> + return ret;
> + }
And especially because of the jump label, I think that function could be
split now into individual chunks for the different platforms now.
But that can be done later. I'll send in a patch once things are merged.
Thanks,
Daniel
> +#endif
> printk(KERN_WARNING
> "%s() unable to setup USBCONTROL for this CPU\n", __func__);
> return -EINVAL;
> }
> -EXPORT_SYMBOL(mxc_set_usbcontrol);
> +EXPORT_SYMBOL(mxc_intialize_usb_hw);
>
> diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
> index c5b1e7b..e61feac 100644
> --- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h
> +++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h
> @@ -83,7 +83,7 @@ struct mxc_usbh_platform_data {
> struct otg_transceiver *otg;
> };
>
> -int mxc_set_usbcontrol(int port, unsigned int flags);
> +int mxc_intialize_usb_hw(int port, unsigned int flags);
>
> #endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
>
> --
> 1.6.0.4
>
On Fri, Apr 16, 2010 at 02:16:09PM -0500, [email protected] wrote:
> From: Dinh Nguyen <[email protected]>
>
> This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
> -Stops and resets USB HW
> -Sets some specific PHY settings
> -Stop and restart the USB HW.
> Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
>
> This patch applies to 2.6.34-rc4.
>
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> arch/arm/plat-mxc/ehci.c | 128 ++++++++++++++++++++++++++++-
> arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
> 2 files changed, 127 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
> index cb0b638..35ff1c1 100644
> --- a/arch/arm/plat-mxc/ehci.c
> +++ b/arch/arm/plat-mxc/ehci.c
> @@ -1,5 +1,6 @@
> /*
> * Copyright (c) 2009 Daniel Mack <[email protected]>
> + * Copyright (C) 2010 Freescale Semiconductor, 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
> @@ -18,6 +19,7 @@
>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/delay.h>
>
> #include <mach/hardware.h>
> #include <mach/mxc_ehci.h>
> @@ -50,9 +52,14 @@
> #define MX35_H1_TLL_BIT (1 << 5)
> #define MX35_H1_USBTE_BIT (1 << 4)
>
> -int mxc_set_usbcontrol(int port, unsigned int flags)
> +int mxc_intialize_usb_hw(int port, unsigned int flags)
> {
> unsigned int v;
> + void __iomem *usb_base;
> + u32 usbotg_base;
> + u32 usbother_base;
> + int timeout;
> + int ret = 0;
> #ifdef CONFIG_ARCH_MX3
> if (cpu_is_mx31()) {
> v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR +
> @@ -186,9 +193,126 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
> return 0;
> }
> #endif /* CONFIG_MACH_MX27 */
> +#ifdef CONFIG_ARCH_MX51
> + if (cpu_is_mx51()) {
> + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
> +
> + switch (port) {
> + case 0: /* OTG port */
> + usbotg_base = (u32)usb_base + USBOTG_OFFSET;
> + break;
> + case 1: /* Host 1 port */
> + usbotg_base = (u32)usb_base + USBH1_OFFSET;
> + break;
> + default:
> + printk(KERN_ERR"%s no such port %d\n", __func__, port);
> + ret = -ENOENT;
> + goto error;
> + }
> + usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
> +
> + /* Stop then Reset */
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v &= ~UCMD_RUN_STOP;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RUN_STOP)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not stop usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v |= UCMD_RESET;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base + USBCMD_OFFSET) & UCMD_RESET)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not reset usb hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + switch (port) {
> + case 0: /*OTG port */
> + v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> + v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used */
> + __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC_OFFSET);
> +
> + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> + v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG wakeup/power mask disable */
> + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> +
> + /* Set the PHY clock to 19.2MHz */
> + v = __raw_readl(usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
> + v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
> + v |= 0x01;
> + __raw_writel(v, usbother_base + USB_PHY_CTR_FUNC2_OFFSET);
> + break;
The sense of this funtion is to make the interface configuration,
especially the receiver type configurable with the flags parameter to
this function. This all looks very specific to your board, flags is
completely unused.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On 10 Apr 16, [email protected] wrote:
> From: Dinh Nguyen <[email protected]>
>
> This patch is part of enabling USB for Freescale MX51 Babbage HW. This
> patch adds device structures for USB Host1 and OTG port, and adds
> clocking information for USB HW.
>
> This patch applies to 2.6.34-rc4.
>
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> arch/arm/mach-mx5/clock-mx51.c | 8 ++++++
> arch/arm/mach-mx5/devices.c | 49 ++++++++++++++++++++++++++++++++++++++++
> arch/arm/mach-mx5/devices.h | 2 +
> 3 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c
> index 1ee6ce4..1fe40e1 100644
> --- a/arch/arm/mach-mx5/clock-mx51.c
> +++ b/arch/arm/mach-mx5/clock-mx51.c
> @@ -762,6 +762,10 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
> DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
> NULL, NULL, &ipg_clk, NULL);
>
> +/* USB */
> +DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET,
> + NULL, NULL, &pll3_sw_clk, NULL);
> +
> /* FEC */
> DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
> NULL, NULL, &ipg_clk, NULL);
> @@ -779,6 +783,10 @@ static struct clk_lookup lookups[] = {
> _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
> _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
> _REGISTER_CLOCK("fec.0", NULL, fec_clk)
> + _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
> + _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
> + _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
> + _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk)
> };
>
> static void clk_tree_init(void)
> diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> index 5070ae1..4b456d5 100644
This part of the patch doesn't apply anymore. Please fix. Also, run
scripts/checkpatch.pl on the series to catch some standard whitespace errors
(like no new line at the end of this file)
> --- a/arch/arm/mach-mx5/devices.c
> +++ b/arch/arm/mach-mx5/devices.c
> @@ -12,6 +12,7 @@
>
> #include <linux/platform_device.h>
> #include <linux/gpio.h>
> +#include <linux/dma-mapping.h>
> #include <mach/hardware.h>
> #include <mach/imx-uart.h>
> #include <mach/irqs.h>
> @@ -92,6 +93,54 @@ struct platform_device mxc_fec_device = {
> .resource = mxc_fec_resources,
> };
>
> +static u64 usb_dma_mask = DMA_BIT_MASK(32);
> +
> +static struct resource usbotg_resources[] = {
> + {
> + .start = MX51_OTG_BASE_ADDR,
> + .end = MX51_OTG_BASE_ADDR + 0x1ff,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = MX51_MXC_INT_USB_OTG,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +struct platform_device mxc_usbdr_host_device = {
> + .name = "mxc-ehci",
> + .id = 0,
> + .num_resources = ARRAY_SIZE(usbotg_resources),
> + .resource = usbotg_resources,
> + .dev = {
> + .dma_mask = &usb_dma_mask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + },
> +};
> +
> +static struct resource usbh1_resources[] = {
> + {
> + .start = MX51_OTG_BASE_ADDR + 0x200,
> + .end = MX51_OTG_BASE_ADDR + 0x200 + 0x1ff,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = MX51_MXC_INT_USB_H1,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +struct platform_device mxc_usbh1_device = {
> + .name = "mxc-ehci",
> + .id = 1,
> + .num_resources = ARRAY_SIZE(usbh1_resources),
> + .resource = usbh1_resources,
> + .dev = {
> + .dma_mask = &usb_dma_mask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + },
> +};
> +
> static struct mxc_gpio_port mxc_gpio_ports[] = {
> {
> .chip.label = "gpio-0",
> diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> index f339ab8..6497764 100644
> --- a/arch/arm/mach-mx5/devices.h
> +++ b/arch/arm/mach-mx5/devices.h
> @@ -2,3 +2,5 @@ extern struct platform_device mxc_uart_device0;
> extern struct platform_device mxc_uart_device1;
> extern struct platform_device mxc_uart_device2;
> extern struct platform_device mxc_fec_device;
> +extern struct platform_device mxc_usbdr_host_device;
> +extern struct platform_device mxc_usbh1_device;
> \ No newline at end of file
> --
> 1.6.0.4
>
--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || [email protected]
----------------------------------------------------------------------
On 10 Apr 17, Daniel Mack wrote:
> On Fri, Apr 16, 2010 at 02:16:09PM -0500, [email protected] wrote:
> > This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
> > -Stops and resets USB HW
> > -Sets some specific PHY settings
> > -Stop and restart the USB HW.
> > Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
> >
> > This patch applies to 2.6.34-rc4.
>
> Yes, the whole series looks _much_ better now, thanks!
> Some minor things below.
>
>
> > Signed-off-by: Dinh Nguyen <[email protected]>
> > ---
> > arch/arm/plat-mxc/ehci.c | 128 ++++++++++++++++++++++++++++-
> > arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
> > 2 files changed, 127 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c
> > index cb0b638..35ff1c1 100644
> > --- a/arch/arm/plat-mxc/ehci.c
> > +++ b/arch/arm/plat-mxc/ehci.c
> > @@ -1,5 +1,6 @@
> > /*
> > * Copyright (c) 2009 Daniel Mack <[email protected]>
> > + * Copyright (C) 2010 Freescale Semiconductor, 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
> > @@ -18,6 +19,7 @@
> >
> > #include <linux/platform_device.h>
> > #include <linux/io.h>
> > +#include <linux/delay.h>
> >
> > #include <mach/hardware.h>
> > #include <mach/mxc_ehci.h>
> > @@ -50,9 +52,14 @@
> > #define MX35_H1_TLL_BIT (1 << 5)
> > #define MX35_H1_USBTE_BIT (1 << 4)
> >
> > -int mxc_set_usbcontrol(int port, unsigned int flags)
> > +int mxc_intialize_usb_hw(int port, unsigned int flags)
>
> This patch and the next one should be merged into one. The reason is
> that you rename a function here and the next patch follows that change.
> Especially when bisecting, this can lead to uncompilable checkouts of
> the tree when stopping in the middle.
Also, patch 3 really belongs with this patch too since the #defines in
patch 3 are used here.
--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || [email protected]
----------------------------------------------------------------------
On Mon, Apr 19, 2010 at 04:03:40AM +0300, Amit Kucheria wrote:
> On 10 Apr 17, Daniel Mack wrote:
> > > @@ -18,6 +19,7 @@
> > >
> > > #include <linux/platform_device.h>
> > > #include <linux/io.h>
> > > +#include <linux/delay.h>
> > >
> > > #include <mach/hardware.h>
> > > #include <mach/mxc_ehci.h>
> > > @@ -50,9 +52,14 @@
> > > #define MX35_H1_TLL_BIT (1 << 5)
> > > #define MX35_H1_USBTE_BIT (1 << 4)
> > >
> > > -int mxc_set_usbcontrol(int port, unsigned int flags)
> > > +int mxc_intialize_usb_hw(int port, unsigned int flags)
> >
> > This patch and the next one should be merged into one. The reason is
> > that you rename a function here and the next patch follows that change.
> > Especially when bisecting, this can lead to uncompilable checkouts of
> > the tree when stopping in the middle.
>
> Also, patch 3 really belongs with this patch too since the #defines in
> patch 3 are used here.
Well, as long as the defines are commited _before_ their users, it
should be fine. But they can also be squashed into one, that's true.
Thanks,
Daniel
-----Original Message-----
From: Amit Kucheria [mailto:[email protected]]
Sent: Sunday, April 18, 2010 7:33 PM
To: Nguyen Dinh-R00091
Cc: [email protected]; [email protected];
[email protected]; [email protected];
[email protected]; [email protected]; [email protected];
[email protected]; Herring Robert-RA7055; Li Jun-R65092; Zhang
Lily-R58066
Subject: Re: [PATCHv4 2.6.34-rc4 2/7] mx5: Add USB device definitions
for Freescale MX51 Babbage HW
On 10 Apr 16, [email protected] wrote:
> From: Dinh Nguyen <[email protected]>
>
> This patch is part of enabling USB for Freescale MX51 Babbage HW. This
> patch adds device structures for USB Host1 and OTG port, and adds
> clocking information for USB HW.
>
> This patch applies to 2.6.34-rc4.
>
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> arch/arm/mach-mx5/clock-mx51.c | 8 ++++++
> arch/arm/mach-mx5/devices.c | 49
++++++++++++++++++++++++++++++++++++++++
> arch/arm/mach-mx5/devices.h | 2 +
> 3 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-mx5/clock-mx51.c
> b/arch/arm/mach-mx5/clock-mx51.c index 1ee6ce4..1fe40e1 100644
> --- a/arch/arm/mach-mx5/clock-mx51.c
> +++ b/arch/arm/mach-mx5/clock-mx51.c
> @@ -762,6 +762,10 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2,
> MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2,
MXC_CCM_CCGRx_CG10_OFFSET,
> NULL, NULL, &ipg_clk, NULL);
>
> +/* USB */
> +DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET,
> + NULL, NULL, &pll3_sw_clk, NULL);
> +
> /* FEC */
> DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
> NULL, NULL, &ipg_clk, NULL);
> @@ -779,6 +783,10 @@ static struct clk_lookup lookups[] = {
> _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
> _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
> _REGISTER_CLOCK("fec.0", NULL, fec_clk)
> + _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
> + _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
> + _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
> + _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk)
> };
>
> static void clk_tree_init(void)
> diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> index 5070ae1..4b456d5 100644
This part of the patch doesn't apply anymore. Please fix. Also, run
scripts/checkpatch.pl on the series to catch some standard whitespace
errors (like no new line at the end of this file)
[Dinh] I'm not sure I know what you mean Amit? The mxc-ehci makes calls
in the driver probe function to get the usb and usb_ahb clock. I have
ran checkpatch.pl on all of the patches in Bryan Wu made that comment.
There are only warnings for 80 characters on all of the patches.
> --- a/arch/arm/mach-mx5/devices.c
> +++ b/arch/arm/mach-mx5/devices.c
> @@ -12,6 +12,7 @@
>
> #include <linux/platform_device.h>
> #include <linux/gpio.h>
> +#include <linux/dma-mapping.h>
> #include <mach/hardware.h>
> #include <mach/imx-uart.h>
> #include <mach/irqs.h>
> @@ -92,6 +93,54 @@ struct platform_device mxc_fec_device = {
> .resource = mxc_fec_resources,
> };
>
> +static u64 usb_dma_mask = DMA_BIT_MASK(32);
> +
> +static struct resource usbotg_resources[] = {
> + {
> + .start = MX51_OTG_BASE_ADDR,
> + .end = MX51_OTG_BASE_ADDR + 0x1ff,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = MX51_MXC_INT_USB_OTG,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +struct platform_device mxc_usbdr_host_device = {
> + .name = "mxc-ehci",
> + .id = 0,
> + .num_resources = ARRAY_SIZE(usbotg_resources),
> + .resource = usbotg_resources,
> + .dev = {
> + .dma_mask = &usb_dma_mask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + },
> +};
> +
> +static struct resource usbh1_resources[] = {
> + {
> + .start = MX51_OTG_BASE_ADDR + 0x200,
> + .end = MX51_OTG_BASE_ADDR + 0x200 + 0x1ff,
> + .flags = IORESOURCE_MEM,
> + },
> + {
> + .start = MX51_MXC_INT_USB_H1,
> + .flags = IORESOURCE_IRQ,
> + },
> +};
> +
> +struct platform_device mxc_usbh1_device = {
> + .name = "mxc-ehci",
> + .id = 1,
> + .num_resources = ARRAY_SIZE(usbh1_resources),
> + .resource = usbh1_resources,
> + .dev = {
> + .dma_mask = &usb_dma_mask,
> + .coherent_dma_mask = DMA_BIT_MASK(32),
> + },
> +};
> +
> static struct mxc_gpio_port mxc_gpio_ports[] = {
> {
> .chip.label = "gpio-0",
> diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> index f339ab8..6497764 100644
> --- a/arch/arm/mach-mx5/devices.h
> +++ b/arch/arm/mach-mx5/devices.h
> @@ -2,3 +2,5 @@ extern struct platform_device mxc_uart_device0;
> extern struct platform_device mxc_uart_device1; extern struct
> platform_device mxc_uart_device2; extern struct platform_device
> mxc_fec_device;
> +extern struct platform_device mxc_usbdr_host_device; extern struct
> +platform_device mxc_usbh1_device;
> \ No newline at end of file
> --
> 1.6.0.4
>
--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || [email protected]
----------------------------------------------------------------------
-----Original Message-----
From: Sascha Hauer [mailto:[email protected]]
Sent: Saturday, April 17, 2010 9:07 PM
To: Nguyen Dinh-R00091
Cc: [email protected]; [email protected];
[email protected]; [email protected]; [email protected];
[email protected]; [email protected];
[email protected]; Herring Robert-RA7055; Li Jun-R65092; Zhang
Lily-R58066
Subject: Re: [PATCHv4 2.6.34-rc4 5/7] mxc: Add generic USB
HWinitialization for MX51
On Fri, Apr 16, 2010 at 02:16:09PM -0500, [email protected]
wrote:
> From: Dinh Nguyen <[email protected]>
>
> This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
> -Stops and resets USB HW
> -Sets some specific PHY settings
> -Stop and restart the USB HW.
> Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
>
> This patch applies to 2.6.34-rc4.
>
> Signed-off-by: Dinh Nguyen <[email protected]>
> ---
> arch/arm/plat-mxc/ehci.c | 128
++++++++++++++++++++++++++++-
> arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
> 2 files changed, 127 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index
> cb0b638..35ff1c1 100644
> --- a/arch/arm/plat-mxc/ehci.c
> +++ b/arch/arm/plat-mxc/ehci.c
> @@ -1,5 +1,6 @@
> /*
> * Copyright (c) 2009 Daniel Mack <[email protected]>
> + * Copyright (C) 2010 Freescale Semiconductor, 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 @@ -18,6 +19,7 @@
>
> #include <linux/platform_device.h>
> #include <linux/io.h>
> +#include <linux/delay.h>
>
> #include <mach/hardware.h>
> #include <mach/mxc_ehci.h>
> @@ -50,9 +52,14 @@
> #define MX35_H1_TLL_BIT (1 << 5)
> #define MX35_H1_USBTE_BIT (1 << 4)
>
> -int mxc_set_usbcontrol(int port, unsigned int flags)
> +int mxc_intialize_usb_hw(int port, unsigned int flags)
> {
> unsigned int v;
> + void __iomem *usb_base;
> + u32 usbotg_base;
> + u32 usbother_base;
> + int timeout;
> + int ret = 0;
> #ifdef CONFIG_ARCH_MX3
> if (cpu_is_mx31()) {
> v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + @@ -186,9
+193,126
> @@ int mxc_set_usbcontrol(int port, unsigned int flags)
> return 0;
> }
> #endif /* CONFIG_MACH_MX27 */
> +#ifdef CONFIG_ARCH_MX51
> + if (cpu_is_mx51()) {
> + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
> +
> + switch (port) {
> + case 0: /* OTG port */
> + usbotg_base = (u32)usb_base + USBOTG_OFFSET;
> + break;
> + case 1: /* Host 1 port */
> + usbotg_base = (u32)usb_base + USBH1_OFFSET;
> + break;
> + default:
> + printk(KERN_ERR"%s no such port %d\n", __func__,
port);
> + ret = -ENOENT;
> + goto error;
> + }
> + usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
> +
> + /* Stop then Reset */
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v &= ~UCMD_RUN_STOP;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base +
USBCMD_OFFSET) & UCMD_RUN_STOP)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not stop usb
hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> + v |= UCMD_RESET;
> + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> + timeout = 0x100000;
> + while (--timeout && __raw_readl(usbotg_base +
USBCMD_OFFSET) & UCMD_RESET)
> + cpu_relax();
> + if (!timeout) {
> + printk(KERN_ERR "%s could not reset usb
hardware\n", __func__);
> + ret = -ETIMEDOUT;
> + goto error;
> + }
> +
> + switch (port) {
> + case 0: /*OTG port */
> + v = __raw_readl(usbother_base +
USB_PHY_CTR_FUNC_OFFSET);
> + v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used
*/
> + __raw_writel(v, usbother_base +
USB_PHY_CTR_FUNC_OFFSET);
> +
> + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> + v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG
wakeup/power mask disable */
> + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> +
> + /* Set the PHY clock to 19.2MHz */
> + v = __raw_readl(usbother_base +
USB_PHY_CTR_FUNC2_OFFSET);
> + v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
> + v |= 0x01;
> + __raw_writel(v, usbother_base +
USB_PHY_CTR_FUNC2_OFFSET);
> + break;
The sense of this funtion is to make the interface configuration,
especially the receiver type configurable with the flags parameter to
this function. This all looks very specific to your board, flags is
completely unused.
[Dinh] I think you're right Sascha, I think I can move this to the board
initialization. Do you agree Daniel?
Sascha
--
Pengutronix e.K. |
|
Industrial Linux Solutions | http://www.pengutronix.de/
|
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0
|
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555
|
On Mon, Apr 19, 2010 at 08:40:29AM -0700, Nguyen Dinh-R00091 wrote:
>
>
> -----Original Message-----
> From: Sascha Hauer [mailto:[email protected]]
> Sent: Saturday, April 17, 2010 9:07 PM
> To: Nguyen Dinh-R00091
> Cc: [email protected]; [email protected];
> [email protected]; [email protected]; [email protected];
> [email protected]; [email protected];
> [email protected]; Herring Robert-RA7055; Li Jun-R65092; Zhang
> Lily-R58066
> Subject: Re: [PATCHv4 2.6.34-rc4 5/7] mxc: Add generic USB
> HWinitialization for MX51
>
> On Fri, Apr 16, 2010 at 02:16:09PM -0500, [email protected]
> wrote:
> > From: Dinh Nguyen <[email protected]>
> >
> > This patch adds USB HW initializiation code to /plat-mxc/ehci.c.
> > -Stops and resets USB HW
> > -Sets some specific PHY settings
> > -Stop and restart the USB HW.
> > Renames mxc_set_usbcontrol to mxc_initialize_usb_hw.
> >
> > This patch applies to 2.6.34-rc4.
> >
> > Signed-off-by: Dinh Nguyen <[email protected]>
> > ---
> > arch/arm/plat-mxc/ehci.c | 128
> ++++++++++++++++++++++++++++-
> > arch/arm/plat-mxc/include/mach/mxc_ehci.h | 2 +-
> > 2 files changed, 127 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index
>
> > cb0b638..35ff1c1 100644
> > --- a/arch/arm/plat-mxc/ehci.c
> > +++ b/arch/arm/plat-mxc/ehci.c
> > @@ -1,5 +1,6 @@
> > /*
> > * Copyright (c) 2009 Daniel Mack <[email protected]>
> > + * Copyright (C) 2010 Freescale Semiconductor, 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 @@ -18,6 +19,7 @@
> >
> > #include <linux/platform_device.h>
> > #include <linux/io.h>
> > +#include <linux/delay.h>
> >
> > #include <mach/hardware.h>
> > #include <mach/mxc_ehci.h>
> > @@ -50,9 +52,14 @@
> > #define MX35_H1_TLL_BIT (1 << 5)
> > #define MX35_H1_USBTE_BIT (1 << 4)
> >
> > -int mxc_set_usbcontrol(int port, unsigned int flags)
> > +int mxc_intialize_usb_hw(int port, unsigned int flags)
> > {
> > unsigned int v;
> > + void __iomem *usb_base;
> > + u32 usbotg_base;
> > + u32 usbother_base;
> > + int timeout;
> > + int ret = 0;
> > #ifdef CONFIG_ARCH_MX3
> > if (cpu_is_mx31()) {
> > v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + @@ -186,9
> +193,126
> > @@ int mxc_set_usbcontrol(int port, unsigned int flags)
> > return 0;
> > }
> > #endif /* CONFIG_MACH_MX27 */
> > +#ifdef CONFIG_ARCH_MX51
> > + if (cpu_is_mx51()) {
> > + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
> > +
> > + switch (port) {
> > + case 0: /* OTG port */
> > + usbotg_base = (u32)usb_base + USBOTG_OFFSET;
> > + break;
> > + case 1: /* Host 1 port */
> > + usbotg_base = (u32)usb_base + USBH1_OFFSET;
> > + break;
> > + default:
> > + printk(KERN_ERR"%s no such port %d\n", __func__,
> port);
> > + ret = -ENOENT;
> > + goto error;
> > + }
> > + usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
> > +
> > + /* Stop then Reset */
> > + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> > + v &= ~UCMD_RUN_STOP;
> > + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> > + timeout = 0x100000;
> > + while (--timeout && __raw_readl(usbotg_base +
> USBCMD_OFFSET) & UCMD_RUN_STOP)
> > + cpu_relax();
> > + if (!timeout) {
> > + printk(KERN_ERR "%s could not stop usb
> hardware\n", __func__);
> > + ret = -ETIMEDOUT;
> > + goto error;
> > + }
> > +
> > + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> > + v |= UCMD_RESET;
> > + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> > + timeout = 0x100000;
> > + while (--timeout && __raw_readl(usbotg_base +
> USBCMD_OFFSET) & UCMD_RESET)
> > + cpu_relax();
> > + if (!timeout) {
> > + printk(KERN_ERR "%s could not reset usb
> hardware\n", __func__);
> > + ret = -ETIMEDOUT;
> > + goto error;
> > + }
> > +
> > + switch (port) {
> > + case 0: /*OTG port */
> > + v = __raw_readl(usbother_base +
> USB_PHY_CTR_FUNC_OFFSET);
> > + v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used
> */
> > + __raw_writel(v, usbother_base +
> USB_PHY_CTR_FUNC_OFFSET);
> > +
> > + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> > + v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG
> wakeup/power mask disable */
> > + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> > +
> > + /* Set the PHY clock to 19.2MHz */
> > + v = __raw_readl(usbother_base +
> USB_PHY_CTR_FUNC2_OFFSET);
> > + v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
> > + v |= 0x01;
> > + __raw_writel(v, usbother_base +
> USB_PHY_CTR_FUNC2_OFFSET);
> > + break;
>
> The sense of this funtion is to make the interface configuration,
> especially the receiver type configurable with the flags parameter to
> this function. This all looks very specific to your board, flags is
> completely unused.
>
> [Dinh] I think you're right Sascha, I think I can move this to the board
> initialization. Do you agree Daniel?
No, and Daniel won't agree either. What I meant is that you should add
support for the different transceiver types in this function. Take
i.MX27/31/35 as an example how to do this: Parse the flag parameter and
do whatever you have to.
Sascha
--
Pengutronix e.K. | |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
On Mon, Apr 19, 2010 at 05:58:28PM +0200, Sascha Hauer wrote:
> On Mon, Apr 19, 2010 at 08:40:29AM -0700, Nguyen Dinh-R00091 wrote:
> > > cb0b638..35ff1c1 100644
> > > --- a/arch/arm/plat-mxc/ehci.c
> > > +++ b/arch/arm/plat-mxc/ehci.c
> > > @@ -1,5 +1,6 @@
> > > /*
> > > * Copyright (c) 2009 Daniel Mack <[email protected]>
> > > + * Copyright (C) 2010 Freescale Semiconductor, 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 @@ -18,6 +19,7 @@
> > >
> > > #include <linux/platform_device.h>
> > > #include <linux/io.h>
> > > +#include <linux/delay.h>
> > >
> > > #include <mach/hardware.h>
> > > #include <mach/mxc_ehci.h>
> > > @@ -50,9 +52,14 @@
> > > #define MX35_H1_TLL_BIT (1 << 5)
> > > #define MX35_H1_USBTE_BIT (1 << 4)
> > >
> > > -int mxc_set_usbcontrol(int port, unsigned int flags)
> > > +int mxc_intialize_usb_hw(int port, unsigned int flags)
> > > {
> > > unsigned int v;
> > > + void __iomem *usb_base;
> > > + u32 usbotg_base;
> > > + u32 usbother_base;
> > > + int timeout;
> > > + int ret = 0;
> > > #ifdef CONFIG_ARCH_MX3
> > > if (cpu_is_mx31()) {
> > > v = readl(MX31_IO_ADDRESS(MX31_OTG_BASE_ADDR + @@ -186,9
> > +193,126
> > > @@ int mxc_set_usbcontrol(int port, unsigned int flags)
> > > return 0;
> > > }
> > > #endif /* CONFIG_MACH_MX27 */
> > > +#ifdef CONFIG_ARCH_MX51
> > > + if (cpu_is_mx51()) {
> > > + usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
> > > +
> > > + switch (port) {
> > > + case 0: /* OTG port */
> > > + usbotg_base = (u32)usb_base + USBOTG_OFFSET;
> > > + break;
> > > + case 1: /* Host 1 port */
> > > + usbotg_base = (u32)usb_base + USBH1_OFFSET;
> > > + break;
> > > + default:
> > > + printk(KERN_ERR"%s no such port %d\n", __func__,
> > port);
> > > + ret = -ENOENT;
> > > + goto error;
> > > + }
> > > + usbother_base = (u32)usb_base + USBOTHER_REGS_OFFSET;
> > > +
> > > + /* Stop then Reset */
> > > + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> > > + v &= ~UCMD_RUN_STOP;
> > > + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> > > + timeout = 0x100000;
> > > + while (--timeout && __raw_readl(usbotg_base +
> > USBCMD_OFFSET) & UCMD_RUN_STOP)
> > > + cpu_relax();
> > > + if (!timeout) {
> > > + printk(KERN_ERR "%s could not stop usb
> > hardware\n", __func__);
> > > + ret = -ETIMEDOUT;
> > > + goto error;
> > > + }
> > > +
> > > + v = __raw_readl(usbotg_base + USBCMD_OFFSET);
> > > + v |= UCMD_RESET;
> > > + __raw_writel(v, usbotg_base + USBCMD_OFFSET);
> > > + timeout = 0x100000;
> > > + while (--timeout && __raw_readl(usbotg_base +
> > USBCMD_OFFSET) & UCMD_RESET)
> > > + cpu_relax();
> > > + if (!timeout) {
> > > + printk(KERN_ERR "%s could not reset usb
> > hardware\n", __func__);
> > > + ret = -ETIMEDOUT;
> > > + goto error;
> > > + }
> > > +
> > > + switch (port) {
> > > + case 0: /*OTG port */
> > > + v = __raw_readl(usbother_base +
> > USB_PHY_CTR_FUNC_OFFSET);
> > > + v |= USB_UTMI_PHYCTRL_OC_DIS; /* OC is not used
> > */
> > > + __raw_writel(v, usbother_base +
> > USB_PHY_CTR_FUNC_OFFSET);
> > > +
> > > + v = __raw_readl(usbother_base + USBCTRL_OFFSET);
> > > + v &= ~(UCTRL_OPM | UCTRL_OWIE);/* OTG
> > wakeup/power mask disable */
> > > + __raw_writel(v, usbother_base + USBCTRL_OFFSET);
> > > +
> > > + /* Set the PHY clock to 19.2MHz */
> > > + v = __raw_readl(usbother_base +
> > USB_PHY_CTR_FUNC2_OFFSET);
> > > + v &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
> > > + v |= 0x01;
> > > + __raw_writel(v, usbother_base +
> > USB_PHY_CTR_FUNC2_OFFSET);
> > > + break;
> >
> > The sense of this funtion is to make the interface configuration,
> > especially the receiver type configurable with the flags parameter to
> > this function. This all looks very specific to your board, flags is
> > completely unused.
> >
> > [Dinh] I think you're right Sascha, I think I can move this to the board
> > initialization. Do you agree Daniel?
>
> No, and Daniel won't agree either. What I meant is that you should add
> support for the different transceiver types in this function. Take
> i.MX27/31/35 as an example how to do this: Parse the flag parameter and
> do whatever you have to.
Yes, of course. Sorry I didn't see this when reviewing.
Think about what's necessary to add support for a new board. You don't
want to copy all the register accessing functions again but re-use and
share generic code. All you need to have in the board specific support
code are flags which are passed to the generic driver core. Just like
all other board support code does it as well. Not just for USB btw. but
for all sorts of other drivers as wel. Have a look at code which is
already there to get the idea.
[Btw - your mail client is broken as it wraps quoted lines (see above).
See Documentation/email-clients.txt]
Daniel
On Mon, Apr 19, 2010 at 06:59:39PM +0200, Daniel Mack wrote:
> Think about what's necessary to add support for a new board. You don't
> want to copy all the register accessing functions again but re-use and
> share generic code. All you need to have in the board specific support
> code are flags which are passed to the generic driver core. Just like
> all other board support code does it as well. Not just for USB btw. but
> for all sorts of other drivers as wel. Have a look at code which is
> already there to get the idea.
>
> [Btw - your mail client is broken as it wraps quoted lines (see above).
> See Documentation/email-clients.txt]
Sorry, I messed up the To/Cc fields in my reply. The above was directed
to Nguyen Dinh of course, not to Sascha.