[U-Boot] [PATCH v8 4/4] Add USB support for Efika

Jana Rapava
2011-09-28T15:07:37Z

This commit adds USB support for EfikaMX and EfikaSB.

Signed-off-by: Jana Rapava <fermata7@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
Cc: Remy Bohmer <linux@bohmer.net>
Cc: Stefano Babic <sbabic@denx.de>
---
Changes for v2:
- changed to proper patch
Changes for v3:
- merged other USB patches from u-boot-pxa/efikasb
- offset-based access changed to struct-based access
- use {clrset,clr,set}bits_le32() calls
- CodingStyle and naming cleanup
Changes for v4:
- split into patchset
- CodingStyle and naming cleanup
- remove endless loops
- silence compiler warnings
Changes for v5:
- change order of arguments in ulpi* functions
- change type of reg argument
- rename offset macro
Changes for v6:
- rebase on top of u-boot-imx/next
- cleanup of CodingStyle and comments
- use macro machine_is_efikasb()
- introduce header file efika.h
Changes for v7:
- add proper header to efika.h
- include efika.h into efikamx.c
- check return values from ulpi_wait()
Changes for v8:
- change the return value of ulpi_wait()
- CodingStyle cleanup
- add proper header to efikamx-usb.c

board/efikamx/Makefile | 3 +
board/efikamx/efika.h | 30 +++
board/efikamx/efikamx-usb.c | 420 +++++++++++++++++++++++++++++++++++++++++++
board/efikamx/efikamx.c | 3 +
include/configs/efikamx.h | 16 ++
5 files changed, 472 insertions(+), 0 deletions(-)
create mode 100644 board/efikamx/efika.h
create mode 100644 board/efikamx/efikamx-usb.c

diff --git a/board/efikamx/Makefile b/board/efikamx/Makefile
index ee4a16e..860e4d2 100644
--- a/board/efikamx/Makefile
+++ b/board/efikamx/Makefile
@@ -28,6 +28,9 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).o

COBJS := efikamx.o
+ifdef CONFIG_CMD_USB
+COBJS += efikamx-usb.o
+endif

SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
OBJS := $(addprefix $(obj),$(COBJS))
diff --git a/board/efikamx/efika.h b/board/efikamx/efika.h
new file mode 100644
index 0000000..b3532e2
--- /dev/null
+++ b/board/efikamx/efika.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+/*
+ * EHCI USB
+ */
+#ifdef CONFIG_CMD_USB
+void setup_iomux_usb(void);
+#else
+static inline void setup_iomux_usb(void) { }
+#endif
diff --git a/board/efikamx/efikamx-usb.c b/board/efikamx/efikamx-usb.c
new file mode 100644
index 0000000..fc4ebfa
--- /dev/null
+++ b/board/efikamx/efikamx-usb.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#include <common.h>
+#include <usb.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/mx5x_pins.h>
+#include <asm/arch/iomux.h>
+#include <asm/gpio.h>
+#include <usb/ehci-fsl.h>
+#include <errno.h>
+#include <watchdog.h>
+
+#include <usb/ehci.h>
+#include <usb/ehci-core.h>
+
+/*
+ * Configure the USB H1 and USB H2 IOMUX.
+ */
+#define USB_PAD_CONFIG (PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST | \
+ PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU | \
+ PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_PULL)
+void setup_iomux_usb(void)
+{
+ /*
+ * Configure USBH1 pads
+ */
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_CLK, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DIR, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_NXT, USB_PAD_CONFIG);
+
+ mxc_request_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA0, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA1, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA2, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA3, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA4, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA5, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA6, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA7, USB_PAD_CONFIG);
+
+ /*
+ * Configure USBH1 control pads
+ */
+
+ /* USB PHY reset */
+ mxc_request_iomux(MX51_PIN_EIM_D27, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D27, PAD_CTL_PKE_ENABLE |
+ PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH);
+
+ /* USB HUB reset */
+ mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_5, PAD_CTL_PKE_ENABLE |
+ PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH);
+
+
+ if (machine_is_efikasb()) {
+ /*
+ * Configure USBH2 pads (used on EfikaSB)
+ */
+ /* USBH2_DATA */
+ mxc_request_iomux(MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D16, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D17, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D18, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D18, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D19, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D20, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D20, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D21, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D21, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D22, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D22, USB_PAD_CONFIG);
+ mxc_request_iomux(MX51_PIN_EIM_D23, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D23, USB_PAD_CONFIG);
+
+ /* USBH2_CLK */
+ mxc_request_iomux(MX51_PIN_EIM_A24, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A24, USB_PAD_CONFIG);
+ /* USBH2_DIR */
+ mxc_request_iomux(MX51_PIN_EIM_A25, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A25, USB_PAD_CONFIG);
+ /* USBH2_STP */
+ mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A26, USB_PAD_CONFIG);
+ /* USBH2_NXT */
+ mxc_request_iomux(MX51_PIN_EIM_A27, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A27, USB_PAD_CONFIG);
+ }
+
+ /* WIFI EN (act low) */
+ mxc_request_iomux(MX51_PIN_EIM_A22, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A22, 0);
+ /* WIFI RESET */
+ mxc_request_iomux(MX51_PIN_EIM_A16, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A16, 0);
+ /* BT EN (act low) */
+ mxc_request_iomux(MX51_PIN_EIM_A17, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A17, 0);
+}
+
+/*
+ * Enable devices connected to USB BUSes.
+ */
+void efika_usb_enable_devices(void)
+{
+ /* Enable Bluetooth */
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A17), 0);
+ udelay(10000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A17), 1);
+
+ /* Enable WiFi */
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A22), 1);
+ udelay(10000);
+
+ /* Reset the WiFi chip */
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A16), 0);
+ udelay(10000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A16), 1);
+}
+
+/*
+ * Reset USB HUB (or HUBs on EfikaSB).
+ */
+void efika_usb_hub_reset(void)
+{
+ /* HUB reset */
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 1);
+ udelay(1000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 0);
+ udelay(1000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_5), 1);
+}
+
+/*
+ * Reset USB PHY (or PHYs on EfikaSB).
+ */
+void efika_usb_phy_reset(void)
+{
+ /* SMSC 3317 PHY reset */
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_D27), 0);
+ udelay(1000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_D27), 1);
+}
+
+/*
+ * Configure control registers of the USB controller.
+ */
+void control_regs_setup(struct mx5_usb_control_regs *control)
+{
+ clrsetbits_le32(&control->usbctrl,
+ (MXC_OTG_WUE | MXC_OTG_PM | MX51_H1_ULPI_IE | MX51_H1_WUE),
+ MX51_H1_PM);
+
+ clrsetbits_le32(&control->phyctrl0,
+ MX51_OTG_OVERCURD,
+ MX51_EHCI_POWERPINSE);
+
+ clrsetbits_le32(&control->phyctrl1,
+ MX51_SYSCLOCK_MASK,
+ MX51_SYSCLOCK_24_MHZ);
+
+ setbits_le32(&control->usbctrl1, MX51_H1_EXTCLKE);
+
+ clrsetbits_le32(&control->uh2ctrl,
+ (MX51_H2_ULPI_IE | MX51_H2_WUE),
+ MX51_H2_PM);
+
+ udelay(10000);
+}
+
+#define ULPI_ADDR_SHIFT 16
+#define ulpi_write_mask(value) ((value) & 0xff)
+#define ulpi_read_mask(value) (((value) >> 8) & 0xff)
+
+int ulpi_wait(struct usb_ehci *ehci, u32 ulpi_bit)
+{
+ int timeout = ULPI_TIMEOUT;
+ u32 tmp;
+
+ /* Wait for the ulpi_bit to become zero. */
+ while (--timeout) {
+ tmp = readl(&ehci->ulpi_viewpoint);
+ if (!(tmp & ulpi_bit))
+ break;
+ WATCHDOG_RESET();
+ }
+
+ if (!timeout)
+ return -1;
+ else
+ return tmp;
+}
+
+void ulpi_write(struct usb_ehci *ehci, u32 reg, u32 value)
+{
+ if (!(readl(&ehci->ulpi_viewpoint) & ULPI_SS)) {
+ writel(ULPI_WU, &ehci->ulpi_viewpoint);
+ if (ulpi_wait(ehci, ULPI_WU) == -1)
+ printf("ULPI wakeup timed out\n");
+ }
+
+ writel(ULPI_RWRUN | ULPI_RWCTRL |
+ reg << ULPI_ADDR_SHIFT | ulpi_write_mask(value),
+ &ehci->ulpi_viewpoint);
+ if (ulpi_wait(ehci, ULPI_RWRUN) == -1)
+ printf("ULPI write timed out\n");
+}
+
+u32 ulpi_read(struct usb_ehci *ehci, u32 reg)
+{
+ u32 tmp;
+ if (!(readl(&ehci->ulpi_viewpoint) & ULPI_SS)) {
+ writel(ULPI_WU, &ehci->ulpi_viewpoint);
+ if (ulpi_wait(ehci, ULPI_WU) == -1)
+ printf("ULPI wakeup timed out\n");
+ }
+
+ writel(ULPI_RWRUN | reg << ULPI_ADDR_SHIFT, &ehci->ulpi_viewpoint);
+ tmp = ulpi_wait(ehci, ULPI_RWRUN);
+ if (tmp == -1) {
+ printf("ULPI read timed out\n");
+ return 0;
+ }
+ return ulpi_read_mask(tmp);
+}
+
+void ulpi_init(struct usb_ehci *ehci, struct mxc_ulpi_regs *ulpi)
+{
+ u32 tmp = 0;
+ int reg, i;
+
+ /* get ID from ULPI immediate registers */
+ for (reg = ULPI_ID_REGS_COUNT - 1; reg >= 0; reg--)
+ tmp |= ulpi_read(ehci, reg) << (reg * 8);
+ /* split into vendor and product ID */
+ debug("Found ULPI TX, ID %04x:%04x\n", tmp >> 16, tmp & 0xffff);
+
+ /* ULPI check integrity */
+ for (i = 0; i < 2; i++) {
+ ulpi_write(ehci, (u32)&ulpi->scratch_write,
+ ULPI_TEST_VALUE << i);
+ tmp = ulpi_read(ehci, (u32)&ulpi->scratch_write);
+
+ if (tmp != (ULPI_TEST_VALUE << i)) {
+ printf("ULPI integrity check failed\n");
+ return;
+ }
+ }
+
+ /* ULPI set flags */
+ ulpi_write(ehci, (u32)&ulpi->otg_ctrl_write,
+ ULPI_OTG_EXT_VBUS_IND |
+ ULPI_OTG_DM_PULLDOWN | ULPI_OTG_DP_PULLDOWN);
+ ulpi_write(ehci, (u32)&ulpi->function_ctrl_write,
+ ULPI_FC_XCVR_SELECT | ULPI_FC_OPMODE_NORMAL |
+ ULPI_FC_SUSPENDM_PWRED);
+ ulpi_write(ehci, (u32)&ulpi->iface_ctrl_write, 0);
+ ulpi_write(ehci, (u32)&ulpi->otg_ctrl_set,
+ ULPI_OTG_DRV_VBUS | ULPI_OTG_DRV_VBUS_EXT);
+
+ /*
+ * NOTE: This violates USB specification, but otherwise, USB on Efika
+ * doesn't charge VBUS and as a result, USB doesn't work.
+ */
+ ulpi_write(ehci, (u32)&ulpi->otg_ctrl_set, ULPI_OTG_CHRG_VBUS);
+}
+
+/*
+ * Solve the VBUS reset problem on Efika
+ * by setting the CHRG_VBUS bit in the reset.
+ */
+void ehci_fixup(uint32_t *status_reg, uint32_t *reg_ref)
+{
+ struct usb_ehci *ehci = (struct usb_ehci *)(OTG_BASE_ADDR +
+ MX51_REGISTER_LAYOUT_LENGTH);
+ struct mxc_ulpi_regs *ulpi = (struct mxc_ulpi_regs *)0;
+
+ u32 tmp = ulpi_read(ehci, (u32)&ulpi->otg_ctrl_write);
+ tmp |= ULPI_OTG_CHRG_VBUS;
+ ulpi_write(ehci, (u32)&ulpi->otg_ctrl_write, tmp);
+
+ /* USB 2.0 specification say 50 ms resets on root. */
+ wait_ms(50);
+
+ /* Now terminate the reset. */
+ *reg_ref = ehci_readl(status_reg);
+ *reg_ref |= EHCI_PS_PE;
+}
+
+void ehci0_init(struct usb_ehci *ehci)
+{
+ writel(MX51_16BIT_UTMI, &ehci->portsc);
+}
+
+void ehci1_init(struct usb_ehci *ehci, struct mxc_ulpi_regs *ulpi)
+{
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_DRV_HIGH |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP), 0);
+ udelay(1000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_USBH1_STP), 1);
+ udelay(1000);
+
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, USB_PAD_CONFIG);
+ udelay(10000);
+
+ clrbits_le32(&ehci->usbcmd, MX51_ITC_IMMEDIATE_MASK);
+ udelay(10000);
+
+ writel(MX51_ULPI_MODE_MASK, &ehci->portsc);
+ udelay(10000);
+
+ ulpi_init(ehci, ulpi);
+}
+
+void ehci2_init(struct usb_ehci *ehci, struct mxc_ulpi_regs *ulpi)
+{
+ mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A26, PAD_CTL_DRV_HIGH |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_A26), 0);
+ udelay(1000);
+ gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_A26), 1);
+ udelay(1000);
+
+ mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A26, USB_PAD_CONFIG);
+
+ writel(MX51_ULPI_MODE_MASK, &ehci->portsc);
+ udelay(10000);
+
+ ulpi_init(ehci, ulpi);
+}
+
+int ehci_hcd_init(void)
+{
+ struct usb_ehci *ehci;
+ struct mx5_usb_control_regs *mx5_usb_control_regs;
+ struct mxc_ulpi_regs *ulpi;
+
+ mx5_usb_control_regs = (struct mx5_usb_control_regs *)(OTG_BASE_ADDR +
+ MX5_CTRL_REGS_OFFSET);
+ control_regs_setup(mx5_usb_control_regs);
+ ulpi = (struct mxc_ulpi_regs *)0;
+
+ /* Init EHCI core */
+ ehci = (struct usb_ehci *)(OTG_BASE_ADDR +
+ (MX51_REGISTER_LAYOUT_LENGTH * CONFIG_MXC_USB_PORT));
+ hccr = (struct ehci_hccr *)((uint32_t)&ehci->caplength);
+ hcor = (struct ehci_hcor *)((uint32_t) hccr +
+ HC_LENGTH(ehci_readl(&hccr->cr_capbase)));
+ setbits_le32(&ehci->usbmode, CM_HOST);
+ setbits_le32(&ehci->control, USB_EN);
+
+ /* Init iMX51 EHCI */
+ efika_usb_phy_reset();
+ efika_usb_hub_reset();
+ efika_usb_enable_devices();
+
+ switch (CONFIG_MXC_USB_PORT) {
+ case 0:
+ ehci0_init(ehci);
+ break;
+ case 1:
+ ehci1_init(ehci, ulpi);
+ break;
+ case 2:
+ if (machine_is_efikasb())
+ ehci2_init(ehci, ulpi);
+ break;
+ };
+
+ /* EfikaMX USB has issues ... */
+ udelay(10000);
+
+ return 0;
+}
+
+int ehci_hcd_stop(void)
+{
+ return 0;
+}
diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c
index 0c4e24b..8e9b42b 100644
--- a/board/efikamx/efikamx.c
+++ b/board/efikamx/efikamx.c
@@ -37,6 +37,8 @@
#include <fsl_pmic.h>
#include <mc13892.h>

