Skip to contentSkip to conversation

ARM: mx28: add usb host function

PATCH Superseded Tony Lin 6 participants 16 messages Jul 25, 2011 – Jul 26, 2011

Subsystems (5)

v2 of 4 Superseded Latest is v4 →

lore
Share & tools
lore

Tony Lin

author
#0 lore raw

v2 cover ARM: mx28: add usb host function

this patch series is to add mx28 usb host function. the driver only support usb host mode on usb port1. the driver reuses ehci-mxc.c under usb/host, but did some modifications based on it to satisfy mx28 usb host requirement. The modifications will not affect other platforms.

Code is based on the branch for-next in sascha's tree http://git.pengutronix.de/git/imx/linux-2.6.git

Tested on MX28 EVK.

changes since v1:
* add dummy clock to avoid adding cpu judgement in driver for Sascha's request.
* use context in phy functions, so that usb device could share the code.
* some code consolidation and patch reorgnization.
* error checking improvement.
* remove a few unneccesary code.

Tony Lin (6):
ARM: mxs: ehci: consolidate definitions and structures to share among platforms
ARM: mxs: enable usb1 phy power supply
ARM: mxs: add usb clocks to clock tree
ARM: mxs: make ehci-mxc more flexible to be used on different platforms
ARM: mxs: add usb phy operations
ARM: mxs: add usb host function to default config

 arch/arm/configs/mxs_defconfig            |    8 +-
 arch/arm/mach-mxs/Kconfig                 |    1 +
 arch/arm/mach-mxs/Makefile                |    1 +
 arch/arm/mach-mxs/clock-mx28.c            |   28 ++-
 arch/arm/mach-mxs/include/mach/hardware.h |    2 +
 arch/arm/mach-mxs/include/mach/mxs.h      |   12 +-
 arch/arm/mach-mxs/mach-mx28evk.c          |    8 +
 arch/arm/mach-mxs/mxs_usb.c               |  286 +++++++++++++++++++++++++++++
 arch/arm/mach-mxs/regs-usbphy-mx28.h      |  240 ++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/mxc_ehci.h |   19 --
 drivers/usb/host/Kconfig                  |    2 +-
 drivers/usb/host/ehci-mxc.c               |   21 ++-
 include/linux/fsl_devices.h               |   21 ++
 13 files changed, 613 insertions(+), 36 deletions(-)
 create mode 100644 arch/arm/mach-mxs/mxs_usb.c
 create mode 100644 arch/arm/mach-mxs/regs-usbphy-mx28.h
author
#1 lore raw

PATCH v2 1/6 ARM: mxs: ehci: consolidate definitions and structures to share among platforms

move common definitions and data structures used for mxs and mxc platforms to fsl_device.h from mxc_ehci.h
so that these definitions and structures could be shared without duplicated copies.

---
 arch/arm/plat-mxc/include/mach/mxc_ehci.h |   19 -------------------
 drivers/usb/host/ehci-mxc.c               |    4 +---
 include/linux/fsl_devices.h               |   19 +++++++++++++++++++
 3 files changed, 20 insertions(+), 22 deletions(-)
arch/arm/plat-mxc/include/mach/mxc_ehci.h +0 -19
index 2c159dc..8775807 100644
@@ -1,17 +1,6 @@
 #ifndef __INCLUDE_ASM_ARCH_MXC_EHCI_H
 #define __INCLUDE_ASM_ARCH_MXC_EHCI_H
 
-/* values for portsc field */
-#define MXC_EHCI_PHY_LOW_POWER_SUSPEND	(1 << 23)
-#define MXC_EHCI_FORCE_FS		(1 << 24)
-#define MXC_EHCI_UTMI_8BIT		(0 << 28)
-#define MXC_EHCI_UTMI_16BIT		(1 << 28)
-#define MXC_EHCI_SERIAL			(1 << 29)
-#define MXC_EHCI_MODE_UTMI		(0 << 30)
-#define MXC_EHCI_MODE_PHILIPS		(1 << 30)
-#define MXC_EHCI_MODE_ULPI		(2 << 30)
-#define MXC_EHCI_MODE_SERIAL		(3 << 30)
-
 /* values for flags field */
 #define MXC_EHCI_INTERFACE_DIFF_UNI	(0 << 0)
 #define MXC_EHCI_INTERFACE_DIFF_BI	(1 << 0)
@@ -39,14 +28,6 @@
 #define MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK		0x3
 #define MX5_USB_UTMI_PHYCTRL1_PLLDIV_SHIFT		0
 
-struct mxc_usbh_platform_data {
-	int (*init)(struct platform_device *pdev);
-	int (*exit)(struct platform_device *pdev);
-
-	unsigned int		 portsc;
-	struct otg_transceiver	*otg;
-};
-
 int mx51_initialize_usb_hw(int port, unsigned int flags);
 int mx25_initialize_usb_hw(int port, unsigned int flags);
 int mx31_initialize_usb_hw(int port, unsigned int flags);
drivers/usb/host/ehci-mxc.c +1 -3
index 0c058be..cbf60a6 100644
@@ -23,9 +23,7 @@
 #include <linux/usb/otg.h>
 #include <linux/usb/ulpi.h>
 #include <linux/slab.h>
-
-#include <mach/mxc_ehci.h>
-
+#include <linux/fsl_devices.h>
 #include <asm/mach-types.h>
 
 #define ULPI_VIEWPORT_OFFSET	0x170
include/linux/fsl_devices.h +19 -0
index fffdf00..bc2c1bf 100644
@@ -103,6 +103,25 @@ struct fsl_usb2_platform_data {
 
 #define FLS_USB2_WORKAROUND_ENGCM09152	(1 << 0)
 
+/* values for portsc field */
+#define MXC_EHCI_PHY_LOW_POWER_SUSPEND	(1 << 23)
+#define MXC_EHCI_FORCE_FS		(1 << 24)
+#define MXC_EHCI_UTMI_8BIT		(0 << 28)
+#define MXC_EHCI_UTMI_16BIT		(1 << 28)
+#define MXC_EHCI_SERIAL			(1 << 29)
+#define MXC_EHCI_MODE_UTMI		(0 << 30)
+#define MXC_EHCI_MODE_PHILIPS		(1 << 30)
+#define MXC_EHCI_MODE_ULPI		(2 << 30)
+#define MXC_EHCI_MODE_SERIAL		(3 << 30)
+
+struct mxc_usbh_platform_data {
+	int (*init)(struct platform_device *pdev);
+	int (*exit)(struct platform_device *pdev);
+
+	unsigned int		 portsc;
+	struct otg_transceiver	*otg;
+};
+
 struct spi_device;
 
 struct fsl_spi_platform_data {
Signature · 1 line
1.7.0.4
author
#2 lore raw

PATCH v2 2/6 ARM: mxs: enable usb1 phy power supply

In reply to Tony Lin

configure usb1 phy power enable gpio and enable usb1 phy power

---
 arch/arm/mach-mxs/mach-mx28evk.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)
arch/arm/mach-mxs/mach-mx28evk.c +8 -0
index eaaf6ff..9901547 100644
@@ -34,6 +34,7 @@
 #define MX28EVK_BL_ENABLE	MXS_GPIO_NR(3, 18)
 #define MX28EVK_LCD_ENABLE	MXS_GPIO_NR(3, 30)
 #define MX28EVK_FEC_PHY_RESET	MXS_GPIO_NR(4, 13)
+#define MX28EVK_USB1_PWR_EN	MXS_GPIO_NR(3, 8)
 
 #define MX28EVK_MMC0_WRITE_PROTECT	MXS_GPIO_NR(2, 12)
 #define MX28EVK_MMC1_WRITE_PROTECT	MXS_GPIO_NR(0, 28)
@@ -183,6 +184,8 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
 
 	/* led */
 	MX28_PAD_AUART1_TX__GPIO_3_5 | MXS_PAD_CTRL,
+	/* usb1 */
+	MX28_PAD_AUART2_RX__GPIO_3_8 | MXS_PAD_CTRL,
 };
 
 /* led */
@@ -405,6 +408,11 @@ static void __init mx28evk_init(void)
 		pr_warn("failed to request gpio mmc1-slot-power: %d\n", ret);
 	mx28_add_mxs_mmc(1, &mx28evk_mmc_pdata[1]);
 
+	ret = gpio_request_one(MX28EVK_USB1_PWR_EN, GPIOF_OUT_INIT_HIGH,
+			       "usb1-power-en");
+	if (ret)
+		pr_warn("failed to request gpio usb1-power-en %d\n", ret);
+
 	gpio_led_register_device(0, &mx28evk_led_data);
 }
 
Signature · 1 line
1.7.0.4
author
#3 lore raw

PATCH v2 3/6 ARM: mxs: add usb clocks to clock tree

In reply to Tony Lin

add usb host clock and usb host phy clock to clock tree add usb dummy clocks to clock tree to get rid of adding more cpu_is_mx macros

---
 arch/arm/mach-mxs/clock-mx28.c |   28 +++++++++++++++++++---------
 1 files changed, 19 insertions(+), 9 deletions(-)
arch/arm/mach-mxs/clock-mx28.c +19 -9
index 5dcc59d..6f3cd40 100644
@@ -554,15 +554,15 @@ static struct clk rtc_clk = {
 	.parent = &ref_xtal_clk,
 };
 
