Patchwork [U-Boot,4/4] Armada100: Adds support for USB on gplugD

login
register
mail settings
Submitter Ajay Bhargav
Date July 8, 2011, 6:22 a.m.
Message ID <1310106168-17166-4-git-send-email-ajay.bhargav@einfochips.com>
Download mbox | patch
Permalink /patch/103770/
State Superseded
Delegated to: Marek Vasut
Headers show

Comments

Ajay Bhargav - July 8, 2011, 6:22 a.m.
Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
---
 arch/arm/cpu/arm926ejs/armada100/Makefile          |    1 +
 arch/arm/cpu/arm926ejs/armada100/cpu.c             |   14 ++
 arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c      |  154 ++++++++++++++++++++
 arch/arm/include/asm/arch-armada100/cpu.h          |   31 ++++
 .../include/asm/arch-armada100/pxa168_usb_phy.h    |  115 +++++++++++++++
 drivers/usb/host/Makefile                          |    1 +
 drivers/usb/host/ehci-pxa168.c                     |   58 ++++++++
 include/configs/gplugd.h                           |   20 +++
 8 files changed, 394 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
 create mode 100644 arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h
 create mode 100644 drivers/usb/host/ehci-pxa168.c
Wolfgang Denk - July 8, 2011, 8:12 a.m.
Dear Ajay Bhargav,

In message <1310106168-17166-4-git-send-email-ajay.bhargav@einfochips.com> you wrote:
...
> diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
> index c21938e..2db42a0 100644
> --- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
> +++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
...
> +
> +/* Both USB host as well as USB ETH requires this function.
> + * So moving it from usb eth file (usbeth/mv_u2o_ctl.c) to this common file */
> +/* CHIP ID:
> + * Z0: 0x00a0c910
> + * Y0: 0x00f0c910
> + */

Incorrect multiline comment style.  Please fix globally.

...
> --- /dev/null
> +++ b/arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
> @@ -0,0 +1,154 @@
...
> +#undef DEBUG

Please don't undefine what is not defined anyway.

> +#if DEBUG
> +static unsigned int usb_debug = DEBUG;

NAK.  "DEBUG' in U-Boot is either not defined, or defined without a
specific value.  This code assumes it is defined as a numeric value,
which is an incorrect assumption.

> +#else
> +#define usb_debug 0     /* gcc will remove all the debug code for us */
> +#endif
> +
> +/*****************************************************************************
> + * The registers read/write routines
> + ******************************************************************************/
> +static unsigned usb_sph_get(unsigned *base, unsigned offset)
> +{
> +	return readl(base + (offset>>2));
> +}

NAK.  Please use C structs, and use the standard I/O accessors
directly.