+#include "efika.h"
+
DECLARE_GLOBAL_DATA_PTR;

/*
@@ -678,6 +680,7 @@ int board_late_init(void)

setup_iomux_led();
setup_iomux_ata();
+ setup_iomux_usb();

efikamx_toggle_led(EFIKAMX_LED_BLUE);

diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h
index 54f48e4..010a16a 100644
--- a/include/configs/efikamx.h
+++ b/include/configs/efikamx.h
@@ -44,6 +44,10 @@

#define CONFIG_SYS_TEXT_BASE 0x97800000

+#define CONFIG_L2_OFF
+#define CONFIG_SYS_ICACHE_OFF
+#define CONFIG_SYS_DCACHE_OFF
+
/*
* Bootloader Components Configuration
*/
@@ -172,6 +176,18 @@
#endif

/*
+ * USB
+ */
+#define CONFIG_CMD_USB
+#ifdef CONFIG_CMD_USB
+#define CONFIG_USB_EHCI /* Enable EHCI USB support */
+#define CONFIG_MXC_USB_PORT 1
+#define CONFIG_EHCI_IS_TDI
+#define CONFIG_USB_STORAGE
+#define CONFIG_USB_KEYBOARD
+#endif /* CONFIG_CMD_USB */
+
+/*
* Filesystems
*/
#ifdef CONFIG_CMD_FAT
--
1.7.6.3