-/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
-static struct clk usb0_clk = {
-	.enable_reg = DIGCTRL_BASE_ADDR,
-	.enable_shift = 2,
-	.enable = _raw_clk_enable,
-	.disable = _raw_clk_disable,
-	.parent = &pll0_clk,
+static struct clk dummy_clk = {
+	.enable_reg = 0,
+	.enable_shift = 0,
+	.enable = NULL,
+	.disable = NULL,
+	.parent = NULL,
 };
 
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
 static struct clk usb1_clk = {
 	.enable_reg = DIGCTRL_BASE_ADDR,
 	.enable_shift = 16,
@@ -571,6 +571,14 @@ static struct clk usb1_clk = {
 	.parent = &pll1_clk,
 };
 
+/* usb phy clock for usb1 */
+static struct clk usb_phy_clk1 = {
+	.parent = &pll1_clk,
+	.enable = _raw_clk_disable,
+	.disable = _raw_clk_enable,
+	.enable_reg = CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLL1CTRL0,
+	.enable_shift = 18,
+};
 #define _DEFINE_CLOCK(name, er, es, p)					\
 	static struct clk name = {					\
 		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
@@ -627,8 +635,10 @@ static struct clk_lookup lookups[] = {
 	_REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
 	_REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
 	_REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
-	_REGISTER_CLOCK(NULL, "usb0", usb0_clk)
-	_REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+	_REGISTER_CLOCK("mxc-ehci", "usb1", usb1_clk)
+	_REGISTER_CLOCK("mxc-ehci", "usb1_phy", usb_phy_clk1)
+	_REGISTER_CLOCK("mxc-ehci", "usb", dummy_clk)
+	_REGISTER_CLOCK("mxc-ehci", "usb_ahb", dummy_clk)
 	_REGISTER_CLOCK("mxs-pwm.0", NULL, pwm_clk)
 	_REGISTER_CLOCK("mxs-pwm.1", NULL, pwm_clk)
 	_REGISTER_CLOCK("mxs-pwm.2", NULL, pwm_clk)
Signature · 1 line
1.7.0.4
#4 lore raw

PATCH v2 3/6 ARM: mxs: add usb clocks to clock tree

Hello.

Quoted 20 lines · Tony Lin

add usb host clock and usb host phy clock to clock tree add usb dummy clocks to clock tree to get rid of adding more cpu_is_mx macros

---
  arch/arm/mach-mxs/clock-mx28.c |   28 +++++++++++++++++++---------
  1 files changed, 19 insertions(+), 9 deletions(-)
arch/arm/mach-mxs/clock-mx28.c +0 -3
index 5dcc59d..6f3cd40 100644
@@ -554,15 +554,15 @@ static struct clk rtc_clk = {
  	.parent =&ref_xtal_clk,
  };
 
-/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
-static struct clk usb0_clk = {
-	.enable_reg = DIGCTRL_BASE_ADDR,

arch/arm/mach-mxs/clock-mx28.c static struct clk rtc_clk = { · line 562

Quoted 10 lines
arch/arm/mach-mxs/clock-mx28.c +6 -4
-	.enable_shift = 2,
-	.enable = _raw_clk_enable,
-	.disable = _raw_clk_disable,
-	.parent =&pll0_clk,
+static struct clk dummy_clk = {
+	.enable_reg = 0,
+	.enable_shift = 0,
+	.enable = NULL,
+	.disable = NULL,
+	.parent = NULL,

You don't need to explicitly initialize to 0 or NULL.

WBR, Sergei

#5 lore raw

PATCH v2 3/6 ARM: mxs: add usb clocks to clock tree

Quoted 28 lines

-----Original Message-----
From: Sergei Shtylyov [mailto:sshtylyov at mvista.com]
Sent: Monday, July 25, 2011 6:24 PM
To: Lin Tony-B19295
Cc: linux-usb at vger.kernel.org; linux-arm-kernel at lists.infradead.org; stern at rowland.harvard.edu; koen.beel.barco at gmail.com
Subject: Re: [PATCH v2 3/6] ARM: mxs: add usb clocks to clock tree

Hello.

Quoted 16 lines · Tony Lin

add usb host clock and usb host phy clock to clock tree add usb dummy clocks to clock tree to get rid of adding more cpu_is_mx macros

---
  arch/arm/mach-mxs/clock-mx28.c |   28 +++++++++++++++++++---------
  1 files changed, 19 insertions(+), 9 deletions(-)
(quoted diff) +0 -0

b/arch/arm/mach-mxs/clock-mx28.c index 5dcc59d..6f3cd40 100644

arch/arm/mach-mxs/clock-mx28.c +0 -0
@@ -554,15 +554,15 @@ static struct clk rtc_clk = {
  	.parent =&ref_xtal_clk,
  };
 
Quoted 16 lines

arch/arm/mach-mxs/clock-mx28.c static struct clk rtc_clk = { · line 562

Quoted 13 lines
arch/arm/mach-mxs/clock-mx28.c +6 -7
-/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
-static struct clk usb0_clk = {
-	.enable_reg = DIGCTRL_BASE_ADDR,
-	.enable_shift = 2,
-	.enable = _raw_clk_enable,
-	.disable = _raw_clk_disable,
-	.parent =&pll0_clk,
+static struct clk dummy_clk = {
+	.enable_reg = 0,
+	.enable_shift = 0,
+	.enable = NULL,
+	.disable = NULL,
+	.parent = NULL,

You don't need to explicitly initialize to 0 or NULL.

Okay.

Quoted 1 line

WBR, Sergei

author
#6 lore raw

PATCH v2 4/6 ARM: mxs: make ehci-mxc more flexible to be used on different platforms

In reply to Tony Lin

change ehci_irq to mxc_ehci_irq to give chance do some platform specific actions in irq handler for different platforms.
add void pointer in the last of mxc_usbh_platform_data structure so that additional information could be added to that field if needed.

---
 arch/arm/mach-mxs/include/mach/hardware.h |    2 ++
 arch/arm/mach-mxs/include/mach/mxs.h      |   12 +++++++++++-
 drivers/usb/host/Kconfig                  |    2 +-
 drivers/usb/host/ehci-mxc.c               |   17 +++++++++++++++--
 include/linux/fsl_devices.h               |    4 +++-
 5 files changed, 32 insertions(+), 5 deletions(-)
arch/arm/mach-mxs/include/mach/hardware.h +2 -0
index 53e89a0..affa72b 100644
@@ -26,4 +26,6 @@
 #define IOMEM(addr)	((void __force __iomem *)(addr))
 #endif
 
+#include "mxs.h"
+
 #endif /* __MACH_MXS_HARDWARE_H__ */
arch/arm/mach-mxs/include/mach/mxs.h +11 -1
index 35a89dd..0661e90 100644
@@ -35,7 +35,17 @@
 		machine_is_mx28evk() ||					\
 		machine_is_tx28() ||					\
 		0)
-
+#define cpu_is_mx1()		0
+#define cpu_is_mx21()		0
+#define cpu_is_mx25()		0
+#define cpu_is_mx27()		0
+#define cpu_is_mx31()		0
+#define cpu_is_mx35()		0
+#define cpu_is_mx50()		0
+#define cpu_is_mx51()		0
+#define cpu_is_mx53()		0
+#define cpu_is_mx3()		(cpu_is_mx31() || cpu_is_mx35())
+#define cpu_is_mx2()		(cpu_is_mx21() || cpu_is_mx27())
 /*
  * IO addresses common to MXS-based
  */
drivers/usb/host/Kconfig +1 -1
index ab085f1..6a5905b 100644
@@ -139,7 +139,7 @@ config USB_EHCI_FSL
 
 config USB_EHCI_MXC
 	bool "Support for Freescale on-chip EHCI USB controller"
-	depends on USB_EHCI_HCD && ARCH_MXC
+	depends on USB_EHCI_HCD && (ARCH_MXC || ARCH_MXS)
 	select USB_EHCI_ROOT_HUB_TT
 	---help---
 	  Variation of ARC USB block used in some Freescale chips.
drivers/usb/host/ehci-mxc.c +15 -2
index cbf60a6..b22d6cf 100644
@@ -64,6 +64,19 @@ static int ehci_mxc_setup(struct usb_hcd *hcd)
 	return 0;
 }
 
+static irqreturn_t mxc_ehci_irq(struct usb_hcd *hcd)
+{
+	struct mxc_usbh_platform_data *pdata;
+
+	pdata = hcd->self.controller->platform_data;
+	if (pdata->plt_irq_handler == NULL)
+		goto out;
+	pdata->plt_irq_handler(pdata);
+
+out:
+	return ehci_irq(hcd);
+}
+
 static const struct hc_driver ehci_mxc_hc_driver = {
 	.description = hcd_name,
 	.product_desc = "Freescale On-Chip EHCI Host Controller",
@@ -72,7 +85,7 @@ static const struct hc_driver ehci_mxc_hc_driver = {
 	/*
 	 * generic hardware linkage
 	 */
-	.irq = ehci_irq,
+	.irq = mxc_ehci_irq,
 	.flags = HCD_USB2 | HCD_MEMORY,
 
 	/*
@@ -334,6 +347,6 @@ static struct platform_driver ehci_mxc_driver = {
 	.remove = __exit_p(ehci_mxc_drv_remove),
 	.shutdown = ehci_mxc_drv_shutdown,
 	.driver = {
-		   .name = "mxc-ehci",
+		.name = "mxc-ehci",
 	},
 };
include/linux/fsl_devices.h +3 -1
index bc2c1bf..cf441e8 100644
@@ -118,8 +118,10 @@ struct mxc_usbh_platform_data {
 	int (*init)(struct platform_device *pdev);
 	int (*exit)(struct platform_device *pdev);
 
-	unsigned int		 portsc;
+	unsigned int		portsc;
 	struct otg_transceiver	*otg;
+	void (*plt_irq_handler)(struct mxc_usbh_platform_data *pdata);
+	void		*ppriv;
 };
 
 struct spi_device;
Signature · 1 line
1.7.0.4
#7 lore raw

PATCH v2 4/6 ARM: mxs: make ehci-mxc more flexible to be used on different platforms

Hi,

Quoted 14 lines · Tony Lin

change ehci_irq to mxc_ehci_irq to give chance do some platform specific actions in irq handler for different platforms.
add void pointer in the last of mxc_usbh_platform_data structure so that additional information could be added to that field if needed.

---
 arch/arm/mach-mxs/include/mach/hardware.h |    2 ++
 arch/arm/mach-mxs/include/mach/mxs.h      |   12 +++++++++++-
 drivers/usb/host/Kconfig                  |    2 +-
 drivers/usb/host/ehci-mxc.c               |   17 +++++++++++++++--
 include/linux/fsl_devices.h               |    4 +++-
 5 files changed, 32 insertions(+), 5 deletions(-)

[...]

Quoted 5 lines
include/linux/fsl_devices.h +0 -0
index bc2c1bf..cf441e8 100644

include/linux/fsl_devices.h struct mxc_usbh_platform_data { · line 126

Quoted 10 lines
include/linux/fsl_devices.h +3 -1
@@ -118,8 +118,10 @@ struct mxc_usbh_platform_data {
 	int (*init)(struct platform_device *pdev);
 	int (*exit)(struct platform_device *pdev);
 
-	unsigned int		 portsc;
+	unsigned int		portsc;
 	struct otg_transceiver	*otg;
+	void (*plt_irq_handler)(struct mxc_usbh_platform_data *pdata);
+	void		*ppriv;
 };
 

You just added this structure in patch 1/6. Then modify it in this patch. The indentation change should be incorporated into the first patch.

Lothar Wa?mann

Signature · 9 lines
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
author
#8 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

In reply to Tony Lin

add usb phy register definitions and functions
usb host driver will use these callback functions
to initialize usb phy and change working mode

---
 arch/arm/mach-mxs/Kconfig            |    1 +
 arch/arm/mach-mxs/Makefile           |    1 +
 arch/arm/mach-mxs/mxs_usb.c          |  286 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/regs-usbphy-mx28.h |  240 ++++++++++++++++++++++++++++
 4 files changed, 528 insertions(+), 0 deletions(-)
arch/arm/mach-mxs/Kconfig +1 -0
index 4cd0231..1c4264f 100644
@@ -49,6 +49,7 @@ config MACH_MX28EVK
 	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
+	select USB_ARCH_HAS_EHCI
 	help
 	  Include support for MX28EVK platform. This includes specific
 	  configurations for the board and its peripherals.
arch/arm/mach-mxs/Makefile +1 -0
index 6c38262..726c49f 100644
@@ -12,5 +12,6 @@ obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
 obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
+obj-$(CONFIG_USB_EHCI_MXC)   += mxs_usb.o
 
 obj-y += devices/
arch/arm/mach-mxs/mxs_usb.c new file +286 -0

286 lines not on this page · raw message

arch/arm/mach-mxs/regs-usbphy-mx28.h new file +240 -0

240 lines not on this page · raw message

Signature · 1 line
1.7.0.4
#9 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

Hi,

Quoted 232 lines · Tony Lin

add usb phy register definitions and functions
usb host driver will use these callback functions
to initialize usb phy and change working mode

---
 arch/arm/mach-mxs/Kconfig            |    1 +
 arch/arm/mach-mxs/Makefile           |    1 +
 arch/arm/mach-mxs/mxs_usb.c          |  286 ++++++++++++++++++++++++++++++++++
 arch/arm/mach-mxs/regs-usbphy-mx28.h |  240 ++++++++++++++++++++++++++++
 4 files changed, 528 insertions(+), 0 deletions(-)
arch/arm/mach-mxs/Kconfig +1 -0
index 4cd0231..1c4264f 100644
@@ -49,6 +49,7 @@ config MACH_MX28EVK
 	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
+	select USB_ARCH_HAS_EHCI
 	help
 	  Include support for MX28EVK platform. This includes specific
 	  configurations for the board and its peripherals.
arch/arm/mach-mxs/Makefile +1 -0
index 6c38262..726c49f 100644
@@ -12,5 +12,6 @@ obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
 obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
+obj-$(CONFIG_USB_EHCI_MXC)   += mxs_usb.o
 
 obj-y += devices/
arch/arm/mach-mxs/mxs_usb.c new file +191 -0
new file mode 100644
index 0000000..01753ea
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/mx28.h>
+#include "regs-usbphy-mx28.h"
+
+/* EHCI registers: */
+#define UOG_USBCMD		(0x140) /* USB command register */
+#define UOG_USBSTS		(0x144) /* USB status register */
+#define UOG_PORTSC1		(0x184) /* port status and control */
+/* x_PORTSCx */
+#define PORTSC_PTS_MASK		(3 << 30) /* parallel xcvr mask */
+#define PORTSC_PTS_UTMI		(0 << 30) /* UTMI/UTMI+ */
+#define PORTSC_PTW		(1 << 28) /* UTMI width */
+/* USBCMD */
+#define UCMD_RUN_STOP           (1 << 0) /* controller run/stop */
+#define UCMD_RESET		(1 << 1) /* controller reset */
+
+#define HOSTPHY_CONNECT_STATE	(1 << 3)
+#define STS_PCD			(1 << 2) /* port change detect */
+
+struct mxs_usb_private_date {
+	struct clk *usb_clk, *usb_phy_clk;
+	int internal_phy_clk_already_on;
+	void __iomem *phy_regs;		/* usb phy register base */
+	void __iomem *ctrl_regs;	/* usb controller register base */
+};
+
+static inline int fsl_platform_get_usb_connect_status
+			(struct mxs_usb_private_date *ppriv)
+{
+	u32 status;
+
+	status = __raw_readl(ppriv->phy_regs + HW_USBPHY_STATUS);
+
+	return ((status & HOSTPHY_CONNECT_STATE) == 0);
+}
+
+/* enable/disable high-speed disconnect detector of phy ctrl */
+static inline void fsl_platform_disconnect_detect
+			(struct mxs_usb_private_date *ppriv, int enable)
+{
+	if (enable) {
+		__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+		ppriv->phy_regs + HW_USBPHY_CTRL_SET);
+	} else {
+		__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+		ppriv->phy_regs + HW_USBPHY_CTRL_CLR);
+	}
+}
+
+static void fsl_plt_usbh_irq_handler(struct mxc_usbh_platform_data *pdata)
+{
+	u32			status;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	status = __raw_readl(ppriv->ctrl_regs + UOG_USBSTS);
+
+	if (status & STS_PCD)
+		fsl_platform_disconnect_detect(ppriv,
+			fsl_platform_get_usb_connect_status(ppriv));
+}
+
+static int usb_phy_enable(struct mxc_usbh_platform_data *pdata)
+{
+	u32 tmp;
+	u32 i = 0;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+	void __iomem *usbcmd, *phy_ctrl, *portsc;
+
+	/* Reset USB IP */
+	/* Set run stop bit */
+	/* Send reset command */
+	usbcmd = ppriv->ctrl_regs + UOG_USBCMD;
+	tmp = __raw_readl(usbcmd); /* usb command */
+	tmp &= ~UCMD_RUN_STOP;
+	__raw_writel(tmp, usbcmd);
+	while (__raw_readl(usbcmd) & UCMD_RUN_STOP) {
+		i++;
+		if (i == 1000)
+			break;
+		mdelay(1);
+	}
+	tmp |= UCMD_RESET;
+	__raw_writel(tmp, usbcmd);
+	i = 0;
+	while (__raw_readl(usbcmd) & UCMD_RESET) {
+		i++;
+		if (i == 1000)
+			break;
+		mdelay(1);
+	}
+	mdelay(10);
+
+	/* Reset USBPHY module, set soft reset bit */
+	phy_ctrl = ppriv->phy_regs + HW_USBPHY_CTRL;
+	tmp = __raw_readl(phy_ctrl);
+	tmp |= BM_USBPHY_CTRL_SFTRST;
+	__raw_writel(tmp, phy_ctrl);
+	udelay(10);
+
+	/* clear CLKGATE and SFTRST bits to be out of reset mode*/
+	tmp = __raw_readl(phy_ctrl);
+	tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
+	__raw_writel(tmp, phy_ctrl);
+	udelay(10);
+
+	/* set UTMI xcvr */
+	/* Workaround an IC issue for ehci driver:
+	 * when turn off root hub port power, EHCI set
+	 * PORTSC reserved bits to be 0, but PTW with 0
+	 * means 8 bits tranceiver width, here change
+	 * it back to be 16 bits and do PHY diable and
+	 * then enable.
+	 */
+	portsc = ppriv->ctrl_regs + UOG_PORTSC1;
+	tmp = __raw_readl(portsc);
+	tmp &=  ~PORTSC_PTS_MASK;
+	tmp |= (PORTSC_PTS_UTMI | PORTSC_PTW);
+	__raw_writel(tmp, portsc);
+
+	/* Power up the PHY */
+	__raw_writel(0, ppriv->phy_regs + HW_USBPHY_PWD);
+	return 0;
+}
+
+static int fsl_usbh_init(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+	u32 tmp;
+
+	usb_phy_enable(pdata);
+	/* enable FS/LS device */
+	tmp = __raw_readl(ppriv->phy_regs + HW_USBPHY_CTRL);
+	tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
+	__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL);
+
+	return 0;
+}
+
+static void phy_clock_gate(struct mxs_usb_private_date *ppriv, bool on)
+{
+	u32 tmp;
+
+	if (on) {
+		ppriv->internal_phy_clk_already_on += 1;
+		if (ppriv->internal_phy_clk_already_on == 1) {
+			tmp = BM_USBPHY_CTRL_SFTRST | BM_USBPHY_CTRL_CLKGATE;
+			__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL_CLR);
+		}
+	} else {
+		ppriv->internal_phy_clk_already_on -= 1;
+		if (ppriv->internal_phy_clk_already_on == 0) {
+			tmp = BM_USBPHY_CTRL_CLKGATE;
+			__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL_SET);
+		}
+	}
+	if (WARN_ON(ppriv->internal_phy_clk_already_on < 0))
+		printk(KERN_ERR "please check phy clock ON/OFF sequence\n");
+}
+static int fsl_usb_host_init(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;

arch/arm/mach-mxs/mxs_usb.c line 201

Quoted 10 lines
arch/arm/mach-mxs/mxs_usb.c new file +10 -0
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
+	if (ppriv->phy_regs == NULL)
+		return -ENOMEM;
+
+	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
+	if (ppriv->ctrl_regs == NULL)
+		return -ENOMEM;
+

What about proper cleanup in the error case?

arch/arm/mach-mxs/mxs_usb.c line 204

Quoted 3 lines
arch/arm/mach-mxs/mxs_usb.c new file +3 -0
+	ppriv->usb_clk = clk_get(&pdev->dev, "usb1");
+	if (IS_ERR(ppriv->usb_clk))
+		return PTR_ERR(ppriv->usb_clk);

dto.

arch/arm/mach-mxs/mxs_usb.c line 209

Quoted 5 lines
arch/arm/mach-mxs/mxs_usb.c new file +5 -0
+	clk_enable(ppriv->usb_clk);
+
+	ppriv->usb_phy_clk = clk_get(&pdev->dev, "usb1_phy");
+	if (IS_ERR(ppriv->usb_phy_clk))
+		return PTR_ERR(ppriv->usb_phy_clk);

dto.

Quoted 17 lines
arch/arm/mach-mxs/mxs_usb.c new file +15 -0
+	clk_enable(ppriv->usb_phy_clk);
+
+	phy_clock_gate(ppriv, true);
+	return fsl_usbh_init(pdev);
+}
+
+static int fsl_usb_host_uninit(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	phy_clock_gate(ppriv, false);
+	if (ppriv->usb_phy_clk) {
 
+		clk_disable(ppriv->usb_phy_clk);
+		clk_put(ppriv->usb_phy_clk);

arch/arm/mach-mxs/mxs_usb.c line 234

Quoted 10 lines
arch/arm/mach-mxs/mxs_usb.c new file +10 -0
+	}
+	if (ppriv->usb_clk) {
+		clk_disable(ppriv->usb_clk);
+		clk_put(ppriv->usb_clk);
+	}
+	if (ppriv->phy_regs)
+		iounmap(ppriv->phy_regs);
+	if (ppriv->ctrl_regs)
+		iounmap(ppriv->ctrl_regs);
+

The 'if' clauses are redundant here. fsl_usb_host_uninit() will only be called when fsl_usb_host_init() has succeeded and thus all pointers have been set up correctly (which makes it necessary to have proper cleanup code in fsl_usb_host_init()).

Lothar Wa?mann

Signature · 9 lines
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
#10 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

Quoted 289 lines

-----Original Message-----
From: linux-arm-kernel-bounces at lists.infradead.org [mailto:linux-arm- kernel-bounces at lists.infradead.org] On Behalf Of Lothar Wa?mann
Sent: Monday, July 25, 2011 3:15 PM
To: Lin Tony-B19295
Cc: koen.beel.barco at gmail.com; linux-usb at vger.kernel.org; stern at rowland.harvard.edu; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH v2 5/6] ARM: mxs: add usb phy operations

Hi,

Quoted 9 lines · Tony Lin

add usb phy register definitions and functions usb host driver will use these callback functions to initialize usb phy and change working mode

---
 arch/arm/mach-mxs/Kconfig            |    1 +
 arch/arm/mach-mxs/Makefile           |    1 +
 arch/arm/mach-mxs/mxs_usb.c          |  286

++++++++++++++++++++++++++++++++++

Quoted 32 lines
 arch/arm/mach-mxs/regs-usbphy-mx28.h |  240
++++++++++++++++++++++++++++
 4 files changed, 528 insertions(+), 0 deletions(-)
arch/arm/mach-mxs/Kconfig +1 -0
index 4cd0231..1c4264f 100644
@@ -49,6 +49,7 @@ config MACH_MX28EVK
 	select MXS_HAVE_PLATFORM_MXS_MMC
 	select MXS_HAVE_PLATFORM_MXSFB
 	select MXS_OCOTP
+	select USB_ARCH_HAS_EHCI
 	help
 	  Include support for MX28EVK platform. This includes specific
 	  configurations for the board and its peripherals.
arch/arm/mach-mxs/Makefile +1 -0
index 6c38262..726c49f 100644
@@ -12,5 +12,6 @@ obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
 obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
 obj-$(CONFIG_MODULE_TX28) += module-tx28.o
 obj-$(CONFIG_MACH_TX28)    += mach-tx28.o
+obj-$(CONFIG_USB_EHCI_MXC)   += mxs_usb.o
 
 obj-y += devices/
arch/arm/mach-mxs/mxs_usb.c new file +0 -0
new file mode 100644 index 0000000..01753ea

arch/arm/mach-mxs/mxs_usb.c line 2

Quoted 2 lines
arch/arm/mach-mxs/mxs_usb.c new file +2 -0
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights

Reserved.

Quoted 186 lines
arch/arm/mach-mxs/mxs_usb.c new file +186 -0
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/mx28.h>
+#include "regs-usbphy-mx28.h"
+
+/* EHCI registers: */
+#define UOG_USBCMD		(0x140) /* USB command register */
+#define UOG_USBSTS		(0x144) /* USB status register */
+#define UOG_PORTSC1		(0x184) /* port status and control */
+/* x_PORTSCx */
+#define PORTSC_PTS_MASK		(3 << 30) /* parallel xcvr mask */
+#define PORTSC_PTS_UTMI		(0 << 30) /* UTMI/UTMI+ */
+#define PORTSC_PTW		(1 << 28) /* UTMI width */
+/* USBCMD */
+#define UCMD_RUN_STOP           (1 << 0) /* controller run/stop */
+#define UCMD_RESET		(1 << 1) /* controller reset */
+
+#define HOSTPHY_CONNECT_STATE	(1 << 3)
+#define STS_PCD			(1 << 2) /* port change detect */
+
+struct mxs_usb_private_date {
+	struct clk *usb_clk, *usb_phy_clk;
+	int internal_phy_clk_already_on;
+	void __iomem *phy_regs;		/* usb phy register base */
+	void __iomem *ctrl_regs;	/* usb controller register base */
+};
+
+static inline int fsl_platform_get_usb_connect_status
+			(struct mxs_usb_private_date *ppriv) {
+	u32 status;
+
+	status = __raw_readl(ppriv->phy_regs + HW_USBPHY_STATUS);
+
+	return ((status & HOSTPHY_CONNECT_STATE) == 0); }
+
+/* enable/disable high-speed disconnect detector of phy ctrl */
+static inline void fsl_platform_disconnect_detect
+			(struct mxs_usb_private_date *ppriv, int enable) {
+	if (enable) {
+		__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+		ppriv->phy_regs + HW_USBPHY_CTRL_SET);
+	} else {
+		__raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+		ppriv->phy_regs + HW_USBPHY_CTRL_CLR);
+	}
+}
+
+static void fsl_plt_usbh_irq_handler(struct mxc_usbh_platform_data
+*pdata) {
+	u32			status;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	status = __raw_readl(ppriv->ctrl_regs + UOG_USBSTS);
+
+	if (status & STS_PCD)
+		fsl_platform_disconnect_detect(ppriv,
+			fsl_platform_get_usb_connect_status(ppriv));
+}
+
+static int usb_phy_enable(struct mxc_usbh_platform_data *pdata) {
+	u32 tmp;
+	u32 i = 0;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+	void __iomem *usbcmd, *phy_ctrl, *portsc;
+
+	/* Reset USB IP */
+	/* Set run stop bit */
+	/* Send reset command */
+	usbcmd = ppriv->ctrl_regs + UOG_USBCMD;
+	tmp = __raw_readl(usbcmd); /* usb command */
+	tmp &= ~UCMD_RUN_STOP;
+	__raw_writel(tmp, usbcmd);
+	while (__raw_readl(usbcmd) & UCMD_RUN_STOP) {
+		i++;
+		if (i == 1000)
+			break;
+		mdelay(1);
+	}
+	tmp |= UCMD_RESET;
+	__raw_writel(tmp, usbcmd);
+	i = 0;
+	while (__raw_readl(usbcmd) & UCMD_RESET) {
+		i++;
+		if (i == 1000)
+			break;
+		mdelay(1);
+	}
+	mdelay(10);
+
+	/* Reset USBPHY module, set soft reset bit */
+	phy_ctrl = ppriv->phy_regs + HW_USBPHY_CTRL;
+	tmp = __raw_readl(phy_ctrl);
+	tmp |= BM_USBPHY_CTRL_SFTRST;
+	__raw_writel(tmp, phy_ctrl);
+	udelay(10);
+
+	/* clear CLKGATE and SFTRST bits to be out of reset mode*/
+	tmp = __raw_readl(phy_ctrl);
+	tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
+	__raw_writel(tmp, phy_ctrl);
+	udelay(10);
+
+	/* set UTMI xcvr */
+	/* Workaround an IC issue for ehci driver:
+	 * when turn off root hub port power, EHCI set
+	 * PORTSC reserved bits to be 0, but PTW with 0
+	 * means 8 bits tranceiver width, here change
+	 * it back to be 16 bits and do PHY diable and
+	 * then enable.
+	 */
+	portsc = ppriv->ctrl_regs + UOG_PORTSC1;
+	tmp = __raw_readl(portsc);
+	tmp &=  ~PORTSC_PTS_MASK;
+	tmp |= (PORTSC_PTS_UTMI | PORTSC_PTW);
+	__raw_writel(tmp, portsc);
+
+	/* Power up the PHY */
+	__raw_writel(0, ppriv->phy_regs + HW_USBPHY_PWD);
+	return 0;
+}
+
+static int fsl_usbh_init(struct platform_device *pdev) {
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+	u32 tmp;
+
+	usb_phy_enable(pdata);
+	/* enable FS/LS device */
+	tmp = __raw_readl(ppriv->phy_regs + HW_USBPHY_CTRL);
+	tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 | BM_USBPHY_CTRL_ENUTMILEVEL3);
+	__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL);
+
+	return 0;
+}
+
+static void phy_clock_gate(struct mxs_usb_private_date *ppriv, bool
+on) {
+	u32 tmp;
+
+	if (on) {
+		ppriv->internal_phy_clk_already_on += 1;
+		if (ppriv->internal_phy_clk_already_on == 1) {
+			tmp = BM_USBPHY_CTRL_SFTRST | BM_USBPHY_CTRL_CLKGATE;
+			__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL_CLR);
+		}
+	} else {
+		ppriv->internal_phy_clk_already_on -= 1;
+		if (ppriv->internal_phy_clk_already_on == 0) {
+			tmp = BM_USBPHY_CTRL_CLKGATE;
+			__raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL_SET);
+		}
+	}
+	if (WARN_ON(ppriv->internal_phy_clk_already_on < 0))
+		printk(KERN_ERR "please check phy clock ON/OFF sequence\n"); }
+static int fsl_usb_host_init(struct platform_device *pdev) {
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;

arch/arm/mach-mxs/mxs_usb.c line 201

Quoted 10 lines
arch/arm/mach-mxs/mxs_usb.c new file +10 -0
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
+	if (ppriv->phy_regs == NULL)
+		return -ENOMEM;
+
+	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
+	if (ppriv->ctrl_regs == NULL)
+		return -ENOMEM;
+

What about proper cleanup in the error case?

arch/arm/mach-mxs/mxs_usb.c line 204

Quoted 3 lines
arch/arm/mach-mxs/mxs_usb.c new file +3 -0
+	ppriv->usb_clk = clk_get(&pdev->dev, "usb1");
+	if (IS_ERR(ppriv->usb_clk))
+		return PTR_ERR(ppriv->usb_clk);

dto.

arch/arm/mach-mxs/mxs_usb.c line 209

Quoted 5 lines
arch/arm/mach-mxs/mxs_usb.c new file +5 -0
+	clk_enable(ppriv->usb_clk);
+
+	ppriv->usb_phy_clk = clk_get(&pdev->dev, "usb1_phy");
+	if (IS_ERR(ppriv->usb_phy_clk))
+		return PTR_ERR(ppriv->usb_phy_clk);

dto.

Quoted 22 lines
arch/arm/mach-mxs/mxs_usb.c new file +21 -0
+	clk_enable(ppriv->usb_phy_clk);
+
+	phy_clock_gate(ppriv, true);
+	return fsl_usbh_init(pdev);
+}
+
+static int fsl_usb_host_uninit(struct platform_device *pdev) {
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	phy_clock_gate(ppriv, false);
+	if (ppriv->usb_phy_clk) {
 
+		clk_disable(ppriv->usb_phy_clk);
+		clk_put(ppriv->usb_phy_clk);
+	}
+	if (ppriv->usb_clk) {
+		clk_disable(ppriv->usb_clk);
+		clk_put(ppriv->usb_clk);
+	}
+	if (ppriv->phy_regs)
+		iounmap(ppriv->phy_regs);
Quoted 10 lines

arch/arm/mach-mxs/mxs_usb.c line 234

Quoted 4 lines
arch/arm/mach-mxs/mxs_usb.c new file +3 -0
+	if (ppriv->ctrl_regs)
+		iounmap(ppriv->ctrl_regs);
+

The 'if' clauses are redundant here. fsl_usb_host_uninit() will only be called when fsl_usb_host_init() has succeeded and thus all pointers have been set up correctly (which makes it necessary to have proper cleanup code in fsl_usb_host_init()).

Yes, silly mistake. Will correct it.

Quoted 16 lines

Lothar Wa?mann
--
___________________________________________________________

Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10 Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996

www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#11 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

In reply to Lothar Waßmann
Quoted 3 lines · Lothar Wa?mann

arch/arm/mach-mxs/mxs_usb.c line 188

Quoted 3 lines
arch/arm/mach-mxs/mxs_usb.c new file +3 -0
+	if (WARN_ON(ppriv->internal_phy_clk_already_on < 0))
+		printk(KERN_ERR "please check phy clock ON/OFF sequence\n");
+}