> +static void usb_sph_set(unsigned *base, unsigned offset, unsigned value)
> +{
> +	unsigned int reg;
> +
> +	if (usb_debug)
> +		printf("base %p off %x base+off %p read %x\n", base, offset,
> +		(base + (offset>>2)), *(unsigned *)(base + (offset>>2)));

Braces needed for multiline statements. Please fix globally.

> +static void usb_sph_clear(unsigned *base, unsigned offset, unsigned value)
...
> +static void usb_sph_write(unsigned *base, unsigned offset, unsigned value)

NAK, see above.

> +	/* Turn on Main PMU clocks ACGR */
> +	writel(0x1EFFFF, 0xD4051024);

Please provide #defines for these magic numbers.

> +	/* USB clk reset */
> +	writel(0x18, PMUA_USB_CLK_RES_CTRL);
> +	writel(0x1b, PMUA_USB_CLK_RES_CTRL);
> +
> +	/* enable the pull up */
> +	if (!cpu_is_pxa910_168()) {
> +		if (pxa910_is_z0()) {
> +			writel((1<<20), (0xc0000004));
> +		} else {
> +			tmp = readl(0xd4207004);
> +			tmp |= (1<<20);
> +			writel(tmp, (0xd4207004));

Ditto.

...
> --- a/arch/arm/include/asm/arch-armada100/cpu.h
> +++ b/arch/arm/include/asm/arch-armada100/cpu.h
> @@ -28,6 +28,36 @@
>  #include <asm/io.h>
>  #include <asm/system.h>
>  
> +#define CPUID_ID                0
> +
> +#define __stringify_1(x)        #x
> +#define __stringify(x)          __stringify_1(x)
> +
> +#define read_cpuid(reg)							\
> +	({								\
> +		unsigned int __val;					\
> +		asm("mrc        p15, 0, %0, c0, c0, " __stringify(reg)	\
> +		    : "=r" (__val)					\
> +		    :							\
> +		    : "cc");						\
> +		__val;							\
> +	})
> +
> +#define __cpu_is_pxa910_168(id)						\
> +	({								\
> +		unsigned int _id = (id) & 0xffff;			\
> +		_id == 0x9263 || _id == 0x8400;				\
> +	})
> +
> +
> +#define cpu_is_pxa910_168()						\
> +	({								\
> +		unsigned int id = read_cpuid(CPUID_ID);			\
> +		__cpu_is_pxa910_168(id);				\
> +	})

CodingStyle says:

"Generally, inline functions are preferable to macros resembling functions."

...
> +/* ASPEN */
> +#define UTMI_REVISION           0x0
> +#define UTMI_CTRL               0x4
> +#define UTMI_PLL                0x8
> +#define UTMI_TX                 0xc
> +#define UTMI_RX                 0x10
> +#define UTMI_IVREF              0x14
> +#define UTMI_T0                 0x18
> +#define UTMI_T1                 0x1c
> +#define UTMI_T2                 0x20
> +#define UTMI_T3                 0x24
> +#define UTMI_T4                 0x28
> +#define UTMI_T5                 0x2c
> +#define UTMI_RESERVE            0x30
> +#define UTMI_USB_INT            0x34
> +#define UTMI_DBG_CTL            0x38
> +#define UTMI_OTG_ADDON          0x3c
etc.

NAK. Please use C structs instead.

...
> --- a/drivers/usb/host/Makefile
> +++ b/drivers/usb/host/Makefile
> @@ -46,6 +46,7 @@ COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o
>  COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o
>  COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
>  COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
> +COBJS-$(CONFIG_USB_EHCI_PXA168) += ehci-pxa168.o

Please keep lists sorted.  Fix globally.

...
> +/*
> + * Destroy the appropriate control structures corresponding
> + * the the EHCI host controller.
> + */
> +int ehci_hcd_stop(void)
> +{
> +	return 0;
> +}

This is probably not sufficient to really stop the EHCI controller,
which is a mandatory action here.


Best regards,

Wolfgang Denk
Prafulla Wadaskar - July 8, 2011, 3:26 p.m.
> -----Original Message-----
> From: Ajay Bhargav [mailto:ajay.bhargav@einfochips.com]
> Sent: Friday, July 08, 2011 11:53 AM
> To: Prafulla Wadaskar
> Cc: u-boot@lists.denx.de; Ajay Bhargav
> Subject: [PATCH 4/4] Armada100: Adds support for USB on gplugD
> 
> Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
> ---
>  arch/arm/cpu/arm926ejs/armada100/Makefile          |    1 +
>  arch/arm/cpu/arm926ejs/armada100/cpu.c             |   14 ++
>  arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c      |  154
> ++++++++++++++++++++
>  arch/arm/include/asm/arch-armada100/cpu.h          |   31 ++++
>  .../include/asm/arch-armada100/pxa168_usb_phy.h    |  115
> +++++++++++++++
>  drivers/usb/host/Makefile                          |    1 +
>  drivers/usb/host/ehci-pxa168.c                     |   58 ++++++++

The file name should be mv_ehci.c

>  include/configs/gplugd.h                           |   20 +++
>  8 files changed, 394 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
>  create mode 100644 arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h
>  create mode 100644 drivers/usb/host/ehci-pxa168.c

No pxa reference in the code, replace them by ARMD, armada100, ARMADA100

Split the patch as UAB echi driver support for armada followed by enabling it for your board.

Regards..
Prafulla ..
Ajay Bhargav - July 11, 2011, 4:45 a.m.
Hi Prafulla,

You mean file names should be like uad_u2h.c or armd_u2h.c?

Thanks again.

Regards,
Ajay Bhargav

----- Original Message -----
From: "Prafulla Wadaskar" <prafulla@marvell.com>
To: "Ajay Bhargav" <ajay.bhargav@einfochips.com>
Cc: u-boot@lists.denx.de, "Ashish Karkare" <akarkare@marvell.com>, "Prabhanjan Sarnaik" <sarnaik@marvell.com>
Sent: Friday, July 8, 2011 8:56:53 PM
Subject: RE: [PATCH 4/4] Armada100: Adds support for USB on gplugD



> -----Original Message-----
> From: Ajay Bhargav [mailto:ajay.bhargav@einfochips.com]
> Sent: Friday, July 08, 2011 11:53 AM
> To: Prafulla Wadaskar
> Cc: u-boot@lists.denx.de; Ajay Bhargav
> Subject: [PATCH 4/4] Armada100: Adds support for USB on gplugD
> 
> Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
> ---
>  arch/arm/cpu/arm926ejs/armada100/Makefile          |    1 +
>  arch/arm/cpu/arm926ejs/armada100/cpu.c             |   14 ++
>  arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c      |  154
> ++++++++++++++++++++
>  arch/arm/include/asm/arch-armada100/cpu.h          |   31 ++++
>  .../include/asm/arch-armada100/pxa168_usb_phy.h    |  115
> +++++++++++++++
>  drivers/usb/host/Makefile                          |    1 +
>  drivers/usb/host/ehci-pxa168.c                     |   58 ++++++++

The file name should be mv_ehci.c

>  include/configs/gplugd.h                           |   20 +++
>  8 files changed, 394 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
>  create mode 100644 arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h
>  create mode 100644 drivers/usb/host/ehci-pxa168.c

No pxa reference in the code, replace them by ARMD, armada100, ARMADA100

Split the patch as UAB echi driver support for armada followed by enabling it for your board.

Regards..
Prafulla ..
Prafulla Wadaskar - July 11, 2011, 5 a.m.
> -----Original Message-----
> From: Ajay Bhargav [mailto:ajay.bhargav@einfochips.com]
> Sent: Monday, July 11, 2011 10:15 AM
> To: Prafulla Wadaskar
> Cc: u-boot@lists.denx.de; Ashish Karkare; Prabhanjan Sarnaik
> Subject: Re: [PATCH 4/4] Armada100: Adds support for USB on gplugD
> 
> Hi Prafulla,
> 
> You mean file names should be like uad_u2h.c or armd_u2h.c?

Avoid top posting
See my comments inlined.

> 
> Thanks again.
> 
> Regards,
> Ajay Bhargav
> 
> ----- Original Message -----
> From: "Prafulla Wadaskar" <prafulla@marvell.com>
> To: "Ajay Bhargav" <ajay.bhargav@einfochips.com>
> Cc: u-boot@lists.denx.de, "Ashish Karkare" <akarkare@marvell.com>,
> "Prabhanjan Sarnaik" <sarnaik@marvell.com>
> Sent: Friday, July 8, 2011 8:56:53 PM
> Subject: RE: [PATCH 4/4] Armada100: Adds support for USB on gplugD
> 
> 
> 
> > -----Original Message-----
> > From: Ajay Bhargav [mailto:ajay.bhargav@einfochips.com]
> > Sent: Friday, July 08, 2011 11:53 AM
> > To: Prafulla Wadaskar
> > Cc: u-boot@lists.denx.de; Ajay Bhargav
> > Subject: [PATCH 4/4] Armada100: Adds support for USB on gplugD
> >
> > Signed-off-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
> > ---
> >  arch/arm/cpu/arm926ejs/armada100/Makefile          |    1 +
> >  arch/arm/cpu/arm926ejs/armada100/cpu.c             |   14 ++
> >  arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c      |  154
> > ++++++++++++++++++++
> >  arch/arm/include/asm/arch-armada100/cpu.h          |   31 ++++
> >  .../include/asm/arch-armada100/pxa168_usb_phy.h    |  115
> > +++++++++++++++
> >  drivers/usb/host/Makefile                          |    1 +
> >  drivers/usb/host/ehci-pxa168.c                     |   58 ++++++++
> 
> The file name should be mv_ehci.c
> 
> >  include/configs/gplugd.h                           |   20 +++
> >  8 files changed, 394 insertions(+), 0 deletions(-)
> >  create mode 100644 arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c

Any file in this folder should not contain soc-name prefix, if it targeted to specific SOC in that family it should start with armada100_<peripheral>.c/h

> >  create mode 100644 arch/arm/include/asm/arch-
> armada100/pxa168_usb_phy.h

Same here..

> >  create mode 100644 drivers/usb/host/ehci-pxa168.c

This should be preferably mv_ehci.c/h if it is not generic then mv_armava100.c/h

Remember any driver here should be designed more generic way so that it can be supported for other SoCs in that family


Regards..
Prafulla . .
Ajay Bhargav - July 11, 2011, 5:10 a.m.
Hi Prafulla,

> Avoid top posting
> See my comments inlined.

I will rather avoid quoting old message as suggested by Wolfgang.

> Remember any driver here should be designed more generic way so that it can be supported for other SoCs in that family

Thank you for comments. I will keep that in mind.

Regards,
Ajay Bhargav

Patch

diff --git a/arch/arm/cpu/arm926ejs/armada100/Makefile b/arch/arm/cpu/arm926ejs/armada100/Makefile
index 76bd06d..8f931ff 100644
--- a/arch/arm/cpu/arm926ejs/armada100/Makefile
+++ b/arch/arm/cpu/arm926ejs/armada100/Makefile
@@ -27,6 +27,7 @@  include $(TOPDIR)/config.mk
 LIB	= $(obj)lib$(SOC).o
 
 COBJS-y	= cpu.o timer.o dram.o
+COBJS-${CONFIG_USB_EHCI_PXA168} += pxa168_u2h.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
 OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS-y))
diff --git a/arch/arm/cpu/arm926ejs/armada100/cpu.c b/arch/arm/cpu/arm926ejs/armada100/cpu.c
index c21938e..2db42a0 100644
--- a/arch/arm/cpu/arm926ejs/armada100/cpu.c
+++ b/arch/arm/cpu/arm926ejs/armada100/cpu.c
@@ -106,3 +106,17 @@  void i2c_clk_enable(void)
 {
 }
 #endif
+
+/* Both USB host as well as USB ETH requires this function.
+ * So moving it from usb eth file (usbeth/mv_u2o_ctl.c) to this common file */
+/* CHIP ID:
+ * Z0: 0x00a0c910
+ * Y0: 0x00f0c910
+ */
+int pxa910_is_z0(void)
+{
+	if ((readl(CHIP_ID) & 0x00f00000) == 0x00a00000)
+		return 1;
+
+	return 0;
+}
diff --git a/arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c b/arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
new file mode 100644
index 0000000..99d94f0
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/armada100/pxa168_u2h.c
@@ -0,0 +1,154 @@ 
+/**************************************************************************
+ *
+ * Copyright (c) 2009, 2010 Marvell International Ltd.
+ *
+ * This file is part of GNU program.
+ *
+ * GNU 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.
+ *
+ * GNU 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, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ *************************************************************************/
+
+#include <common.h>
+
+#include <linux/types.h>
+#include <asm/errno.h>
+#include <asm/io.h>
+#include <common.h>
+#include <config.h>
+#include <net.h>
+#include <command.h>
+#include <malloc.h>
+
+#include <asm/arch/cpu.h>
+#include <asm/arch/pxa168_usb_phy.h>
+
+#define PXA168_USB_SPH_PHY_BASE         CONFIG_USB_SPH_PHY_BASE
+#define PMUA_USB_CLK_RES_CTRL   (0xd428285c)
+
+#undef DEBUG
+
+#if DEBUG
+static unsigned int usb_debug = DEBUG;
+#else
+#define usb_debug 0     /* gcc will remove all the debug code for us */
+#endif
+
+/*****************************************************************************
+ * The registers read/write routines
+ ******************************************************************************/
+static unsigned usb_sph_get(unsigned *base, unsigned offset)
+{
+	return readl(base + (offset>>2));
+}
+
+static void usb_sph_set(unsigned *base, unsigned offset, unsigned value)
+{
+	unsigned int reg;
+
+	if (usb_debug)
+		printf("base %p off %x base+off %p read %x\n", base, offset,
+		(base + (offset>>2)), *(unsigned *)(base + (offset>>2)));
+	reg = readl(base + (offset>>2));
+	reg |= value;
+	writel(reg, base + (offset>>2));
+	readl(base + (offset>>2));
+}
+
+static void usb_sph_clear(unsigned *base, unsigned offset, unsigned value)
+{
+	unsigned int reg;
+
+	reg = readl(base + (offset>>2));
+	reg &= ~value;
+	writel(reg, base + (offset>>2));
+	readl(base + (offset>>2));
+}
+
+static void usb_sph_write(unsigned *base, unsigned offset, unsigned value)
+{
+	writel(value, base + (offset>>2));
+	readl(base + (offset>>2));
+}
+
+static void usb_sph_phy_init(unsigned *base)
+{
+	if (usb_debug)
+		printf("init phy\n\n");
+
+	usb_sph_set(base, U2PCTRL, 1<<UTMI_CTRL_INPKT_DELAY_SOF_SHIFT);
+	usb_sph_set(base, U2PCTRL, 1<<UTMI_CTRL_PLL_PWR_UP_SHIFT);
+	udelay(1000);
+	usb_sph_set(base, U2PCTRL, 1<<UTMI_CTRL_PWR_UP_SHIFT);
+
+	/* aspen specific*/
+	if (cpu_is_pxa910_168())
+		/* Turn on UTMI PHY OTG extension */
+		usb_sph_write(base, 0x3C, 1);
+
+	usb_sph_clear(base, U2PPLL, UTMI_PLL_FBDIV_MASK | UTMI_PLL_REFDIV_MASK);
+	usb_sph_set(base, U2PPLL, 0xee<<UTMI_PLL_FBDIV_SHIFT |
+			0xb<<UTMI_PLL_REFDIV_SHIFT);
+	usb_sph_set(base, U2PTX, 0x80000);
+
+	/* calibrate */
+	while ((usb_sph_get(base, U2PPLL) & PLL_READY) == 0)
+		;
+
+	/* toggle VCOCAL_START bit of U2PPLL */
+	udelay(200);
+	usb_sph_set(base, U2PPLL, VCOCAL_START);
+	udelay(40);
+	usb_sph_clear(base, U2PPLL, VCOCAL_START);
+
+	/* toggle REG_RCAL_START bit of U2PTX */
+	udelay(200);
+	usb_sph_set(base, U2PTX, REG_RCAL_START);
+	udelay(400);
+	usb_sph_clear(base, U2PTX, REG_RCAL_START);
+
+	/* make sure phy is ready */
+	while ((usb_sph_get(base, U2PPLL) & PLL_READY) == 0)
+		;
+}
+
+
+/* PXA USB SPH init */
+/* Initialize USB host controller's UTMI physical interface */
+void pxa168_usb_sph_init(void)
+{
+	u32 tmp;
+
+	/* Turn on Main PMU clocks ACGR */
+	writel(0x1EFFFF, 0xD4051024);
+
+	/* USB clk reset */
+	writel(0x18, PMUA_USB_CLK_RES_CTRL);
+	writel(0x1b, PMUA_USB_CLK_RES_CTRL);
+
+	/* enable the pull up */
+	if (!cpu_is_pxa910_168()) {
+		if (pxa910_is_z0()) {
+			writel((1<<20), (0xc0000004));
+		} else {
+			tmp = readl(0xd4207004);
+			tmp |= (1<<20);
+			writel(tmp, (0xd4207004));
+		}
+	}
+
+	/* init the UTMI transceiver */
+	usb_sph_phy_init((unsigned *)PXA168_USB_SPH_PHY_BASE);
+}
diff --git a/arch/arm/include/asm/arch-armada100/cpu.h b/arch/arm/include/asm/arch-armada100/cpu.h
index 6ab3bf9..7c62bfa 100644
--- a/arch/arm/include/asm/arch-armada100/cpu.h
+++ b/arch/arm/include/asm/arch-armada100/cpu.h
@@ -28,6 +28,36 @@ 
 #include <asm/io.h>
 #include <asm/system.h>
 
+#define CPUID_ID                0
+
+#define __stringify_1(x)        #x
+#define __stringify(x)          __stringify_1(x)
+
+#define read_cpuid(reg)							\
+	({								\
+		unsigned int __val;					\
+		asm("mrc        p15, 0, %0, c0, c0, " __stringify(reg)	\
+		    : "=r" (__val)					\
+		    :							\
+		    : "cc");						\
+		__val;							\
+	})
+
+#define __cpu_is_pxa910_168(id)						\
+	({								\
+		unsigned int _id = (id) & 0xffff;			\
+		_id == 0x9263 || _id == 0x8400;				\
+	})
+
+
+#define cpu_is_pxa910_168()						\
+	({								\
+		unsigned int id = read_cpuid(CPUID_ID);			\
+		__cpu_is_pxa910_168(id);				\
+	})
+
+#define CHIP_ID    0xd4282c00
+
 /*
  * CPU Interface Registers
  * Refer Datasheet Appendix A.2
@@ -49,6 +79,7 @@  struct armd1cpu_registers {
  */
 u32 armd1_sdram_base(int);
 u32 armd1_sdram_size(int);
+int pxa910_is_z0(void);
 
 #ifdef CONFIG_PXASDH
 int pxa_sdh_init(bd_t *);
diff --git a/arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h b/arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h
new file mode 100644
index 0000000..752ad5c
--- /dev/null
+++ b/arch/arm/include/asm/arch-armada100/pxa168_usb_phy.h
@@ -0,0 +1,115 @@ 
+/**************************************************************************
+ *
+ * Copyright (c) 2009, 2010 Marvell International Ltd.
+ *
+ * This file is part of GNU program.
+ *
+ * GNU 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.
+ *
+ * GNU 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, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ *************************************************************************/
+
+#ifndef PXA168_USB_PHY
+#define PXA168_USB_PHY
+
+/* ASPEN */
+#define UTMI_REVISION           0x0
+#define UTMI_CTRL               0x4
+#define UTMI_PLL                0x8
+#define UTMI_TX                 0xc
+#define UTMI_RX                 0x10
+#define UTMI_IVREF              0x14
+#define UTMI_T0                 0x18
+#define UTMI_T1                 0x1c
+#define UTMI_T2                 0x20
+#define UTMI_T3                 0x24
+#define UTMI_T4                 0x28
+#define UTMI_T5                 0x2c
+#define UTMI_RESERVE            0x30
+#define UTMI_USB_INT            0x34
+#define UTMI_DBG_CTL            0x38
+#define UTMI_OTG_ADDON          0x3c
+
+/* TTC/TD */
+#define U2PRSRVD        0x0
+#define U2PCTRL         0x4
+#define U2PPLL          0x8
+#define U2PTX           0xc
+#define U2PRX           0x10
+#define U2PIVREF        0x14
+#define U2PT0           0x18
+#define U2PT1           0x1c
+#define U2PT2           0x20
+#define U2PID           0x24
+#define U2PINT          0x28
+#define U2PDBGCTL       0x2c
+#define U2PCTL1         0x30
+#define U2PT3           0x34
+#define U2PT4           0x38
+#define U2PT5           0x3c
+
+/* For UTMICTRL Register */
+#define UTMI_CTRL_USB_CLK_EN                    (1<<31)
+/* pxa168 */
+#define UTMI_CTRL_SUSPEND_SET1                  (1<<30)
+#define UTMI_CTRL_SUSPEND_SET2                  (1<<29)
+#define UTMI_CTRL_RXBUF_PDWN                    (1<<24)
+#define UTMI_CTRL_TXBUF_PDWN                    (1<<11)
+
+#define UTMI_CTRL_INPKT_DELAY_SHIFT             30
+#define UTMI_CTRL_INPKT_DELAY_SOF_SHIFT		28
+#define UTMI_CTRL_PU_REF_SHIFT			20
+#define UTMI_CTRL_ARC_PULLDN_SHIFT              12
+#define UTMI_CTRL_PLL_PWR_UP_SHIFT              1
+#define UTMI_CTRL_PWR_UP_SHIFT                  0
+/* For UTMI_PLL Register */
+#define UTMI_PLL_CLK_BLK_EN_SHIFT               24
+#define UTMI_PLL_FBDIV_SHIFT                    4
+#define UTMI_PLL_REFDIV_SHIFT                   0
+#define UTMI_PLL_FBDIV_MASK                     0x00000FF0
+#define UTMI_PLL_REFDIV_MASK                    0x0000000F
+#define UTMI_PLL_ICP_MASK                       0x00007000
+#define UTMI_PLL_KVCO_MASK                      0x00031000
+#define UTMI_PLL_PLLCALI12_SHIFT		29
+#define UTMI_PLL_PLLCALI12_MASK			(0x3<<29)
+#define UTMI_PLL_PLLVDD18_SHIFT			27
+#define UTMI_PLL_PLLVDD18_MASK			(0x3<<27)
+#define UTMI_PLL_PLLVDD12_SHIFT			25
+#define UTMI_PLL_PLLVDD12_MASK			(0x3<<25)
+#define UTMI_PLL_KVCO_SHIFT			15
+#define UTMI_PLL_ICP_SHIFT			12
+/* For UTMI_TX Register */
+#define UTMI_TX_LOW_VDD_EN_SHIFT                11
+#define UTMI_TX_IMPCAL_VTH_SHIFT                14
+#define UTMI_TX_IMPCAL_VTH_MASK                 (0x7<<14)
+#define UTMI_TX_CK60_PHSEL_SHIFT                17
+#define UTMI_TX_CK60_PHSEL_MASK                 (0xf<<17)
+#define UTMI_TX_TXVDD12_SHIFT                   22
+#define UTMI_TX_TXVDD12_MASK                    (0x3<<22)
+/* For UTMI_RX Register */
+#define UTMI_RX_SQ_THRESH_SHIFT                 4
+#define UTMI_RX_SQ_THRESH_MASK                  (0xf<<4)
+#define UTMI_REG_SQ_LENGTH_SHIFT                15
+#define UTMI_REG_SQ_LENGTH_MASK                 (0x3<<15)
+
+#define REG_RCAL_START                          0x00001000
+#define VCOCAL_START                            0x00200000
+#define KVCO_EXT                                0x00400000
+#define PLL_READY                               0x00800000
+#define CLK_BLK_EN                              0x01000000
+
+void pxa168_usb_sph_init(void);
+
+#endif /* PXA168_USB_PHY */
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index 51b2494..b399ba6 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -46,6 +46,7 @@  COBJS-$(CONFIG_USB_EHCI_IXP4XX) += ehci-ixp.o
 COBJS-$(CONFIG_USB_EHCI_KIRKWOOD) += ehci-kirkwood.o
 COBJS-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
 COBJS-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
+COBJS-$(CONFIG_USB_EHCI_PXA168) += ehci-pxa168.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/usb/host/ehci-pxa168.c b/drivers/usb/host/ehci-pxa168.c
new file mode 100644
index 0000000..1194f03
--- /dev/null
+++ b/drivers/usb/host/ehci-pxa168.c
@@ -0,0 +1,58 @@ 
+/**************************************************************************
+ *
+ * Copyright (c) 2009, 2010 Marvell International Ltd.
+ *
+ * This file is part of GNU program.
+ *
+ * GNU 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.
+ *
+ * GNU 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, see http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
+ *
+ *************************************************************************/
+
+#include <common.h>
+#include <asm/io.h>
+#include <usb.h>
+#include "ehci.h"
+#include "ehci-core.h"
+
+#include <asm/arch/pxa168_usb_phy.h>
+#define PXA168_USB_SPH_BASE	CONFIG_USB_SPH_REG_BASE
+
+/*
+ * Create the appropriate control structures to manage
+ * a new EHCI host controller.
+ */
+int ehci_hcd_init(void)
+{
+	pxa168_usb_sph_init();
+
+	hccr = (struct ehci_hccr *)(PXA168_USB_SPH_BASE + 0x100);
+	hcor = (struct ehci_hcor *)(PXA168_USB_SPH_BASE + 0x140);
+
+	debug("Pxa168-ehci: init hccr %x and hcor %x hc_length %d\n",
+		(uint32_t)hccr, (uint32_t)hcor,
+		(uint32_t)HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+
+	return 0;
+}
+
+/*
+ * Destroy the appropriate control structures corresponding
+ * the the EHCI host controller.
+ */
+int ehci_hcd_stop(void)
+{
+	return 0;
+}
diff --git a/include/configs/gplugd.h b/include/configs/gplugd.h
index 16fd03e..12421ee 100644
--- a/include/configs/gplugd.h
+++ b/include/configs/gplugd.h
@@ -124,6 +124,26 @@ 
 #endif /* CONFIG_PXASDH */
 
 /*
+ *  * USB/EHCI
+ *   */
+#define CONFIG_CMD_USB
+#define CONFIG_USB_SPH_REG_BASE         0xd4209000
+#define CONFIG_USB_SPH_PHY_BASE         0xd4206000
+
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI                 /* Enable EHCI USB support */
+#define CONFIG_USB_EHCI_PXA168
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#ifndef CONFIG_DOS_PARTITION
+#define CONFIG_DOS_PARTITION
+#endif /* CONFIG_DOS_PARTITION */
+#define CONFIG_ISO_PARTITION
+#define CONFIG_SUPPORT_VFAT
+#define CONFIG_CMD_EXT2
+#endif /* CONFIG_CMD_USB */
+
+/*
  * mv-common.h should be defined after CMD configs since it used them
  * to enable certain macros
  */