And there should be a blank line here.

Quoted 6 lines
Quoted 6 lines
arch/arm/mach-mxs/mxs_usb.c new file +6 -0
+static int fsl_usb_host_init(struct platform_device *pdev)
+{
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
Quoted 8 lines

arch/arm/mach-mxs/mxs_usb.c line 201

Quoted 7 lines
arch/arm/mach-mxs/mxs_usb.c new file +7 -0
+	if (ppriv->phy_regs == NULL)
+		return -ENOMEM;
+
+	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
+	if (ppriv->ctrl_regs == NULL)
+		return -ENOMEM;
+

What about proper cleanup in the error case?

Doing something like this is probably easiest:

	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
	if (!ppriv->phy_regs || !ppriv_ctrl_regs) {
		iounmap(ppriv->phy_regs);
		iounmap(ppriv->ctrl_regs);
		return -ENOMEM;
	}

As iounmap ignores NULL pointers.

#12 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

Quoted 38 lines

-----Original Message-----
From: Russell King - ARM Linux [mailto:linux at arm.linux.org.uk]
Sent: Monday, July 25, 2011 4:24 PM
To: Lothar Wa?mann
Cc: Lin Tony-B19295; koen.beel.barco at gmail.com; linux-usb at vger.kernel.org; stern at rowland.harvard.edu; linux-arm-kernel at lists.infradead.org
Subject: Re: [PATCH v2 5/6] ARM: mxs: add usb phy operations

Quoted 2 lines · Lothar Wa?mann

Review

Quoted 2 lines
(quoted diff) +2 -0
+	if (WARN_ON(ppriv->internal_phy_clk_already_on < 0))
+		printk(KERN_ERR "please check phy clock ON/OFF sequence\n"); }

And there should be a blank line here.

Quoted 5 lines
Quoted 5 lines
arch/arm/mach-mxs/mxs_usb.c new file +5 -0
+static int fsl_usb_host_init(struct platform_device *pdev) {
+	struct mxc_usbh_platform_data *pdata = pdev->dev.platform_data;
+	struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
Quoted 8 lines

arch/arm/mach-mxs/mxs_usb.c line 201

Quoted 7 lines
arch/arm/mach-mxs/mxs_usb.c new file +7 -0
+	if (ppriv->phy_regs == NULL)
+		return -ENOMEM;
+
+	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
+	if (ppriv->ctrl_regs == NULL)
+		return -ENOMEM;
+

What about proper cleanup in the error case?

Doing something like this is probably easiest:

	ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
	ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
	if (!ppriv->phy_regs || !ppriv_ctrl_regs) {
		iounmap(ppriv->phy_regs);
		iounmap(ppriv->ctrl_regs);
		return -ENOMEM;
	}
Quoted 1 line

As iounmap ignores NULL pointers.

good suggestion, thank you.

#14 lore raw

PATCH v2 5/6 ARM: mxs: add usb phy operations

Quoted 9 lines

Hi,

From what I see in the datasheet of mx23/mx28, phy regs for mx23 and mx28 are the same.
Then it might be better to name the file regs-usbphy-mxs.h instead of regs-usbphy-mx28.h.

Koen

Good idea.

Quoted 588 lines · Tony Lin
Quoted 42 lines

add usb phy register definitions and functions usb host driver will use these callback functions to initialize usb phy and change working mode

---

?arch/arm/mach-mxs/Kconfig ? ? ? ? ? ?| ? ?1 +
?arch/arm/mach-mxs/Makefile ? ? ? ? ? | ? ?1 +
?arch/arm/mach-mxs/mxs_usb.c ? ? ? ? ?| ?286

++++++++++++++++++++++++++++++++++
?arch/arm/mach-mxs/regs-usbphy-mx28.h | ?240
++++++++++++++++++++++++++++
?4 files changed, 528 insertions(+), 0 deletions(-)

arch/arm/mach-mxs/Kconfig +0 -0
index 4cd0231..1c4264f 100644
@@ -49,6 +49,7 @@ config MACH_MX28EVK

? ? ? ?select MXS_HAVE_PLATFORM_MXS_MMC
? ? ? ?select MXS_HAVE_PLATFORM_MXSFB
? ? ? ?select MXS_OCOTP
+ ? ? ? select USB_ARCH_HAS_EHCI
? ? ? ?help
? ? ? ? ?Include support for MX28EVK platform. This includes specific ? ? ? ? ?configurations for the board and its peripherals.

arch/arm/mach-mxs/Makefile +0 -0
index 6c38262..726c49f 100644
@@ -12,5 +12,6 @@ obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o

?obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
?obj-$(CONFIG_MODULE_TX28) += module-tx28.o
?obj-$(CONFIG_MACH_TX28) ? ?+= mach-tx28.o
+obj-$(CONFIG_USB_EHCI_MXC) ? += mxs_usb.o

?obj-y += devices/

arch/arm/mach-mxs/mxs_usb.c new file +0 -0
new file mode 100644 index 0000000..01753ea

arch/arm/mach-mxs/mxs_usb.c line 2

Quoted 2 lines
arch/arm/mach-mxs/mxs_usb.c new file +2 -0
@@ -0,0 +1,286 @@
+/*
+ * Copyright (C) 2009-2011 Freescale Semiconductor, Inc. All Rights

Reserved.

Quoted 39 lines
arch/arm/mach-mxs/mxs_usb.c new file +39 -0
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/irqs.h>
+#include <mach/mx28.h>
+#include "regs-usbphy-mx28.h"
+
+/* EHCI registers: */
+#define UOG_USBCMD ? ? ? ? ? ? (0x140) /* USB command register */
+#define UOG_USBSTS ? ? ? ? ? ? (0x144) /* USB status register */
+#define UOG_PORTSC1 ? ? ? ? ? ?(0x184) /* port status and control */

arch/arm/mach-mxs/mxs_usb.c

Quoted 10 lines
arch/arm/mach-mxs/mxs_usb.c new file +10 -0
+/* x_PORTSCx */
+#define PORTSC_PTS_MASK ? ? ? ? ? ? ? ?(3 << 30) /* parallel xcvr
+mask */ #define PORTSC_PTS_UTMI ? ? ? ? ? ? ? ?(0 << 30) /*
+UTMI/UTMI+ */ #define PORTSC_PTW ? ? ? ? ? ? (1 << 28) /* UTMI width
+*/
+/* USBCMD */
+#define UCMD_RUN_STOP ? ? ? ? ? (1 << 0) /* controller run/stop */
+#define UCMD_RESET ? ? ? ? ? ? (1 << 1) /* controller reset */
+
+#define HOSTPHY_CONNECT_STATE ?(1 << 3) #define

STS_PCD

Quoted 249 lines
arch/arm/mach-mxs/mxs_usb.c new file +242 -0
+(1 << 2) /* port change detect */
+
+struct mxs_usb_private_date {
+ ? ? ? struct clk *usb_clk, *usb_phy_clk;
+ ? ? ? int internal_phy_clk_already_on;
+ ? ? ? void __iomem *phy_regs; ? ? ? ? /* usb phy register base */
+ ? ? ? void __iomem *ctrl_regs; ? ? ? ?/* usb controller register
+base */ };
+
+static inline int fsl_platform_get_usb_connect_status
+ ? ? ? ? ? ? ? ? ? ? ? (struct mxs_usb_private_date *ppriv) {
+ ? ? ? u32 status;
+
+ ? ? ? status = __raw_readl(ppriv->phy_regs + HW_USBPHY_STATUS);
+
+ ? ? ? return ((status & HOSTPHY_CONNECT_STATE) == 0); }
+
+/* enable/disable high-speed disconnect detector of phy ctrl */
+static inline void fsl_platform_disconnect_detect
+ ? ? ? ? ? ? ? ? ? ? ? (struct mxs_usb_private_date *ppriv, int
+enable) {
+ ? ? ? if (enable) {
+ ? ? ? ? ? ? ? __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ ? ? ? ? ? ? ? ppriv->phy_regs + HW_USBPHY_CTRL_SET);
+ ? ? ? } else {
+ ? ? ? ? ? ? ? __raw_writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
+ ? ? ? ? ? ? ? ppriv->phy_regs + HW_USBPHY_CTRL_CLR);
+ ? ? ? }
+}
+
+static void fsl_plt_usbh_irq_handler(struct mxc_usbh_platform_data
+*pdata) {
+ ? ? ? u32 ? ? ? ? ? ? ? ? ? ? status;
+ ? ? ? struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+ ? ? ? status = __raw_readl(ppriv->ctrl_regs + UOG_USBSTS);
+
+ ? ? ? if (status & STS_PCD)
+ ? ? ? ? ? ? ? fsl_platform_disconnect_detect(ppriv,
+ ? ? ? ? ? ? ? ? ? ? ? fsl_platform_get_usb_connect_status(ppriv));
+}
+
+static int usb_phy_enable(struct mxc_usbh_platform_data *pdata) {
+ ? ? ? u32 tmp;
+ ? ? ? u32 i = 0;
+ ? ? ? struct mxs_usb_private_date *ppriv = pdata->ppriv;
+ ? ? ? void __iomem *usbcmd, *phy_ctrl, *portsc;
+
+ ? ? ? /* Reset USB IP */
+ ? ? ? /* Set run stop bit */
+ ? ? ? /* Send reset command */
+ ? ? ? usbcmd = ppriv->ctrl_regs + UOG_USBCMD;
+ ? ? ? tmp = __raw_readl(usbcmd); /* usb command */
+ ? ? ? tmp &= ~UCMD_RUN_STOP;
+ ? ? ? __raw_writel(tmp, usbcmd);
+ ? ? ? while (__raw_readl(usbcmd) & UCMD_RUN_STOP) {
+ ? ? ? ? ? ? ? i++;
+ ? ? ? ? ? ? ? if (i == 1000)
+ ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? mdelay(1);
+ ? ? ? }
+ ? ? ? tmp |= UCMD_RESET;
+ ? ? ? __raw_writel(tmp, usbcmd);
+ ? ? ? i = 0;
+ ? ? ? while (__raw_readl(usbcmd) & UCMD_RESET) {
+ ? ? ? ? ? ? ? i++;
+ ? ? ? ? ? ? ? if (i == 1000)
+ ? ? ? ? ? ? ? ? ? ? ? break;
+ ? ? ? ? ? ? ? mdelay(1);
+ ? ? ? }
+ ? ? ? mdelay(10);
+
+ ? ? ? /* Reset USBPHY module, set soft reset bit */
+ ? ? ? phy_ctrl = ppriv->phy_regs + HW_USBPHY_CTRL;
+ ? ? ? tmp = __raw_readl(phy_ctrl);
+ ? ? ? tmp |= BM_USBPHY_CTRL_SFTRST;
+ ? ? ? __raw_writel(tmp, phy_ctrl);
+ ? ? ? udelay(10);
+
+ ? ? ? /* clear CLKGATE and SFTRST bits to be out of reset mode*/
+ ? ? ? tmp = __raw_readl(phy_ctrl);
+ ? ? ? tmp &= ~(BM_USBPHY_CTRL_CLKGATE | BM_USBPHY_CTRL_SFTRST);
+ ? ? ? __raw_writel(tmp, phy_ctrl);
+ ? ? ? udelay(10);
+
+ ? ? ? /* set UTMI xcvr */
+ ? ? ? /* Workaround an IC issue for ehci driver:
+ ? ? ? ?* when turn off root hub port power, EHCI set
+ ? ? ? ?* PORTSC reserved bits to be 0, but PTW with 0
+ ? ? ? ?* means 8 bits tranceiver width, here change
+ ? ? ? ?* it back to be 16 bits and do PHY diable and
+ ? ? ? ?* then enable.
+ ? ? ? ?*/
+ ? ? ? portsc = ppriv->ctrl_regs + UOG_PORTSC1;
+ ? ? ? tmp = __raw_readl(portsc);
+ ? ? ? tmp &= ?~PORTSC_PTS_MASK;
+ ? ? ? tmp |= (PORTSC_PTS_UTMI | PORTSC_PTW);
+ ? ? ? __raw_writel(tmp, portsc);
+
+ ? ? ? /* Power up the PHY */
+ ? ? ? __raw_writel(0, ppriv->phy_regs + HW_USBPHY_PWD);
+ ? ? ? return 0;
+}
+
+static int fsl_usbh_init(struct platform_device *pdev) {
+ ? ? ? struct mxc_usbh_platform_data *pdata =
+pdev->dev.platform_data;
+ ? ? ? struct mxs_usb_private_date *ppriv = pdata->ppriv;
+ ? ? ? u32 tmp;
+
+ ? ? ? usb_phy_enable(pdata);
+ ? ? ? /* enable FS/LS device */
+ ? ? ? tmp = __raw_readl(ppriv->phy_regs + HW_USBPHY_CTRL);
+ ? ? ? tmp |= (BM_USBPHY_CTRL_ENUTMILEVEL2 |
+ BM_USBPHY_CTRL_ENUTMILEVEL3);
+ ? ? ? __raw_writel(tmp, ppriv->phy_regs + HW_USBPHY_CTRL);
+
+ ? ? ? return 0;
+}
+
+static void phy_clock_gate(struct mxs_usb_private_date *ppriv, bool
+on) {
+ ? ? ? u32 tmp;
+
+ ? ? ? if (on) {
+ ? ? ? ? ? ? ? ppriv->internal_phy_clk_already_on += 1;
+ ? ? ? ? ? ? ? if (ppriv->internal_phy_clk_already_on == 1) {
+ ? ? ? ? ? ? ? ? ? ? ? tmp = BM_USBPHY_CTRL_SFTRST |
+BM_USBPHY_CTRL_CLKGATE;
+ ? ? ? ? ? ? ? ? ? ? ? __raw_writel(tmp, ppriv->phy_regs +
+HW_USBPHY_CTRL_CLR);
+ ? ? ? ? ? ? ? }
+ ? ? ? } else {
+ ? ? ? ? ? ? ? ppriv->internal_phy_clk_already_on -= 1;
+ ? ? ? ? ? ? ? if (ppriv->internal_phy_clk_already_on == 0) {
+ ? ? ? ? ? ? ? ? ? ? ? tmp = BM_USBPHY_CTRL_CLKGATE;
+ ? ? ? ? ? ? ? ? ? ? ? __raw_writel(tmp, ppriv->phy_regs +
+HW_USBPHY_CTRL_SET);
+ ? ? ? ? ? ? ? }
+ ? ? ? }
+ ? ? ? if (WARN_ON(ppriv->internal_phy_clk_already_on < 0))
+ ? ? ? ? ? ? ? printk(KERN_ERR "please check phy clock ON/OFF
+sequence\n"); } static int fsl_usb_host_init(struct platform_device
+*pdev) {
+ ? ? ? struct mxc_usbh_platform_data *pdata =
+pdev->dev.platform_data;
+ ? ? ? struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+ ? ? ? ppriv->phy_regs = ioremap(MX28_USBPHY1_BASE_ADDR, SZ_8K);
+ ? ? ? if (ppriv->phy_regs == NULL)
+ ? ? ? ? ? ? ? return -ENOMEM;
+
+ ? ? ? ppriv->ctrl_regs = ioremap(MX28_USBCTRL1_BASE_ADDR, SZ_8K);
+ ? ? ? if (ppriv->ctrl_regs == NULL)
+ ? ? ? ? ? ? ? return -ENOMEM;
+
+ ? ? ? ppriv->usb_clk = clk_get(&pdev->dev, "usb1");
+ ? ? ? if (IS_ERR(ppriv->usb_clk))
+ ? ? ? ? ? ? ? return PTR_ERR(ppriv->usb_clk);
+ ? ? ? clk_enable(ppriv->usb_clk);
+
+ ? ? ? ppriv->usb_phy_clk = clk_get(&pdev->dev, "usb1_phy");
+ ? ? ? if (IS_ERR(ppriv->usb_phy_clk))
+ ? ? ? ? ? ? ? return PTR_ERR(ppriv->usb_phy_clk);
+ ? ? ? clk_enable(ppriv->usb_phy_clk);
+
+ ? ? ? phy_clock_gate(ppriv, true);
+ ? ? ? return fsl_usbh_init(pdev);
+}
+
+static int fsl_usb_host_uninit(struct platform_device *pdev) {
+ ? ? ? struct mxc_usbh_platform_data *pdata =
+pdev->dev.platform_data;
+ ? ? ? struct mxs_usb_private_date *ppriv = pdata->ppriv;
+
+ ? ? ? phy_clock_gate(ppriv, false);
+ ? ? ? if (ppriv->usb_phy_clk) {
+ ? ? ? ? ? ? ? clk_disable(ppriv->usb_phy_clk);
+ ? ? ? ? ? ? ? clk_put(ppriv->usb_phy_clk);
+ ? ? ? }
+ ? ? ? if (ppriv->usb_clk) {
+ ? ? ? ? ? ? ? clk_disable(ppriv->usb_clk);
+ ? ? ? ? ? ? ? clk_put(ppriv->usb_clk);
+ ? ? ? }
+ ? ? ? if (ppriv->phy_regs)
+ ? ? ? ? ? ? ? iounmap(ppriv->phy_regs);
+ ? ? ? if (ppriv->ctrl_regs)
+ ? ? ? ? ? ? ? iounmap(ppriv->ctrl_regs);
+
+ ? ? ? return 0;
+}
+
+static struct mxs_usb_private_date usbh_private = {
+ ? ? ? .internal_phy_clk_already_on = 0, };
+
+static struct mxc_usbh_platform_data usbh_config = {
+ ? ? ? .init = fsl_usb_host_init,
+ ? ? ? .exit = fsl_usb_host_uninit,
+ ? ? ? .portsc = MXC_EHCI_MODE_ULPI,
+ ? ? ? .otg = NULL,
+ ? ? ? .plt_irq_handler = fsl_plt_usbh_irq_handler,
+ ? ? ? .ppriv = &usbh_private,
+};
+
+/* The resources for kinds of usb devices */ static struct resource
+usbh_resources[] = {
+ ? ? ? {
+ ? ? ? ? ? ? ? .start = MX28_USBCTRL1_BASE_ADDR,
+ ? ? ? ? ? ? ? .end = MX28_USBCTRL1_BASE_ADDR + 0x1ff,
+ ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
+ ? ? ? },
+ ? ? ? {
+ ? ? ? ? ? ? ? .start = MX28_INT_USB1,
+ ? ? ? ? ? ? ? .flags = IORESOURCE_IRQ,
+ ? ? ? },
+};
+
+static int __init usbh_init(void)
+{
+ ? ? ? struct platform_device *pdev;
+ ? ? ? int instance_id = ~(u32) 0;
+ ? ? ? u64 ehci_dmamask = ~(u32) 0;
+
+ ? ? ? if (!cpu_is_mx28())
+ ? ? ? ? ? ? ? return 0;
+
+ ? ? ? pdev = platform_device_register_resndata(NULL, "mxc-ehci",
+ instance_id,
+ ? ? ? ? ? ? ? ? ? ? ? usbh_resources, ARRAY_SIZE(usbh_resources),
+ ? ? ? ? ? ? ? ? ? ? ? &usbh_config, sizeof(struct
+ mxc_usbh_platform_data));
+ ? ? ? if (IS_ERR(pdev)) {
+ ? ? ? ? ? ? ? pr_debug("can't register Host, %ld\n", PTR_ERR(pdev));
+ ? ? ? ? ? ? ? return PTR_ERR(pdev);
+ ? ? ? }
+
+ ? ? ? pdev->dev.coherent_dma_mask = 0xffffffff;
+ ? ? ? pdev->dev.dma_mask = &ehci_dmamask;
+
+ ? ? ? return 0;
+}
+module_init(usbh_init);
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +0 -0
new file mode 100644
index 0000000..2ec273b

arch/arm/mach-mxs/regs-usbphy-mx28.h line 4

Quoted 4 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +4 -0
@@ -0,0 +1,240 @@
+/*
+ * Freescale USBPHY Register Definitions
+ *
+ * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights

Reserved.

Quoted 18 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +18 -0
+ *
+ * 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., 59 Temple Place, Suite 330, Boston, MA
+02111-1307 USA
+ *

arch/arm/mach-mxs/regs-usbphy-mx28.h

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+ *
+ * Xml Revision: 1.52
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___USBPHY_H
+#define __ARCH_ARM___USBPHY_H
+
+
+#define HW_USBPHY_PWD ? ? ? ? ?0x00000000 #define

HW_USBPHY_PWD_SET

arch/arm/mach-mxs/regs-usbphy-mx28.h line 45

Quoted 13 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +13 -0
+0x00000004 #define HW_USBPHY_PWD_CLR ? ? ?0x00000008 #define
+HW_USBPHY_PWD_TOG ? ? ?0x0000000c
+
+#define BM_USBPHY_PWD_RXPWDRX ?0x00100000 #define
+BM_USBPHY_PWD_RXPWDDIFF ? ? ? ?0x00080000 #define
+BM_USBPHY_PWD_RXPWD1PT1 ? ? ? ?0x00040000 #define
+BM_USBPHY_PWD_RXPWDENV 0x00020000
+
+#define BM_USBPHY_PWD_TXPWDV2I 0x00001000 #define
+BM_USBPHY_PWD_TXPWDIBIAS ? ? ? 0x00000800 #define
+BM_USBPHY_PWD_TXPWDFS ?0x00000400
+
+#define HW_USBPHY_TX ? ? ? ? ? 0x00000010 #define

HW_USBPHY_TX_SET

Quoted 15 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +15 -0
+0x00000014 #define HW_USBPHY_TX_CLR ? ? ? 0x00000018 #define
+HW_USBPHY_TX_TOG ? ? ? 0x0000001c
+
+#define BP_USBPHY_TX_USBPHY_TX_EDGECTRL ? ? ? ?26 #define
+BM_USBPHY_TX_USBPHY_TX_EDGECTRL ? ? ? ?0x1C000000 #define
+BF_USBPHY_TX_USBPHY_TX_EDGECTRL(v) ?\
+ ? ? ? ? ? ? ? (((v) << 26) & BM_USBPHY_TX_USBPHY_TX_EDGECTRL)
+#define BM_USBPHY_TX_USBPHY_TX_SYNC_INVERT ? ? 0x02000000 #define
+BM_USBPHY_TX_USBPHY_TX_SYNC_MUX ? ? ? ?0x01000000
+
+#define BM_USBPHY_TX_TXENCAL45DP ? ? ? 0x00200000 #define
+BP_USBPHY_TX_TXCAL45DP 16 #define BM_USBPHY_TX_TXCAL45DP 0x000F0000
+#define BF_USBPHY_TX_TXCAL45DP(v) ?\
+ ? ? ? ? ? ? ? (((v) << 16) & BM_USBPHY_TX_TXCAL45DP) #define
+BM_USBPHY_TX_TXENCAL45DN ? ? ? 0x00002000 #define

arch/arm/mach-mxs/regs-usbphy-mx28.h line 70

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+BP_USBPHY_TX_TXCAL45DN 8 #define BM_USBPHY_TX_TXCAL45DN 0x00000F00
+#define BF_USBPHY_TX_TXCAL45DN(v) ?\
+ ? ? ? ? ? ? ? (((v) << 8) & BM_USBPHY_TX_TXCAL45DN)
+
+#define BP_USBPHY_TX_D_CAL ? ? 0
+#define BM_USBPHY_TX_D_CAL ? ? 0x0000000F #define
+BF_USBPHY_TX_D_CAL(v) ?\
+ ? ? ? ? ? ? ? (((v) << 0) & BM_USBPHY_TX_D_CAL)
+
+#define HW_USBPHY_RX ? ? ? ? ? 0x00000020 #define

HW_USBPHY_RX_SET

arch/arm/mach-mxs/regs-usbphy-mx28.h line 82

Quoted 12 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +12 -0
+0x00000024 #define HW_USBPHY_RX_CLR ? ? ? 0x00000028 #define
+HW_USBPHY_RX_TOG ? ? ? 0x0000002c
+
+#define BM_USBPHY_RX_RXDBYPASS 0x00400000 #define
+BP_USBPHY_RX_DISCONADJ 4 #define BM_USBPHY_RX_DISCONADJ 0x00000070
+#define BF_USBPHY_RX_DISCONADJ(v) ?\
+ ? ? ? ? ? ? ? (((v) << 4) & BM_USBPHY_RX_DISCONADJ) #define
+BP_USBPHY_RX_ENVADJ ? ?0 #define BM_USBPHY_RX_ENVADJ ? ?0x00000007
+#define BF_USBPHY_RX_ENVADJ(v) ?\
+ ? ? ? ? ? ? ? (((v) << 0) & BM_USBPHY_RX_ENVADJ)
+
+#define HW_USBPHY_CTRL ? ? ? ? 0x00000030 #define

HW_USBPHY_CTRL_SET

Quoted 47 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +47 -0
+0x00000034 #define HW_USBPHY_CTRL_CLR ? ? 0x00000038 #define
+HW_USBPHY_CTRL_TOG ? ? 0x0000003c
+
+#define BM_USBPHY_CTRL_SFTRST ?0x80000000 #define
+BM_USBPHY_CTRL_CLKGATE 0x40000000 #define
+BM_USBPHY_CTRL_UTMI_SUSPENDM ? 0x20000000 #define
+BM_USBPHY_CTRL_HOST_FORCE_LS_SE0 ? ? ? 0x10000000 #define
+BM_USBPHY_CTRL_ENAUTOSET_USBCLKS ? ? ? 0x04000000 #define
+BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE ? ?0x02000000 #define
+BM_USBPHY_CTRL_FSDLL_RST_EN ? ?0x01000000 #define
+BM_USBPHY_CTRL_ENVBUSCHG_WKUP ?0x00800000 #define
+BM_USBPHY_CTRL_ENIDCHG_WKUP ? ?0x00400000 #define
+BM_USBPHY_CTRL_ENDPDMCHG_WKUP ?0x00200000 #define
+BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD ? ? ? 0x00100000 #define
+BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE ? ? ? 0x00080000 #define
+BM_USBPHY_CTRL_ENAUTO_PWRON_PLL ? ? ? ?0x00040000 #define
+BM_USBPHY_CTRL_WAKEUP_IRQ ? ? ?0x00020000 #define
+BM_USBPHY_CTRL_ENIRQWAKEUP ? ? 0x00010000 #define
+BM_USBPHY_CTRL_ENUTMILEVEL3 ? ?0x00008000 #define
+BM_USBPHY_CTRL_ENUTMILEVEL2 ? ?0x00004000 #define
+BM_USBPHY_CTRL_DATA_ON_LRADC ? 0x00002000 #define
+BM_USBPHY_CTRL_DEVPLUGIN_IRQ ? 0x00001000 #define
+BM_USBPHY_CTRL_ENIRQDEVPLUGIN ?0x00000800 #define
+BM_USBPHY_CTRL_RESUME_IRQ ? ? ?0x00000400 #define
+BM_USBPHY_CTRL_ENIRQRESUMEDETECT ? ? ? 0x00000200 #define
+BM_USBPHY_CTRL_RESUMEIRQSTICKY 0x00000100 #define
+BM_USBPHY_CTRL_ENOTGIDDETECT ? 0x00000080 #define
+BM_USBPHY_CTRL_DEVPLUGIN_POLARITY ? ? ?0x00000020 #define
+BM_USBPHY_CTRL_ENDEVPLUGINDETECT ? ? ? 0x00000010 #define
+BM_USBPHY_CTRL_HOSTDISCONDETECT_IRQ ? ?0x00000008 #define
+BM_USBPHY_CTRL_ENIRQHOSTDISCON 0x00000004 #define
+BM_USBPHY_CTRL_ENHOSTDISCONDETECT ? ? ?0x00000002
+
+#define HW_USBPHY_STATUS ? ? ? 0x00000040
+
+#define BM_USBPHY_STATUS_RESUME_STATUS 0x00000400 #define
+BM_USBPHY_STATUS_OTGID_STATUS ?0x00000100 #define
+BM_USBPHY_STATUS_DEVPLUGIN_STATUS ? ? ?0x00000040 #define
+BM_USBPHY_STATUS_HOSTDISCONDETECT_STATUS ? ? ? 0x00000008
+
+#define HW_USBPHY_DEBUG ? ? ? ? ? ? ? ?0x00000050 #define
+HW_USBPHY_DEBUG_SET ? ?0x00000054 #define HW_USBPHY_DEBUG_CLR
+0x00000058 #define HW_USBPHY_DEBUG_TOG ? ?0x0000005c
+
+#define BM_USBPHY_DEBUG_CLKGATE ? ? ? ?0x40000000 #define
+BM_USBPHY_DEBUG_HOST_RESUME_DEBUG ? ? ?0x20000000 #define
+BP_USBPHY_DEBUG_SQUELCHRESETLENGTH ? ? 25 #define

arch/arm/mach-mxs/regs-usbphy-mx28.h line 139

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+BM_USBPHY_DEBUG_SQUELCHRESETLENGTH ? ? 0x1E000000 #define
+BF_USBPHY_DEBUG_SQUELCHRESETLENGTH(v) ?\
+ ? ? ? ? ? ? ? (((v) << 25) & BM_USBPHY_DEBUG_SQUELCHRESETLENGTH)
+#define BM_USBPHY_DEBUG_ENSQUELCHRESET 0x01000000 #define
+BP_USBPHY_DEBUG_SQUELCHRESETCOUNT ? ? ?16 #define
+BM_USBPHY_DEBUG_SQUELCHRESETCOUNT ? ? ?0x001F0000 #define
+BF_USBPHY_DEBUG_SQUELCHRESETCOUNT(v) ?\
+ ? ? ? ? ? ? ? (((v) << 16) & BM_USBPHY_DEBUG_SQUELCHRESETCOUNT)
+#define BM_USBPHY_DEBUG_ENTX2RXCOUNT ? 0x00001000 #define
+BP_USBPHY_DEBUG_TX2RXCOUNT ? ? 8 #define

BM_USBPHY_DEBUG_TX2RXCOUNT

arch/arm/mach-mxs/regs-usbphy-mx28.h line 146

Quoted 7 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +7 -0
+0x00000F00 #define BF_USBPHY_DEBUG_TX2RXCOUNT(v) ?\
+ ? ? ? ? ? ? ? (((v) << 8) & BM_USBPHY_DEBUG_TX2RXCOUNT) #define
+BP_USBPHY_DEBUG_ENHSTPULLDOWN ?4 #define
+BM_USBPHY_DEBUG_ENHSTPULLDOWN ?0x00000030 #define
+BF_USBPHY_DEBUG_ENHSTPULLDOWN(v) ?\
+ ? ? ? ? ? ? ? (((v) << 4) & BM_USBPHY_DEBUG_ENHSTPULLDOWN) #define
+BP_USBPHY_DEBUG_HSTPULLDOWN ? ?2 #define

BM_USBPHY_DEBUG_HSTPULLDOWN

Quoted 4 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +4 -0
+0x0000000C #define BF_USBPHY_DEBUG_HSTPULLDOWN(v) ?\
+ ? ? ? ? ? ? ? (((v) << 2) & BM_USBPHY_DEBUG_HSTPULLDOWN) #define
+BM_USBPHY_DEBUG_DEBUG_INTERFACE_HOLD ? 0x00000002 #define
+BM_USBPHY_DEBUG_OTGIDPIOLOCK ? 0x00000001

arch/arm/mach-mxs/regs-usbphy-mx28.h line 160

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+
+#define HW_USBPHY_DEBUG0_STATUS ? ? ? ?0x00000060
+
+#define BP_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT ?26 #define
+BM_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT ?0xFC000000 #define
+BF_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT(v) \
+ ? ? ? ? ? ? ? (((v) << 26) & BM_USBPHY_DEBUG0_STATUS_SQUELCH_COUNT)
+#define BP_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT ? ? ? ?16
+#define BM_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT
+0x03FF0000 #define

BF_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT(v)

Quoted 9 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +9 -0
+\
+ ? ? ? ? ? ? ? (((v) << 16) &
+BM_USBPHY_DEBUG0_STATUS_UTMI_RXERROR_FAIL_COUNT)
+#define BP_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT ? 0 #define
+BM_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT ? 0x0000FFFF #define
+BF_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT(v) ?\
+ ? ? ? ? ? ? ? (((v) << 0) &
+BM_USBPHY_DEBUG0_STATUS_LOOP_BACK_FAIL_COUNT)
+

arch/arm/mach-mxs/regs-usbphy-mx28.h line 179

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+#define HW_USBPHY_DEBUG1 ? ? ? 0x00000070 #define
+HW_USBPHY_DEBUG1_SET ? 0x00000074 #define HW_USBPHY_DEBUG1_CLR
+0x00000078 #define HW_USBPHY_DEBUG1_TOG ? 0x0000007c
+
+#define BP_USBPHY_DEBUG1_ENTAILADJVD ? 13 #define
+BM_USBPHY_DEBUG1_ENTAILADJVD ? 0x00006000 #define
+BF_USBPHY_DEBUG1_ENTAILADJVD(v) ?\
+ ? ? ? ? ? ? ? (((v) << 13) & BM_USBPHY_DEBUG1_ENTAILADJVD) #define
+BM_USBPHY_DEBUG1_ENTX2TX ? ? ? 0x00001000 #define
+BP_USBPHY_DEBUG1_DBG_ADDRESS ? 0 #define

BM_USBPHY_DEBUG1_DBG_ADDRESS

arch/arm/mach-mxs/regs-usbphy-mx28.h line 189

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+0x0000000F #define BF_USBPHY_DEBUG1_DBG_ADDRESS(v) ?\
+ ? ? ? ? ? ? ? (((v) << 0) & BM_USBPHY_DEBUG1_DBG_ADDRESS)
+
+#define HW_USBPHY_VERSION ? ? ?0x00000080
+
+#define BP_USBPHY_VERSION_MAJOR ? ? ? ?24 #define
+BM_USBPHY_VERSION_MAJOR ? ? ? ?0xFF000000 #define
+BF_USBPHY_VERSION_MAJOR(v) \
+ ? ? ? ? ? ? ? (((v) << 24) & BM_USBPHY_VERSION_MAJOR) #define
+BP_USBPHY_VERSION_MINOR ? ? ? ?16 #define

BM_USBPHY_VERSION_MINOR

arch/arm/mach-mxs/regs-usbphy-mx28.h line 196

Quoted 7 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +7 -0
+0x00FF0000 #define BF_USBPHY_VERSION_MINOR(v) ?\
+ ? ? ? ? ? ? ? (((v) << 16) & BM_USBPHY_VERSION_MINOR) #define
+BP_USBPHY_VERSION_STEP 0 #define BM_USBPHY_VERSION_STEP 0x0000FFFF
+#define BF_USBPHY_VERSION_STEP(v) ?\
+ ? ? ? ? ? ? ? (((v) << 0) & BM_USBPHY_VERSION_STEP)
+
+#define HW_USBPHY_IP ? ? ? ? ? 0x00000090 #define

HW_USBPHY_IP_SET

Quoted 15 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +15 -0
+0x00000094 #define HW_USBPHY_IP_CLR ? ? ? 0x00000098 #define
+HW_USBPHY_IP_TOG ? ? ? 0x0000009c
+
+#define BP_USBPHY_IP_DIV_SEL ? 23
+#define BM_USBPHY_IP_DIV_SEL ? 0x01800000 #define
+BF_USBPHY_IP_DIV_SEL(v) ?\
+ ? ? ? ? ? ? ? (((v) << 23) & BM_USBPHY_IP_DIV_SEL) #define
+BV_USBPHY_IP_DIV_SEL__DEFAULT ? 0x0 #define
+BV_USBPHY_IP_DIV_SEL__LOWER ? ? 0x1 #define
+BV_USBPHY_IP_DIV_SEL__LOWEST ? ?0x2 #define
+BV_USBPHY_IP_DIV_SEL__UNDEFINED 0x3 #define BP_USBPHY_IP_LFR_SEL ? 21
+#define BM_USBPHY_IP_LFR_SEL ? 0x00600000 #define
+BF_USBPHY_IP_LFR_SEL(v) ?\
+ ? ? ? ? ? ? ? (((v) << 21) & BM_USBPHY_IP_LFR_SEL) #define
+BV_USBPHY_IP_LFR_SEL__DEFAULT ? 0x0 #define

arch/arm/mach-mxs/regs-usbphy-mx28.h line 221

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +10 -0
+BV_USBPHY_IP_LFR_SEL__TIMES_2 ? 0x1 #define
+BV_USBPHY_IP_LFR_SEL__TIMES_05 ?0x2 #define
+BV_USBPHY_IP_LFR_SEL__UNDEFINED 0x3 #define BP_USBPHY_IP_CP_SEL ? ?19
+#define BM_USBPHY_IP_CP_SEL ? ?0x00180000 #define
+BF_USBPHY_IP_CP_SEL(v) ?\
+ ? ? ? ? ? ? ? (((v) << 19) & BM_USBPHY_IP_CP_SEL) #define
+BV_USBPHY_IP_CP_SEL__DEFAULT ? 0x0 #define
+BV_USBPHY_IP_CP_SEL__TIMES_2 ? 0x1 #define
+BV_USBPHY_IP_CP_SEL__TIMES_05 ?0x2 #define
+BV_USBPHY_IP_CP_SEL__UNDEFINED 0x3 #define

BM_USBPHY_IP_TSTI_TX_DP

Quoted 10 lines
arch/arm/mach-mxs/regs-usbphy-mx28.h new file +5 -1
+0x00040000 #define BM_USBPHY_IP_TSTI_TX_DM ? ? ? ?0x00020000 #define
+BM_USBPHY_IP_ANALOG_TESTMODE ? 0x00010000 #define
+BM_USBPHY_IP_EN_USB_CLKS ? ? ? 0x00000004 #define
+BM_USBPHY_IP_PLL_LOCKED ? ? ? ?0x00000002 #define
+BM_USBPHY_IP_PLL_POWER 0x00000001 #endif /* __ARCH_ARM___USBPHY_H */
--

1.7.0.4

author
#15 lore raw

PATCH v2 6/6 ARM: mxs: add usb host function to default config

In reply to Tony Lin

change mxs_defconfig.

---
 arch/arm/configs/mxs_defconfig |    8 +++++++-
 1 files changed, 7 insertions(+), 1 deletions(-)
arch/arm/configs/mxs_defconfig +7 -1
index db2cb7d..0a187a2 100644
@@ -87,8 +87,14 @@ CONFIG_GPIO_SYSFS=y
 # CONFIG_HWMON is not set
 # CONFIG_MFD_SUPPORT is not set
 CONFIG_DISPLAY_SUPPORT=m
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+CONFIG_USB_EHCI_TT_NEWSCHED=y
+CONFIG_USB_EHCI_MXC=y
 CONFIG_MMC=y
 CONFIG_MMC_MXS=y
 CONFIG_RTC_CLASS=y
Signature · 1 line
1.7.0.4