Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel-stable
authorRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 20 May 2010 22:43:18 +0000 (23:43 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 20 May 2010 22:43:18 +0000 (23:43 +0100)
35 files changed:
arch/arm/configs/mx51_defconfig
arch/arm/mach-mx2/devices.c
arch/arm/mach-mx2/mach-pca100.c
arch/arm/mach-mx2/mach-pcm038.c
arch/arm/mach-mx25/devices.c
arch/arm/mach-mx25/devices.h
arch/arm/mach-mx3/Kconfig
arch/arm/mach-mx3/devices.c
arch/arm/mach-mx3/devices.h
arch/arm/mach-mx3/mach-mx31_3ds.c
arch/arm/mach-mx3/mach-mx31lilly.c
arch/arm/mach-mx3/mach-mx31moboard.c
arch/arm/mach-mx3/mach-pcm037.c
arch/arm/mach-mx3/mach-pcm043.c
arch/arm/mach-mx3/mx31lite-db.c
arch/arm/mach-mx3/mx31moboard-devboard.c
arch/arm/mach-mx3/mx31moboard-marxbot.c
arch/arm/mach-mx3/mx31moboard-smartbot.c
arch/arm/mach-mx5/board-mx51_babbage.c
arch/arm/mach-mx5/clock-mx51.c
arch/arm/mach-mx5/devices.c
arch/arm/mach-mx5/devices.h
arch/arm/plat-mxc/ehci.c
arch/arm/plat-mxc/gpio.c
arch/arm/plat-mxc/include/mach/board-mx31moboard.h
arch/arm/plat-mxc/include/mach/iomux-mx3.h
arch/arm/plat-mxc/include/mach/iomux-mx51.h
arch/arm/plat-mxc/include/mach/mxc_ehci.h
arch/arm/plat-mxc/time.c
arch/arm/plat-mxc/tzic.c
drivers/mmc/core/sdio.c
drivers/mmc/host/mxcmmc.c
drivers/mtd/nand/mxc_nand.c
drivers/usb/host/ehci-mxc.c
include/linux/mmc/host.h

index c88e952..a708fd6 100644 (file)
@@ -809,7 +809,22 @@ CONFIG_SSB_POSSIBLE=y
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_SOUND is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_MXC=y
+
+
 CONFIG_MMC=y
 # CONFIG_MMC_DEBUG is not set
 # CONFIG_MMC_UNSAFE_RESUME is not set
index b91e412..a9377ce 100644 (file)
@@ -109,12 +109,7 @@ DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5);
 DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
 #endif
 
-/*
- * Watchdog:
- * - i.MX1
- * - i.MX21
- * - i.MX27
- */
+/* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */
 static struct resource mxc_wdt_resources[] = {
        {
                .start = MX2x_WDOG_BASE_ADDR,
@@ -124,7 +119,7 @@ static struct resource mxc_wdt_resources[] = {
 };
 
 struct platform_device mxc_wdt = {
-       .name = "mxc_wdt",
+       .name = "imx2-wdt",
        .id = 0,
        .num_resources = ARRAY_SIZE(mxc_wdt_resources),
        .resource = mxc_wdt_resources,
index 778fff2..a87422e 100644 (file)
@@ -145,6 +145,7 @@ static struct mxc_nand_platform_data pca100_nand_board_info = {
 static struct platform_device *platform_devices[] __initdata = {
        &mxc_w1_master_device,
        &mxc_fec_device,
+       &mxc_wdt,
 };
 
 static struct imxi2c_platform_data pca100_i2c_1_data = {
index 035fbe0..36c8943 100644 (file)
@@ -182,6 +182,7 @@ static struct platform_device *platform_devices[] __initdata = {
        &mxc_w1_master_device,
        &mxc_fec_device,
        &pcm038_sram_mtd_device,
+       &mxc_wdt,
 };
 
 /* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
index 3f4b8a0..3a405fa 100644 (file)
@@ -500,3 +500,18 @@ struct platform_device mx25_fb_device = {
                .coherent_dma_mask = 0xFFFFFFFF,
        },
 };
+
+static struct resource mxc_wdt_resources[] = {
+       {
+               .start = MX25_WDOG_BASE_ADDR,
+               .end = MX25_WDOG_BASE_ADDR + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device mxc_wdt = {
+       .name = "imx2-wdt",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(mxc_wdt_resources),
+       .resource = mxc_wdt_resources,
+};
index 39560e1..cee12c0 100644 (file)
@@ -21,3 +21,4 @@ extern struct platform_device mx25_fec_device;
 extern struct platform_device mxc_nand_device;
 extern struct platform_device mx25_rtc_device;
 extern struct platform_device mx25_fb_device;
+extern struct platform_device mxc_wdt;
index 170f68e..344753f 100644 (file)
@@ -82,6 +82,7 @@ config MACH_MX31MOBOARD
 config MACH_MX31LILLY
        bool "Support MX31 LILLY-1131 platforms (INCO startec)"
        select ARCH_MX31
+       select MXC_ULPI if USB_ULPI
        help
          Include support for mx31 based LILLY1131 modules. This includes
          specific configurations for the board and its peripherals.
index f891115..db7acd6 100644 (file)
@@ -582,12 +582,50 @@ static struct resource imx_wdt_resources[] = {
 };
 
 struct platform_device imx_wdt_device0 = {
-       .name           = "imx-wdt",
+       .name           = "imx2-wdt",
        .id             = 0,
        .num_resources  = ARRAY_SIZE(imx_wdt_resources),
        .resource       = imx_wdt_resources,
 };
 
+static struct resource imx_rtc_resources[] = {
+       {
+               .start  = MX31_RTC_BASE_ADDR,
+               .end    = MX31_RTC_BASE_ADDR + 0x3fff,
+               .flags  = IORESOURCE_MEM,
+       },
+       {
+               .start  = MX31_INT_RTC,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device imx_rtc_device0 = {
+       .name           = "mxc_rtc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(imx_rtc_resources),
+       .resource       = imx_rtc_resources,
+};
+
+static struct resource imx_kpp_resources[] = {
+       {
+               .start  = MX3x_KPP_BASE_ADDR,
+               .end    = MX3x_KPP_BASE_ADDR + 0xf,
+               .flags  = IORESOURCE_MEM
+       }, {
+               .start  = MX3x_INT_KPP,
+               .end    = MX3x_INT_KPP,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device imx_kpp_device = {
+       .name = "imx-keypad",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(imx_kpp_resources),
+       .resource = imx_kpp_resources,
+};
+
 static int __init mx3_devices_init(void)
 {
        if (cpu_is_mx31()) {
index 4f77eb5..2c3c864 100644 (file)
@@ -27,3 +27,5 @@ extern struct platform_device imx_ssi_device0;
 extern struct platform_device imx_ssi_device1;
 extern struct platform_device imx_ssi_device1;
 extern struct platform_device imx_wdt_device0;
+extern struct platform_device imx_rtc_device0;
+extern struct platform_device imx_kpp_device;
index f54af1e..58e5729 100644 (file)
@@ -16,6 +16,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <linux/delay.h>
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/clk.h>
@@ -26,6 +27,8 @@
 #include <linux/mfd/mc13783.h>
 #include <linux/spi/spi.h>
 #include <linux/regulator/machine.h>
+#include <linux/fsl_devices.h>
+#include <linux/input/matrix_keypad.h>
 
 #include <mach/hardware.h>
 #include <asm/mach-types.h>
@@ -65,6 +68,50 @@ static int mx31_3ds_pins[] = {
        MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
        /* MC13783 IRQ */
        IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO),
+       /* USB OTG reset */
+       IOMUX_MODE(MX31_PIN_USB_PWR, IOMUX_CONFIG_GPIO),
+       /* USB OTG */
+       MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+       MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+       MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+       MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+       MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+       MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+       MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+       MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+       MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+       MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+       MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+       MX31_PIN_USBOTG_STP__USBOTG_STP,
+       /*Keyboard*/
+       MX31_PIN_KEY_ROW0_KEY_ROW0,
+       MX31_PIN_KEY_ROW1_KEY_ROW1,
+       MX31_PIN_KEY_ROW2_KEY_ROW2,
+       MX31_PIN_KEY_COL0_KEY_COL0,
+       MX31_PIN_KEY_COL1_KEY_COL1,
+       MX31_PIN_KEY_COL2_KEY_COL2,
+       MX31_PIN_KEY_COL3_KEY_COL3,
+};
+
+/*
+ * Matrix keyboard
+ */
+
+static const uint32_t mx31_3ds_keymap[] = {
+       KEY(0, 0, KEY_UP),
+       KEY(0, 1, KEY_DOWN),
+       KEY(1, 0, KEY_RIGHT),
+       KEY(1, 1, KEY_LEFT),
+       KEY(1, 2, KEY_ENTER),
+       KEY(2, 0, KEY_F6),
+       KEY(2, 1, KEY_F8),
+       KEY(2, 2, KEY_F9),
+       KEY(2, 3, KEY_F10),
+};
+
+static struct matrix_keymap_data mx31_3ds_keymap_data = {
+       .keymap         = mx31_3ds_keymap,
+       .keymap_size    = ARRAY_SIZE(mx31_3ds_keymap),
 };
 
 /* Regulators */
@@ -126,6 +173,41 @@ static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
 #endif
 };
 
+/*
+ * USB OTG
+ */
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+                    PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+#define USBOTG_RST_B IOMUX_TO_GPIO(MX31_PIN_USB_PWR)
+
+static void mx31_3ds_usbotg_init(void)
+{
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+       gpio_request(USBOTG_RST_B, "otgusb-reset");
+       gpio_direction_output(USBOTG_RST_B, 0);
+       mdelay(1);
+       gpio_set_value(USBOTG_RST_B, 1);
+}
+
+static struct fsl_usb2_platform_data usbotg_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
 static struct imxuart_platform_data uart_pdata = {
        .flags = IMXUART_HAVE_RTSCTS,
 };
@@ -315,6 +397,11 @@ static void __init mxc_board_init(void)
        spi_register_board_info(mx31_3ds_spi_devs,
                                                ARRAY_SIZE(mx31_3ds_spi_devs));
 
+       mxc_register_device(&imx_kpp_device, &mx31_3ds_keymap_data);
+
+       mx31_3ds_usbotg_init();
+       mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata);
+
        if (!mx31_3ds_init_expio())
                platform_device_register(&smsc911x_device);
 }
index 80847b0..d3d5877 100644 (file)
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/clk.h>
+#include <linux/gpio.h>
 #include <linux/platform_device.h>
 #include <linux/interrupt.h>
 #include <linux/smsc911x.h>
 #include <linux/mtd/physmap.h>
 #include <linux/spi/spi.h>
 #include <linux/mfd/mc13783.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -44,6 +47,8 @@
 #include <mach/iomux-mx3.h>
 #include <mach/board-mx31lilly.h>
 #include <mach/spi.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include "devices.h"
 
@@ -108,6 +113,137 @@ static struct platform_device physmap_flash_device = {
        .num_resources = 1,
 };
 
+/* USB */
+
+#define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
+                       PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+
+static int usbotg_init(struct platform_device *pdev)
+{
+       unsigned int pins[] = {
+               MX31_PIN_USBOTG_DATA0__USBOTG_DATA0,
+               MX31_PIN_USBOTG_DATA1__USBOTG_DATA1,
+               MX31_PIN_USBOTG_DATA2__USBOTG_DATA2,
+               MX31_PIN_USBOTG_DATA3__USBOTG_DATA3,
+               MX31_PIN_USBOTG_DATA4__USBOTG_DATA4,
+               MX31_PIN_USBOTG_DATA5__USBOTG_DATA5,
+               MX31_PIN_USBOTG_DATA6__USBOTG_DATA6,
+               MX31_PIN_USBOTG_DATA7__USBOTG_DATA7,
+               MX31_PIN_USBOTG_CLK__USBOTG_CLK,
+               MX31_PIN_USBOTG_DIR__USBOTG_DIR,
+               MX31_PIN_USBOTG_NXT__USBOTG_NXT,
+               MX31_PIN_USBOTG_STP__USBOTG_STP,
+       };
+
+       mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB OTG");
+
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_USB_4WIRE, true);
+       mxc_iomux_set_gpr(MUX_PGP_USB_COMMON, true);
+
+       /* chip select */
+       mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE2, IOMUX_CONFIG_GPIO),
+                               "USBOTG_CS");
+       gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE2), "USBH1 CS");
+       gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE2), 0);
+
+       return 0;
+}
+
+static int usbh1_init(struct platform_device *pdev)
+{
+       int pins[] = {
+               MX31_PIN_CSPI1_MOSI__USBH1_RXDM,
+               MX31_PIN_CSPI1_MISO__USBH1_RXDP,
+               MX31_PIN_CSPI1_SS0__USBH1_TXDM,
+               MX31_PIN_CSPI1_SS1__USBH1_TXDP,
+               MX31_PIN_CSPI1_SS2__USBH1_RCV,
+               MX31_PIN_CSPI1_SCLK__USBH1_OEB,
+               MX31_PIN_CSPI1_SPI_RDY__USBH1_FS,
+       };
+
+       mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H1");
+
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+       return 0;
+}
+
+static int usbh2_init(struct platform_device *pdev)
+{
+       int pins[] = {
+               MX31_PIN_USBH2_DATA0__USBH2_DATA0,
+               MX31_PIN_USBH2_DATA1__USBH2_DATA1,
+               MX31_PIN_USBH2_CLK__USBH2_CLK,
+               MX31_PIN_USBH2_DIR__USBH2_DIR,
+               MX31_PIN_USBH2_NXT__USBH2_NXT,
+               MX31_PIN_USBH2_STP__USBH2_STP,
+       };
+
+       mxc_iomux_setup_multiple_pins(pins, ARRAY_SIZE(pins), "USB H2");
+
+       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
+       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
+
+       mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+       /* chip select */
+       mxc_iomux_alloc_pin(IOMUX_MODE(MX31_PIN_DTR_DCE1, IOMUX_CONFIG_GPIO),
+                               "USBH2_CS");
+       gpio_request(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), "USBH2 CS");
+       gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1), 0);
+
+       return 0;
+}
+
+static struct mxc_usbh_platform_data usbotg_pdata = {
+       .init   = usbotg_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static struct mxc_usbh_platform_data usbh1_pdata = {
+       .init   = usbh1_init,
+       .portsc = MXC_EHCI_MODE_UTMI | MXC_EHCI_SERIAL,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_INTERFACE_SINGLE_UNI,
+};
+
+static struct mxc_usbh_platform_data usbh2_pdata = {
+       .init   = usbh2_init,
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
 static struct platform_device *devices[] __initdata = {
        &smsc91x_device,
        &physmap_flash_device,
@@ -183,6 +319,15 @@ static void __init mx31lilly_board_init(void)
        spi_register_board_info(&mc13783_dev, 1);
 
        platform_add_devices(devices, ARRAY_SIZE(devices));
+
+       /* USB */
+       usbotg_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+       usbh2_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                               USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+       mxc_register_device(&mxc_usbh1, &usbh1_pdata);
+       mxc_register_device(&mxc_usbh2, &usbh2_pdata);
 }
 
 static void __init mx31lilly_timer_init(void)
index fccb920..33a8d35 100644 (file)
@@ -18,7 +18,6 @@
 
 #include <linux/delay.h>
 #include <linux/dma-mapping.h>
-#include <linux/fsl_devices.h>
 #include <linux/gfp.h>
 #include <linux/gpio.h>
 #include <linux/init.h>
@@ -306,84 +305,56 @@ static struct imxmmc_platform_data sdhc1_pdata = {
  * this pin is dedicated for all mx31moboard systems, so we do it here
  */
 #define USB_RESET_B    IOMUX_TO_GPIO(MX31_PIN_GPIO1_0)
-
-static void usb_xcvr_reset(void)
-{
-       gpio_request(USB_RESET_B, "usb-reset");
-       gpio_direction_output(USB_RESET_B, 0);
-       mdelay(1);
-       gpio_set_value(USB_RESET_B, 1);
-}
-
 #define USB_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | \
-                       PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+                     PAD_CTL_ODE_CMOS)
 
 #define OTG_EN_B IOMUX_TO_GPIO(MX31_PIN_USB_OC)
-
-static void moboard_usbotg_init(void)
-{
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG);
-
-       gpio_request(OTG_EN_B, "usb-udc-en");
-       gpio_direction_output(OTG_EN_B, 0);
-}
-
-static struct fsl_usb2_platform_data usb_pdata = {
-       .operating_mode = FSL_USB2_DR_DEVICE,
-       .phy_mode       = FSL_USB2_PHY_ULPI,
-};
-
-#if defined(CONFIG_USB_ULPI)
-
 #define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6)
 
-static int moboard_usbh2_hw_init(struct platform_device *pdev)
+static void usb_xcvr_reset(void)
 {
-       int ret;
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBOTG_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
 
        mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG | PAD_CTL_100K_PU);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
+       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG | PAD_CTL_100K_PD);
 
-       mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBH2_STP, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_SRXD6, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_STXD6, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_SFS3, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_SCK3, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_SRXD3, USB_PAD_CFG);
-       mxc_iomux_set_pad(MX31_PIN_STXD3, USB_PAD_CFG);
-
-       ret = gpio_request(USBH2_EN_B, "usbh2-en");
-       if (ret)
-               return ret;
+       gpio_request(OTG_EN_B, "usb-udc-en");
+       gpio_direction_output(OTG_EN_B, 0);
+       gpio_request(USBH2_EN_B, "usbh2-en");
        gpio_direction_output(USBH2_EN_B, 0);
 
-       return 0;
+       gpio_request(USB_RESET_B, "usb-reset");
+       gpio_direction_output(USB_RESET_B, 0);
+       mdelay(1);
+       gpio_set_value(USB_RESET_B, 1);
+       mdelay(1);
 }
 
-static int moboard_usbh2_hw_exit(struct platform_device *pdev)
-{
-       gpio_free(USBH2_EN_B);
-       return 0;
-}
+#if defined(CONFIG_USB_ULPI)
 
 static struct mxc_usbh_platform_data usbh2_pdata = {
-       .init   = moboard_usbh2_hw_init,
-       .exit   = moboard_usbh2_hw_exit,
        .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
        .flags  = MXC_EHCI_POWER_PINS_ENABLED,
 };
@@ -508,8 +479,6 @@ static void __init mxc_board_init(void)
 
        usb_xcvr_reset();
 
-       moboard_usbotg_init();
-       mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
        moboard_usbh2_init();
 
        switch (mx31moboard_baseboard) {
@@ -522,7 +491,8 @@ static void __init mxc_board_init(void)
                mx31moboard_marxbot_init();
                break;
        case MX31SMARTBOT:
-               mx31moboard_smartbot_init();
+       case MX31EYEBOT:
+               mx31moboard_smartbot_init(mx31moboard_baseboard);
                break;
        default:
                printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
index 2df1ec5..5024284 100644 (file)
@@ -449,6 +449,7 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size)
 static struct platform_device *devices[] __initdata = {
        &pcm037_flash,
        &pcm037_sram_device,
+       &imx_wdt_device0,
        &pcm037_mt9t031,
        &pcm037_mt9v022,
 };
index 1bf1ec2..78d9185 100644 (file)
@@ -150,6 +150,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
 static struct platform_device *devices[] __initdata = {
        &pcm043_flash,
        &mxc_fec_device,
+       &imx_wdt_device0,
 };
 
 static struct pad_desc pcm043_pads[] = {
index 093c595..5f05bfb 100644 (file)
@@ -206,5 +206,6 @@ void __init mx31lite_db_init(void)
        mxc_register_device(&mxc_spi_device0, &spi0_pdata);
        platform_device_register(&litekit_led_device);
        mxc_register_device(&imx_wdt_device0, NULL);
+       mxc_register_device(&imx_rtc_device0, NULL);
 }
 
index 11b906c..582299c 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/types.h>
+#include <linux/fsl_devices.h>
 
 #include <linux/usb/otg.h>
 
@@ -213,6 +214,12 @@ static int __init devboard_usbh1_init(void)
        return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
 }
 
+
+static struct fsl_usb2_platform_data usb_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
@@ -229,5 +236,7 @@ void __init mx31moboard_devboard_init(void)
 
        devboard_init_sel_gpios();
 
+       mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+
        devboard_usbh1_init();
 }
index ffb105e..4930f8c 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/slab.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
+#include <linux/fsl_devices.h>
 
 #include <linux/usb/otg.h>
 
@@ -329,6 +330,11 @@ static int __init marxbot_usbh1_init(void)
        return mxc_register_device(&mxc_usbh1, &usbh1_pdata);
 }
 
+static struct fsl_usb2_platform_data usb_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
@@ -356,5 +362,7 @@ void __init mx31moboard_marxbot_init(void)
        gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
        gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
 
+       mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+
        marxbot_usbh1_init();
 }
index 52a69fc..293eea6 100644 (file)
 #include <linux/i2c.h>
 #include <linux/platform_device.h>
 #include <linux/types.h>
+#include <linux/fsl_devices.h>
+
+#include <linux/usb/otg.h>
+#include <linux/usb/ulpi.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx3.h>
+#include <mach/board-mx31moboard.h>
+#include <mach/mxc_ehci.h>
+#include <mach/ulpi.h>
 
 #include <media/soc_camera.h>
 
@@ -116,10 +123,33 @@ static int __init smartbot_cam_init(void)
        return 0;
 }
 
+static struct fsl_usb2_platform_data usb_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_ULPI,
+};
+
+#if defined(CONFIG_USB_ULPI)
+
+static struct mxc_usbh_platform_data otg_host_pdata = {
+       .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
+       .flags  = MXC_EHCI_POWER_PINS_ENABLED,
+};
+
+static int __init smartbot_otg_host_init(void)
+{
+       otg_host_pdata.otg = otg_ulpi_create(&mxc_ulpi_access_ops,
+                       USB_OTG_DRV_VBUS | USB_OTG_DRV_VBUS_EXT);
+
+       return mxc_register_device(&mxc_otg_host, &otg_host_pdata);
+}
+#else
+static inline int smartbot_otg_host_init(void) { return 0; }
+#endif
+
 #define POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
 #define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
 #define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_DCE1)
-#define SEL3 IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
+#define TRSLAT_SRC_CHOICE IOMUX_TO_GPIO(MX31_PIN_DCD_DCE1)
 
 static void smartbot_resets_init(void)
 {
@@ -138,15 +168,15 @@ static void smartbot_resets_init(void)
                gpio_export(TRSLAT_RST_B, false);
        }
 
-       if (!gpio_request(SEL3, "sel3")) {
-               gpio_direction_input(SEL3);
-               gpio_export(SEL3, true);
+       if (!gpio_request(TRSLAT_SRC_CHOICE, "translator-src-choice")) {
+               gpio_direction_output(TRSLAT_SRC_CHOICE, 0);
+               gpio_export(TRSLAT_SRC_CHOICE, false);
        }
 }
 /*
  * system init for baseboard usage. Will be called by mx31moboard init.
  */
-void __init mx31moboard_smartbot_init(void)
+void __init mx31moboard_smartbot_init(int board)
 {
        printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
 
@@ -155,6 +185,19 @@ void __init mx31moboard_smartbot_init(void)
 
        mxc_register_device(&mxc_uart_device1, &uart_pdata);
 
+
+       switch (board) {
+       case MX31SMARTBOT:
+               mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
+               break;
+       case MX31EYEBOT:
+               smartbot_otg_host_init();
+               break;
+       default:
+               printk(KERN_WARNING "Unknown board %d, USB OTG not initialized",
+                       board);
+       }
+
        smartbot_resets_init();
 
        smartbot_cam_init();
index ee67a71..ed885f9 100644 (file)
 
 #include <linux/init.h>
 #include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <linux/fsl_devices.h>
 
 #include <mach/common.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
 #include <mach/iomux-mx51.h>
+#include <mach/mxc_ehci.h>
 
 #include <asm/irq.h>
 #include <asm/setup.h>
 
 #include "devices.h"
 
+#define BABBAGE_USB_HUB_RESET  (0*32 + 7)      /* GPIO_1_7 */
+#define BABBAGE_USBH1_STP      (0*32 + 27)     /* GPIO_1_27 */
+#define BABBAGE_PHY_RESET (1*32 +5)    /* GPIO_2_5 */
+
+/* USB_CTRL_1 */
+#define MX51_USB_CTRL_1_OFFSET                 0x10
+#define MX51_USB_CTRL_UH1_EXT_CLK_EN           (1 << 25)
+
+#define        MX51_USB_PLLDIV_12_MHZ          0x00
+#define        MX51_USB_PLL_DIV_19_2_MHZ       0x01
+#define        MX51_USB_PLL_DIV_24_MHZ 0x02
+
 static struct platform_device *devices[] __initdata = {
        &mxc_fec_device,
 };
@@ -46,6 +63,22 @@ static struct pad_desc mx51babbage_pads[] = {
        MX51_PAD_EIM_D26__UART3_TXD,
        MX51_PAD_EIM_D27__UART3_RTS,
        MX51_PAD_EIM_D24__UART3_CTS,
+
+       /* USB HOST1 */
+       MX51_PAD_USBH1_CLK__USBH1_CLK,
+       MX51_PAD_USBH1_DIR__USBH1_DIR,
+       MX51_PAD_USBH1_NXT__USBH1_NXT,
+       MX51_PAD_USBH1_DATA0__USBH1_DATA0,
+       MX51_PAD_USBH1_DATA1__USBH1_DATA1,
+       MX51_PAD_USBH1_DATA2__USBH1_DATA2,
+       MX51_PAD_USBH1_DATA3__USBH1_DATA3,
+       MX51_PAD_USBH1_DATA4__USBH1_DATA4,
+       MX51_PAD_USBH1_DATA5__USBH1_DATA5,
+       MX51_PAD_USBH1_DATA6__USBH1_DATA6,
+       MX51_PAD_USBH1_DATA7__USBH1_DATA7,
+
+       /* USB HUB reset line*/
+       MX51_PAD_GPIO_1_7__GPIO1_7,
 };
 
 /* Serial ports */
@@ -66,15 +99,149 @@ static inline void mxc_init_imx_uart(void)
 }
 #endif /* SERIAL_IMX */
 
+static int gpio_usbh1_active(void)
+{
+       struct pad_desc usbh1stp_gpio = MX51_PAD_USBH1_STP__GPIO_1_27;
+       struct pad_desc phyreset_gpio = MX51_PAD_EIM_D21__GPIO_2_5;
+       int ret;
+
+       /* Set USBH1_STP to GPIO and toggle it */
+       mxc_iomux_v3_setup_pad(&usbh1stp_gpio);
+       ret = gpio_request(BABBAGE_USBH1_STP, "usbh1_stp");
+
+       if (ret) {
+               pr_debug("failed to get MX51_PAD_USBH1_STP__GPIO_1_27: %d\n", ret);
+               return ret;
+       }
+       gpio_direction_output(BABBAGE_USBH1_STP, 0);
+       gpio_set_value(BABBAGE_USBH1_STP, 1);
+       msleep(100);
+       gpio_free(BABBAGE_USBH1_STP);
+
+       /* De-assert USB PHY RESETB */
+       mxc_iomux_v3_setup_pad(&phyreset_gpio);
+       ret = gpio_request(BABBAGE_PHY_RESET, "phy_reset");
+
+       if (ret) {
+               pr_debug("failed to get MX51_PAD_EIM_D21__GPIO_2_5: %d\n", ret);
+               return ret;
+       }
+       gpio_direction_output(BABBAGE_PHY_RESET, 1);
+       return 0;
+}
+
+static inline void babbage_usbhub_reset(void)
+{
+       int ret;
+
+       /* Bring USB hub out of reset */
+       ret = gpio_request(BABBAGE_USB_HUB_RESET, "GPIO1_7");
+       if (ret) {
+               printk(KERN_ERR"failed to get GPIO_USB_HUB_RESET: %d\n", ret);
+               return;
+       }
+       gpio_direction_output(BABBAGE_USB_HUB_RESET, 0);
+
+       /* USB HUB RESET - De-assert USB HUB RESET_N */
+       msleep(1);
+       gpio_set_value(BABBAGE_USB_HUB_RESET, 0);
+       msleep(1);
+       gpio_set_value(BABBAGE_USB_HUB_RESET, 1);
+}
+
+/* This function is board specific as the bit mask for the plldiv will also
+be different for other Freescale SoCs, thus a common bitmask is not
+possible and cannot get place in /plat-mxc/ehci.c.*/
+static int initialize_otg_port(struct platform_device *pdev)
+{
+       u32 v;
+       void __iomem *usb_base;
+       u32 usbother_base;
+
+       usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+       usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+       /* Set the PHY clock to 19.2MHz */
+       v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+       v &= ~MX5_USB_UTMI_PHYCTRL1_PLLDIV_MASK;
+       v |= MX51_USB_PLL_DIV_19_2_MHZ;
+       __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC2_OFFSET);
+       iounmap(usb_base);
+       return 0;
+}
+
+static int initialize_usbh1_port(struct platform_device *pdev)
+{
+       u32 v;
+       void __iomem *usb_base;
+       u32 usbother_base;
+
+       usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+       usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+       /* The clock for the USBH1 ULPI port will come externally from the PHY. */
+       v = __raw_readl(usbother_base + MX51_USB_CTRL_1_OFFSET);
+       __raw_writel(v | MX51_USB_CTRL_UH1_EXT_CLK_EN, usbother_base + MX51_USB_CTRL_1_OFFSET);
+       iounmap(usb_base);
+       return 0;
+}
+
+static struct mxc_usbh_platform_data dr_utmi_config = {
+       .init           = initialize_otg_port,
+       .portsc = MXC_EHCI_UTMI_16BIT,
+       .flags  = MXC_EHCI_INTERNAL_PHY,
+};
+
+static struct fsl_usb2_platform_data usb_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_UTMI_WIDE,
+};
+
+static struct mxc_usbh_platform_data usbh1_config = {
+       .init           = initialize_usbh1_port,
+       .portsc = MXC_EHCI_MODE_ULPI,
+       .flags  = (MXC_EHCI_POWER_PINS_ENABLED | MXC_EHCI_ITC_NO_THRESHOLD),
+};
+
+static int otg_mode_host;
+
+static int __init babbage_otg_mode(char *options)
+{
+       if (!strcmp(options, "host"))
+               otg_mode_host = 1;
+       else if (!strcmp(options, "device"))
+               otg_mode_host = 0;
+       else
+               pr_info("otg_mode neither \"host\" nor \"device\". "
+                       "Defaulting to device\n");
+       return 0;
+}
+__setup("otg_mode=", babbage_otg_mode);
+
 /*
  * Board specific initialization.
  */
 static void __init mxc_board_init(void)
 {
+       struct pad_desc usbh1stp = MX51_PAD_USBH1_STP__USBH1_STP;
+
        mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
                                        ARRAY_SIZE(mx51babbage_pads));
        mxc_init_imx_uart();
        platform_add_devices(devices, ARRAY_SIZE(devices));
+
+       if (otg_mode_host)
+               mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config);
+       else {
+               initialize_otg_port(NULL);
+               mxc_register_device(&mxc_usbdr_udc_device, &usb_pdata);
+       }
+
+       gpio_usbh1_active();
+       mxc_register_device(&mxc_usbh1_device, &usbh1_config);
+       /* setback USBH1_STP to be function */
+       mxc_iomux_v3_setup_pad(&usbh1stp);
+       babbage_usbhub_reset();
 }
 
 static void __init mx51_babbage_timer_init(void)
index 1ee6ce4..d9f612d 100644 (file)
@@ -37,6 +37,7 @@ static struct clk lp_apm_clk;
 static struct clk periph_apm_clk;
 static struct clk ahb_clk;
 static struct clk ipg_clk;
+static struct clk usboh3_clk;
 
 #define MAX_DPLL_WAIT_TRIES    1000 /* 1000 * udelay(1) = 1ms */
 
@@ -570,6 +571,35 @@ static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
        return 0;
 }
 
+static unsigned long clk_usboh3_get_rate(struct clk *clk)
+{
+       u32 reg, prediv, podf;
+       unsigned long parent_rate;
+
+       parent_rate = clk_get_rate(clk->parent);
+
+       reg = __raw_readl(MXC_CCM_CSCDR1);
+       prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
+                 MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
+       podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
+               MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
+
+       return parent_rate / (prediv * podf);
+}
+
+static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
+{
+       u32 reg, mux;
+
+       mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+                      &lp_apm_clk);
+       reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
+       reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
+       __raw_writel(reg, MXC_CCM_CSCMR1);
+
+       return 0;
+}
+
 static unsigned long get_high_reference_clock_rate(struct clk *clk)
 {
        return external_high_reference;
@@ -691,6 +721,12 @@ static struct clk uart_root_clk = {
        .set_parent = _clk_uart_set_parent,
 };
 
+static struct clk usboh3_clk = {
+       .parent = &pll2_sw_clk,
+       .get_rate = clk_usboh3_get_rate,
+       .set_parent = _clk_usboh3_set_parent,
+};
+
 static struct clk ahb_max_clk = {
        .parent = &ahb_clk,
        .enable_reg = MXC_CCM_CCGR0,
@@ -779,6 +815,12 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
        _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
        _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+       _REGISTER_CLOCK("mxc-ehci.0", "usb", usboh3_clk)
+       _REGISTER_CLOCK("mxc-ehci.0", "usb_ahb", ahb_clk)
+       _REGISTER_CLOCK("mxc-ehci.1", "usb", usboh3_clk)
+       _REGISTER_CLOCK("mxc-ehci.1", "usb_ahb", ahb_clk)
+       _REGISTER_CLOCK("fsl-usb2-udc", "usb", usboh3_clk)
+       _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", ahb_clk)
 };
 
 static void clk_tree_init(void)
@@ -819,6 +861,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
        clk_enable(&cpu_clk);
        clk_enable(&main_bus_clk);
 
+       /* set the usboh3_clk parent to pll2_sw_clk */
+       clk_set_parent(&usboh3_clk, &pll2_sw_clk);
+
        /* System timer */
        mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
                MX51_MXC_INT_GPT);
index d6fd396..7130449 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
  */
 
 #include <linux/platform_device.h>
+#include <linux/dma-mapping.h>
+#include <linux/gpio.h>
 #include <mach/hardware.h>
 #include <mach/imx-uart.h>
+#include <mach/irqs.h>
 
 static struct resource uart0[] = {
        {
@@ -89,8 +93,109 @@ struct platform_device mxc_fec_device = {
        .resource = mxc_fec_resources,
 };
 
-/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
+static u64 usb_dma_mask = DMA_BIT_MASK(32);
+
+static struct resource usbotg_resources[] = {
+       {
+               .start = MX51_OTG_BASE_ADDR,
+               .end = MX51_OTG_BASE_ADDR + 0x1ff,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = MX51_MXC_INT_USB_OTG,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+/* OTG gadget device */
+struct platform_device mxc_usbdr_udc_device = {
+       .name           = "fsl-usb2-udc",
+       .id             = -1,
+       .num_resources  = ARRAY_SIZE(usbotg_resources),
+       .resource       = usbotg_resources,
+       .dev            = {
+               .dma_mask               = &usb_dma_mask,
+               .coherent_dma_mask      = DMA_BIT_MASK(32),
+       },
+};
+
+struct platform_device mxc_usbdr_host_device = {
+       .name = "mxc-ehci",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(usbotg_resources),
+       .resource = usbotg_resources,
+       .dev = {
+               .dma_mask = &usb_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+static struct resource usbh1_resources[] = {
+       {
+               .start = MX51_OTG_BASE_ADDR + 0x200,
+               .end = MX51_OTG_BASE_ADDR + 0x200 + 0x1ff,
+               .flags = IORESOURCE_MEM,
+       },
+       {
+               .start = MX51_MXC_INT_USB_H1,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_usbh1_device = {
+       .name = "mxc-ehci",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(usbh1_resources),
+       .resource = usbh1_resources,
+       .dev = {
+               .dma_mask = &usb_dma_mask,
+               .coherent_dma_mask = DMA_BIT_MASK(32),
+       },
+};
+
+static struct resource mxc_wdt_resources[] = {
+       {
+               .start = MX51_WDOG_BASE_ADDR,
+               .end = MX51_WDOG_BASE_ADDR + SZ_16K - 1,
+               .flags = IORESOURCE_MEM,
+       },
+};
+
+struct platform_device mxc_wdt = {
+       .name = "imx2-wdt",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(mxc_wdt_resources),
+       .resource = mxc_wdt_resources,
+};
+
+static struct mxc_gpio_port mxc_gpio_ports[] = {
+       {
+               .chip.label = "gpio-0",
+               .base = MX51_IO_ADDRESS(MX51_GPIO1_BASE_ADDR),
+               .irq = MX51_MXC_INT_GPIO1_LOW,
+               .virtual_irq_start = MXC_GPIO_IRQ_START
+       },
+       {
+               .chip.label = "gpio-1",
+               .base = MX51_IO_ADDRESS(MX51_GPIO2_BASE_ADDR),
+               .irq = MX51_MXC_INT_GPIO2_LOW,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 1
+       },
+       {
+               .chip.label = "gpio-2",
+               .base = MX51_IO_ADDRESS(MX51_GPIO3_BASE_ADDR),
+               .irq = MX51_MXC_INT_GPIO3_LOW,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 2
+       },
+       {
+               .chip.label = "gpio-3",
+               .base = MX51_IO_ADDRESS(MX51_GPIO4_BASE_ADDR),
+               .irq = MX51_MXC_INT_GPIO4_LOW,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 32 * 3
+       },
+};
+
 int __init mxc_register_gpios(void)
 {
-       return 0;
+       return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
 }
index f339ab8..c879ae7 100644 (file)
@@ -2,3 +2,7 @@ extern struct platform_device mxc_uart_device0;
 extern struct platform_device mxc_uart_device1;
 extern struct platform_device mxc_uart_device2;
 extern struct platform_device mxc_fec_device;
+extern struct platform_device mxc_usbdr_host_device;
+extern struct platform_device mxc_usbh1_device;
+extern struct platform_device mxc_usbdr_udc_device;
+extern struct platform_device mxc_wdt;
index cb0b638..2a86461 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of the GNU General Public License as published by the
 #define MX35_H1_TLL_BIT                (1 << 5)
 #define MX35_H1_USBTE_BIT      (1 << 4)
 
-int mxc_set_usbcontrol(int port, unsigned int flags)
+#define MXC_OTG_OFFSET         0
+#define MXC_H1_OFFSET          0x200
+
+/* USB_CTRL */
+#define MXC_OTG_UCTRL_OWIE_BIT         (1 << 27)       /* OTG wakeup intr enable */
+#define MXC_OTG_UCTRL_OPM_BIT          (1 << 24)       /* OTG power mask */
+#define MXC_H1_UCTRL_H1UIE_BIT         (1 << 12)       /* Host1 ULPI interrupt enable */
+#define MXC_H1_UCTRL_H1WIE_BIT         (1 << 11)       /* HOST1 wakeup intr enable */
+#define MXC_H1_UCTRL_H1PM_BIT          (1 <<  8)               /* HOST1 power mask */
+
+/* USB_PHY_CTRL_FUNC */
+#define MXC_OTG_PHYCTRL_OC_DIS_BIT     (1 << 8)        /* OTG Disable Overcurrent Event */
+#define MXC_H1_OC_DIS_BIT                      (1 << 5)        /* UH1 Disable Overcurrent Event */
+
+#define MXC_USBCMD_OFFSET                      0x140
+
+/* USBCMD */
+#define MXC_UCMD_ITC_NO_THRESHOLD_MASK (~(0xff << 16)) /* Interrupt Threshold Control */
+
+int mxc_initialize_usb_hw(int port, unsigned int flags)
 {
        unsigned int v;
 #ifdef CONFIG_ARCH_MX3
@@ -186,9 +206,85 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
                return 0;
        }
 #endif /* CONFIG_MACH_MX27 */
+#ifdef CONFIG_ARCH_MX51
+       if (cpu_is_mx51()) {
+               void __iomem *usb_base;
+               u32 usbotg_base;
+               u32 usbother_base;
+               int ret = 0;
+
+               usb_base = ioremap(MX51_OTG_BASE_ADDR, SZ_4K);
+
+               switch (port) {
+               case 0: /* OTG port */
+                       usbotg_base = usb_base + MXC_OTG_OFFSET;
+                       break;
+               case 1: /* Host 1 port */
+                       usbotg_base = usb_base + MXC_H1_OFFSET;
+                       break;
+               default:
+                       printk(KERN_ERR"%s no such port %d\n", __func__, port);
+                       ret = -ENOENT;
+                       goto error;
+               }
+               usbother_base = usb_base + MX5_USBOTHER_REGS_OFFSET;
+
+               switch (port) {
+               case 0: /*OTG port */
+                       if (flags & MXC_EHCI_INTERNAL_PHY) {
+                               v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+                               if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+                                       v |= (MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is not used */
+                               else
+                                       v &= ~(MXC_OTG_PHYCTRL_OC_DIS_BIT | MXC_OTG_UCTRL_OPM_BIT); /* OC/USBPWR is used */
+                               __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+                               v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
+                               if (flags & MXC_EHCI_WAKEUP_ENABLED)
+                                       v |= MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup enable */
+                               else
+                                       v &= ~MXC_OTG_UCTRL_OWIE_BIT;/* OTG wakeup disable */
+                               __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
+                       }
+                       break;
+               case 1: /* Host 1 */
+                       /*Host ULPI */
+                       v = __raw_readl(usbother_base + MXC_USBCTRL_OFFSET);
+                       if (flags & MXC_EHCI_WAKEUP_ENABLED)
+                               v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
+                       else
+                               v &= ~(MXC_H1_UCTRL_H1WIE_BIT | MXC_H1_UCTRL_H1UIE_BIT);/* HOST1 wakeup/ULPI intr disable */
+
+                       if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+                               v &= ~MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
+                       else
+                               v |= MXC_H1_UCTRL_H1PM_BIT; /* HOST1 power mask used*/
+                       __raw_writel(v, usbother_base + MXC_USBCTRL_OFFSET);
+
+                       v = __raw_readl(usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+                       if (flags & MXC_EHCI_POWER_PINS_ENABLED)
+                               v &= ~MXC_H1_OC_DIS_BIT; /* OC is used */
+                       else
+                               v |= MXC_H1_OC_DIS_BIT; /* OC is not used */
+                       __raw_writel(v, usbother_base + MXC_USB_PHY_CTR_FUNC_OFFSET);
+
+                       v = __raw_readl(usbotg_base + MXC_USBCMD_OFFSET);
+                       if (flags & MXC_EHCI_ITC_NO_THRESHOLD)
+                               /* Interrupt Threshold Control:Immediate (no threshold) */
+                               v &= MXC_UCMD_ITC_NO_THRESHOLD_MASK;
+                       __raw_writel(v, usbotg_base + MXC_USBCMD_OFFSET);
+                       break;
+               }
+
+error:
+               iounmap(usb_base);
+               return ret;
+       }
+#endif
        printk(KERN_WARNING
                "%s() unable to setup USBCONTROL for this CPU\n", __func__);
        return -EINVAL;
 }
-EXPORT_SYMBOL(mxc_set_usbcontrol);
+EXPORT_SYMBOL(mxc_initialize_usb_hw);
 
index 70b2389..71437c6 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
  *
  * Based on code from Freescale,
- * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2004-2010 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
@@ -38,7 +38,6 @@ static int gpio_table_size;
 #define GPIO_ICR2      (cpu_is_mx1_mx2() ? 0x2C : 0x10)
 #define GPIO_IMR       (cpu_is_mx1_mx2() ? 0x30 : 0x14)
 #define GPIO_ISR       (cpu_is_mx1_mx2() ? 0x34 : 0x18)
-#define GPIO_ISR       (cpu_is_mx1_mx2() ? 0x34 : 0x18)
 
 #define GPIO_INT_LOW_LEV       (cpu_is_mx1_mx2() ? 0x3 : 0x0)
 #define GPIO_INT_HIGH_LEV      (cpu_is_mx1_mx2() ? 0x2 : 0x1)
@@ -289,7 +288,7 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
                /* its a serious configuration bug when it fails */
                BUG_ON( gpiochip_add(&port[i].chip) < 0 );
 
-               if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25()) {
+               if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51()) {
                        /* setup one handler for each entry */
                        set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
                        set_irq_data(port[i].irq, &port[i]);
index fc5fec9..36ff3ce 100644 (file)
@@ -26,6 +26,7 @@ enum mx31moboard_boards {
        MX31DEVBOARD    = 1,
        MX31MARXBOT     = 2,
        MX31SMARTBOT    = 3,
+       MX31EYEBOT      = 4,
 };
 
 /*
@@ -35,7 +36,7 @@ enum mx31moboard_boards {
 
 extern void mx31moboard_devboard_init(void);
 extern void mx31moboard_marxbot_init(void);
-extern void mx31moboard_smartbot_init(void);
+extern void mx31moboard_smartbot_init(int board);
 
 #endif
 
index e51465d..cbaed29 100644 (file)
@@ -719,6 +719,23 @@ enum iomux_pins {
 #define MX31_PIN_SRXD5__SRXD5          IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SCK5__SCK5            IOMUX_MODE(MX31_PIN_SCK5, IOMUX_CONFIG_FUNC)
 #define MX31_PIN_SFS5__SFS5            IOMUX_MODE(MX31_PIN_SFS5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW0_KEY_ROW0     IOMUX_MODE(MX31_PIN_KEY_ROW0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW1_KEY_ROW1     IOMUX_MODE(MX31_PIN_KEY_ROW1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW2_KEY_ROW2     IOMUX_MODE(MX31_PIN_KEY_ROW2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW3_KEY_ROW3     IOMUX_MODE(MX31_PIN_KEY_ROW3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW4_KEY_ROW4     IOMUX_MODE(MX31_PIN_KEY_ROW4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW5_KEY_ROW5     IOMUX_MODE(MX31_PIN_KEY_ROW5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW6_KEY_ROW6     IOMUX_MODE(MX31_PIN_KEY_ROW6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_ROW7_KEY_ROW7     IOMUX_MODE(MX31_PIN_KEY_ROW7, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL0_KEY_COL0     IOMUX_MODE(MX31_PIN_KEY_COL0, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL1_KEY_COL1     IOMUX_MODE(MX31_PIN_KEY_COL1, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL2_KEY_COL2     IOMUX_MODE(MX31_PIN_KEY_COL2, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL3_KEY_COL3     IOMUX_MODE(MX31_PIN_KEY_COL3, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL4_KEY_COL4     IOMUX_MODE(MX31_PIN_KEY_COL4, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL5_KEY_COL5     IOMUX_MODE(MX31_PIN_KEY_COL5, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL6_KEY_COL6     IOMUX_MODE(MX31_PIN_KEY_COL6, IOMUX_CONFIG_FUNC)
+#define MX31_PIN_KEY_COL7_KEY_COL7     IOMUX_MODE(MX31_PIN_KEY_COL7, IOMUX_CONFIG_FUNC)
+
 
 /*
  * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0,
index b4f975e..ab0f95d 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -37,6 +38,11 @@ typedef enum iomux_config {
                                PAD_CTL_SRE_FAST)
 #define MX51_UART3_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
                                PAD_CTL_SRE_FAST)
+#define MX51_USBH1_PAD_CTRL    (PAD_CTL_SRE_FAST | PAD_CTL_DSE_HIGH | \
+                               PAD_CTL_PUS_100K_UP | PAD_CTL_PUE | \
+                               PAD_CTL_PKE | PAD_CTL_HYS)
+#define MX51_GPIO_PAD_CTRL             (PAD_CTL_DSE_HIGH | PAD_CTL_PKE | \
+                               PAD_CTL_SRE_FAST)
 
 /*
  * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
@@ -57,6 +63,7 @@ typedef enum iomux_config {
 #define MX51_PAD_GPIO_2_3__EIM_D19     IOMUX_PAD(0x3fc, 0x068, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_2_4__EIM_D20     IOMUX_PAD(0x400, 0x06c, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_2_5__EIM_D21     IOMUX_PAD(0x404, 0x070, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D21__GPIO_2_5     IOMUX_PAD(0x404, 0x070, IOMUX_CONFIG_ALT1, 0x0,   0, MX51_GPIO_PAD_CTRL)
 #define MX51_PAD_GPIO_2_6__EIM_D22     IOMUX_PAD(0x408, 0x074, 1, 0x0,   0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_2_7__EIM_D23     IOMUX_PAD(0x40c, 0x078, 1, 0x0,   0, NO_PAD_CTRL)
 
@@ -208,18 +215,19 @@ typedef enum iomux_config {
 #define MX51_PAD_KEY_COL3__KEY_COL3    IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_KEY_COL4__KEY_COL4    IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_KEY_COL5__KEY_COL5    IOMUX_PAD(0x660, 0x270, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_25__USBH1_CLK  IOMUX_PAD(0x678, 0x278, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_26__USBH1_DIR  IOMUX_PAD(0x67C, 0x27C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_27__USBH1_STP  IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_28__USBH1_NXT  IOMUX_PAD(0x684, 0x284, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_11__USBH1_DATA0        IOMUX_PAD(0x688, 0x288, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_12__USBH1_DATA1        IOMUX_PAD(0x68C, 0x28C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_13__USBH1_DATA2        IOMUX_PAD(0x690, 0x290, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_14__USBH1_DATA3        IOMUX_PAD(0x694, 0x294, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_15__USBH1_DATA4        IOMUX_PAD(0x698, 0x298, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_16__USBH1_DATA5        IOMUX_PAD(0x69C, 0x29C, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_17__USBH1_DATA6        IOMUX_PAD(0x6A0, 0x2A0, 2, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_18__USBH1_DATA7        IOMUX_PAD(0x6A4, 0x2A4, 2, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_USBH1_CLK__USBH1_CLK  IOMUX_PAD(0x678, 0x278, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DIR__USBH1_DIR  IOMUX_PAD(0x67C, 0x27C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__USBH1_STP  IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_STP__GPIO_1_27  IOMUX_PAD(0x680, 0x280, IOMUX_CONFIG_GPIO, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_NXT__USBH1_NXT  IOMUX_PAD(0x684, 0x284, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA0__USBH1_DATA0      IOMUX_PAD(0x688, 0x288, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA1__USBH1_DATA1      IOMUX_PAD(0x68C, 0x28C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA2__USBH1_DATA2      IOMUX_PAD(0x690, 0x290, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA3__USBH1_DATA3      IOMUX_PAD(0x694, 0x294, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA4__USBH1_DATA4      IOMUX_PAD(0x698, 0x298, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA5__USBH1_DATA5      IOMUX_PAD(0x69C, 0x29C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA6__USBH1_DATA6      IOMUX_PAD(0x6A0, 0x2A0, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
+#define MX51_PAD_USBH1_DATA7__USBH1_DATA7      IOMUX_PAD(0x6A4, 0x2A4, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
 #define MX51_PAD_GPIO_3_0__DI1_PIN11   IOMUX_PAD(0x6A8, 0x2A8, 4, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_3_1__DI1_PIN12   IOMUX_PAD(0x6AC, 0x2AC, 4, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_3_2__DI1_PIN13   IOMUX_PAD(0x6B0, 0x2B0, 4, 0x0, 0, NO_PAD_CTRL)
@@ -299,7 +307,7 @@ typedef enum iomux_config {
 #define MX51_PAD_GPIO_1_4__GPIO1_4     IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_1_5__GPIO1_5     IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
 #define MX51_PAD_GPIO_1_6__GPIO1_6     IOMUX_PAD(0x80C, 0x3E0, 0, 0x0, 0, NO_PAD_CTRL)
-#define MX51_PAD_GPIO_1_7__GPIO1_7     IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_7__GPIO1_7     IOMUX_PAD(0x810, 0x3E4, 0, 0x0, 0, MX51_GPIO_PAD_CTRL)
 #define MX51_PAD_GPIO_1_8__GPIO1_8     IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 1, \
                                                (PAD_CTL_SRE_SLOW | PAD_CTL_DSE_MED | PAD_CTL_PUS_100K_UP |  PAD_CTL_HYS))
 #define MX51_PAD_GPIO_1_9__GPIO1_9     IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
index 4b9b836..7fc5f99 100644 (file)
 #define MXC_EHCI_INTERNAL_PHY          (1 << 7)
 #define MXC_EHCI_IPPUE_DOWN            (1 << 8)
 #define MXC_EHCI_IPPUE_UP              (1 << 9)
+#define MXC_EHCI_WAKEUP_ENABLED        (1 << 10)
+#define MXC_EHCI_ITC_NO_THRESHOLD      (1 << 11)
+
+#define MXC_USBCTRL_OFFSET             0
+#define MXC_USB_PHY_CTR_FUNC_OFFSET    0x8
+#define MXC_USB_PHY_CTR_FUNC2_OFFSET   0xc
+
+#define MX5_USBOTHER_REGS_OFFSET       0x800
+
+/* USB_PHY_CTRL_FUNC2*/
+#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);
@@ -35,7 +47,7 @@ struct mxc_usbh_platform_data {
        struct otg_transceiver  *otg;
 };
 
-int mxc_set_usbcontrol(int port, unsigned int flags);
+int mxc_initialize_usb_hw(int port, unsigned int flags);
 
 #endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
 
index c1ce51a..f9a1b05 100644 (file)
 #define MX2_TSTAT_COMP         (1 << 0)
 
 /* MX31, MX35, MX25, MXC91231, MX5 */
-#define MX3_TCTL_WAITEN                (1 << 3) /* Wait enable mode */
-#define MX3_TCTL_CLK_IPG       (1 << 6)
-#define MX3_TCTL_FRR           (1 << 9)
-#define MX3_IR                 0x0c
-#define MX3_TSTAT              0x08
-#define MX3_TSTAT_OF1          (1 << 0)
-#define MX3_TCN                        0x24
-#define MX3_TCMP               0x10
+#define V2_TCTL_WAITEN         (1 << 3) /* Wait enable mode */
+#define V2_TCTL_CLK_IPG                (1 << 6)
+#define V2_TCTL_FRR            (1 << 9)
+#define V2_IR                  0x0c
+#define V2_TSTAT               0x08
+#define V2_TSTAT_OF1           (1 << 0)
+#define V2_TCN                 0x24
+#define V2_TCMP                        0x10
 
 #define timer_is_v1()  (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
 #define timer_is_v2()  (!timer_is_v1())
@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void)
        unsigned int tmp;
 
        if (timer_is_v2())
-               __raw_writel(0, timer_base + MX3_IR);
+               __raw_writel(0, timer_base + V2_IR);
        else {
                tmp = __raw_readl(timer_base + MXC_TCTL);
                __raw_writel(tmp & ~MX1_2_TCTL_IRQEN, timer_base + MXC_TCTL);
@@ -86,7 +86,7 @@ static inline void gpt_irq_disable(void)
 static inline void gpt_irq_enable(void)
 {
        if (timer_is_v2())
-               __raw_writel(1<<0, timer_base + MX3_IR);
+               __raw_writel(1<<0, timer_base + V2_IR);
        else {
                __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
                        timer_base + MXC_TCTL);
@@ -102,7 +102,7 @@ static void gpt_irq_acknowledge(void)
                        __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
                                timer_base + MX1_2_TSTAT);
        } else if (timer_is_v2())
-               __raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
+               __raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 }
 
 static cycle_t mx1_2_get_cycles(struct clocksource *cs)
@@ -110,9 +110,9 @@ static cycle_t mx1_2_get_cycles(struct clocksource *cs)
        return __raw_readl(timer_base + MX1_2_TCN);
 }
 
-static cycle_t mx3_get_cycles(struct clocksource *cs)
+static cycle_t v2_get_cycles(struct clocksource *cs)
 {
-       return __raw_readl(timer_base + MX3_TCN);
+       return __raw_readl(timer_base + V2_TCN);
 }
 
 static struct clocksource clocksource_mxc = {
@@ -129,7 +129,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
        unsigned int c = clk_get_rate(timer_clk);
 
        if (timer_is_v2())
-               clocksource_mxc.read = mx3_get_cycles;
+               clocksource_mxc.read = v2_get_cycles;
 
        clocksource_mxc.mult = clocksource_hz2mult(c,
                                        clocksource_mxc.shift);
@@ -153,16 +153,16 @@ static int mx1_2_set_next_event(unsigned long evt,
                                -ETIME : 0;
 }
 
-static int mx3_set_next_event(unsigned long evt,
+static int v2_set_next_event(unsigned long evt,
                              struct clock_event_device *unused)
 {
        unsigned long tcmp;
 
-       tcmp = __raw_readl(timer_base + MX3_TCN) + evt;
+       tcmp = __raw_readl(timer_base + V2_TCN) + evt;
 
-       __raw_writel(tcmp, timer_base + MX3_TCMP);
+       __raw_writel(tcmp, timer_base + V2_TCMP);
 
-       return (int)(tcmp - __raw_readl(timer_base + MX3_TCN)) < 0 ?
+       return (int)(tcmp - __raw_readl(timer_base + V2_TCN)) < 0 ?
                                -ETIME : 0;
 }
 
@@ -192,8 +192,8 @@ static void mxc_set_mode(enum clock_event_mode mode,
        if (mode != clockevent_mode) {
                /* Set event time into far-far future */
                if (timer_is_v2())
-                       __raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
-                                       timer_base + MX3_TCMP);
+                       __raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
+                                       timer_base + V2_TCMP);
                else
                        __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
                                        timer_base + MX1_2_TCMP);
@@ -245,7 +245,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
        uint32_t tstat;
 
        if (timer_is_v2())
-               tstat = __raw_readl(timer_base + MX3_TSTAT);
+               tstat = __raw_readl(timer_base + V2_TSTAT);
        else
                tstat = __raw_readl(timer_base + MX1_2_TSTAT);
 
@@ -276,7 +276,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
        unsigned int c = clk_get_rate(timer_clk);
 
        if (timer_is_v2())
-               clockevent_mxc.set_next_event = mx3_set_next_event;
+               clockevent_mxc.set_next_event = v2_set_next_event;
 
        clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
                                        clockevent_mxc.shift);
@@ -308,7 +308,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
        __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
 
        if (timer_is_v2())
-               tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
+               tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
        else
                tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
 
index afa6709..9b86d2a 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C)2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  *
  * The code contained herein is licensed under the GNU General Public
  * License. You may obtain a copy of the GNU General Public License
@@ -19,6 +19,7 @@
 #include <asm/mach/irq.h>
 
 #include <mach/hardware.h>
+#include <mach/common.h>
 
 /*
  *****************************************
@@ -144,6 +145,7 @@ void __init tzic_init_irq(void __iomem *irqbase)
                set_irq_handler(i, handle_level_irq);
                set_irq_flags(i, IRQF_VALID);
        }
+       mxc_register_gpios();
 
        pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
 }
index 2dd4cfe..b9dee28 100644 (file)
@@ -295,6 +295,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
 
        card->type = MMC_TYPE_SDIO;
 
+       /*
+        * Call the optional HC's init_card function to handle quirks.
+        */
+       if (host->ops->init_card)
+               host->ops->init_card(host, card);
+
        /*
         * For native busses:  set card RCA and quit open drain mode.
         */
index 2df9041..ec18e3b 100644 (file)
@@ -119,6 +119,7 @@ struct mxcmci_host {
        int                     detect_irq;
        int                     dma;
        int                     do_dma;
+       int                     use_sdio;
        unsigned int            power_mode;
        struct imxmmc_platform_data *pdata;
 
@@ -138,6 +139,7 @@ struct mxcmci_host {
        int                     clock;
 
        struct work_struct      datawork;
+       spinlock_t              lock;
 };
 
 static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios);
@@ -151,6 +153,8 @@ static void mxcmci_softreset(struct mxcmci_host *host)
 {
        int i;
 
+       dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");
+
        /* reset sequence */
        writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
        writew(STR_STP_CLK_RESET | STR_STP_CLK_START_CLK,
@@ -224,6 +228,9 @@ static int mxcmci_setup_data(struct mxcmci_host *host, struct mmc_data *data)
 static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
                unsigned int cmdat)
 {
+       u32 int_cntr;
+       unsigned long flags;
+
        WARN_ON(host->cmd != NULL);
        host->cmd = cmd;
 
@@ -247,12 +254,16 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
                return -EINVAL;
        }
 
+       int_cntr = INT_END_CMD_RES_EN;
+
        if (mxcmci_use_dma(host))
-               writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN |
-                               INT_END_CMD_RES_EN,
-                               host->base + MMC_REG_INT_CNTR);
-       else
-               writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR);
+               int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
+
+       spin_lock_irqsave(&host->lock, flags);
+       if (host->use_sdio)
+               int_cntr |= INT_SDIO_IRQ_EN;
+       writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+       spin_unlock_irqrestore(&host->lock, flags);
 
        writew(cmd->opcode, host->base + MMC_REG_CMD);
        writel(cmd->arg, host->base + MMC_REG_ARG);
@@ -264,7 +275,14 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
 static void mxcmci_finish_request(struct mxcmci_host *host,
                struct mmc_request *req)
 {
-       writel(0, host->base + MMC_REG_INT_CNTR);
+       u32 int_cntr = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&host->lock, flags);
+       if (host->use_sdio)
+               int_cntr |= INT_SDIO_IRQ_EN;
+       writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+       spin_unlock_irqrestore(&host->lock, flags);
 
        host->req = NULL;
        host->cmd = NULL;
@@ -290,16 +308,25 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat)
                dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
                                stat);
                if (stat & STATUS_CRC_READ_ERR) {
+                       dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
                        data->error = -EILSEQ;
                } else if (stat & STATUS_CRC_WRITE_ERR) {
                        u32 err_code = (stat >> 9) & 0x3;
-                       if (err_code == 2) /* No CRC response */
+                       if (err_code == 2) { /* No CRC response */
+                               dev_err(mmc_dev(host->mmc),
+                                       "%s: No CRC -ETIMEDOUT\n", __func__);
                                data->error = -ETIMEDOUT;
-                       else
+                       } else {
+                               dev_err(mmc_dev(host->mmc),
+                                       "%s: -EILSEQ\n", __func__);
                                data->error = -EILSEQ;
+                       }
                } else if (stat & STATUS_TIME_OUT_READ) {
+                       dev_err(mmc_dev(host->mmc),
+                               "%s: read -ETIMEDOUT\n", __func__);
                        data->error = -ETIMEDOUT;
                } else {
+                       dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
                        data->error = -EIO;
                }
        } else {
@@ -433,8 +460,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host)
        struct scatterlist *sg;
        int stat, i;
 
-       host->datasize = 0;
-
        host->data = data;
        host->datasize = 0;
 
@@ -464,6 +489,9 @@ static void mxcmci_datawork(struct work_struct *work)
        struct mxcmci_host *host = container_of(work, struct mxcmci_host,
                                                  datawork);
        int datastat = mxcmci_transfer_data(host);
+
+       writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
+               host->base + MMC_REG_STATUS);
        mxcmci_finish_data(host, datastat);
 
        if (host->req->stop) {
@@ -523,15 +551,35 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat)
 static irqreturn_t mxcmci_irq(int irq, void *devid)
 {
        struct mxcmci_host *host = devid;
+       unsigned long flags;
+       bool sdio_irq;
        u32 stat;
 
        stat = readl(host->base + MMC_REG_STATUS);
-       writel(stat, host->base + MMC_REG_STATUS);
+       writel(stat & ~(STATUS_SDIO_INT_ACTIVE | STATUS_DATA_TRANS_DONE |
+                       STATUS_WRITE_OP_DONE), host->base + MMC_REG_STATUS);
 
        dev_dbg(mmc_dev(host->mmc), "%s: 0x%08x\n", __func__, stat);
 
+       spin_lock_irqsave(&host->lock, flags);
+       sdio_irq = (stat & STATUS_SDIO_INT_ACTIVE) && host->use_sdio;
+       spin_unlock_irqrestore(&host->lock, flags);
+
+#ifdef HAS_DMA
+       if (mxcmci_use_dma(host) &&
+           (stat & (STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE)))
+               writel(STATUS_READ_OP_DONE | STATUS_WRITE_OP_DONE,
+                       host->base + MMC_REG_STATUS);
+#endif
+
+       if (sdio_irq) {
+               writel(STATUS_SDIO_INT_ACTIVE, host->base + MMC_REG_STATUS);
+               mmc_signal_sdio_irq(host->mmc);
+       }
+
        if (stat & STATUS_END_CMD_RESP)
                mxcmci_cmd_done(host, stat);
+
 #ifdef HAS_DMA
        if (mxcmci_use_dma(host) &&
                  (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
@@ -668,11 +716,46 @@ static int mxcmci_get_ro(struct mmc_host *mmc)
        return -ENOSYS;
 }
 
+static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable)
+{
+       struct mxcmci_host *host = mmc_priv(mmc);
+       unsigned long flags;
+       u32 int_cntr;
+
+       spin_lock_irqsave(&host->lock, flags);
+       host->use_sdio = enable;
+       int_cntr = readl(host->base + MMC_REG_INT_CNTR);
+
+       if (enable)
+               int_cntr |= INT_SDIO_IRQ_EN;
+       else
+               int_cntr &= ~INT_SDIO_IRQ_EN;
+
+       writel(int_cntr, host->base + MMC_REG_INT_CNTR);
+       spin_unlock_irqrestore(&host->lock, flags);
+}
+
+static void mxcmci_init_card(struct mmc_host *host, struct mmc_card *card)
+{
+       /*
+        * MX3 SoCs have a silicon bug which corrupts CRC calculation of
+        * multi-block transfers when connected SDIO peripheral doesn't
+        * drive the BUSY line as required by the specs.
+        * One way to prevent this is to only allow 1-bit transfers.
+        */
+
+       if (cpu_is_mx3() && card->type == MMC_TYPE_SDIO)
+               host->caps &= ~MMC_CAP_4_BIT_DATA;
+       else
+               host->caps |= MMC_CAP_4_BIT_DATA;
+}
 
 static const struct mmc_host_ops mxcmci_ops = {
-       .request        = mxcmci_request,
-       .set_ios        = mxcmci_set_ios,
-       .get_ro         = mxcmci_get_ro,
+       .request                = mxcmci_request,
+       .set_ios                = mxcmci_set_ios,
+       .get_ro                 = mxcmci_get_ro,
+       .enable_sdio_irq        = mxcmci_enable_sdio_irq,
+       .init_card              = mxcmci_init_card,
 };
 
 static int mxcmci_probe(struct platform_device *pdev)
@@ -700,7 +783,7 @@ static int mxcmci_probe(struct platform_device *pdev)
        }
 
        mmc->ops = &mxcmci_ops;
-       mmc->caps = MMC_CAP_4_BIT_DATA;
+       mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_SDIO_IRQ;
 
        /* MMC core transfer sizes tunable parameters */
        mmc->max_hw_segs = 64;
@@ -719,6 +802,7 @@ static int mxcmci_probe(struct platform_device *pdev)
 
        host->mmc = mmc;
        host->pdata = pdev->dev.platform_data;
+       spin_lock_init(&host->lock);
 
        if (host->pdata && host->pdata->ocr_avail)
                mmc->ocr_avail = host->pdata->ocr_avail;
index b2900d8..fb03aff 100644 (file)
@@ -38,7 +38,7 @@
 #define DRIVER_NAME "mxc_nand"
 
 #define nfc_is_v21()           (cpu_is_mx25() || cpu_is_mx35())
-#define nfc_is_v1()            (cpu_is_mx31() || cpu_is_mx27())
+#define nfc_is_v1()            (cpu_is_mx31() || cpu_is_mx27() || cpu_is_mx21())
 
 /* Addresses for NFC registers */
 #define NFC_BUF_SIZE           0xE00
@@ -168,11 +168,7 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
 {
        struct mxc_nand_host *host = dev_id;
 
-       uint16_t tmp;
-
-       tmp = readw(host->regs + NFC_CONFIG1);
-       tmp |= NFC_INT_MSK; /* Disable interrupt */
-       writew(tmp, host->regs + NFC_CONFIG1);
+       disable_irq_nosync(irq);
 
        wake_up(&host->irq_waitq);
 
@@ -184,15 +180,13 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
  */
 static void wait_op_done(struct mxc_nand_host *host, int useirq)
 {
-       uint32_t tmp;
-       int max_retries = 2000;
+       uint16_t tmp;
+       int max_retries = 8000;
 
        if (useirq) {
                if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
 
-                       tmp = readw(host->regs + NFC_CONFIG1);
-                       tmp  &= ~NFC_INT_MSK;   /* Enable interrupt */
-                       writew(tmp, host->regs + NFC_CONFIG1);
+                       enable_irq(host->irq);
 
                        wait_event(host->irq_waitq,
                                readw(host->regs + NFC_CONFIG2) & NFC_INT);
@@ -226,8 +220,23 @@ static void send_cmd(struct mxc_nand_host *host, uint16_t cmd, int useirq)
        writew(cmd, host->regs + NFC_FLASH_CMD);
        writew(NFC_CMD, host->regs + NFC_CONFIG2);
 
-       /* Wait for operation to complete */
-       wait_op_done(host, useirq);
+       if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
+               int max_retries = 100;
+               /* Reset completion is indicated by NFC_CONFIG2 */
+               /* being set to 0 */
+               while (max_retries-- > 0) {
+                       if (readw(host->regs + NFC_CONFIG2) == 0) {
+                               break;
+                       }
+                       udelay(1);
+               }
+               if (max_retries < 0)
+                       DEBUG(MTD_DEBUG_LEVEL0, "%s: RESET failed\n",
+                             __func__);
+       } else {
+               /* Wait for operation to complete */
+               wait_op_done(host, useirq);
+       }
 }
 
 /* This function sends an address (or partial address) to the
@@ -542,6 +551,41 @@ static void mxc_do_addr_cycle(struct mtd_info *mtd, int column, int page_addr)
        }
 }
 
+static void preset(struct mtd_info *mtd)
+{
+       struct nand_chip *nand_chip = mtd->priv;
+       struct mxc_nand_host *host = nand_chip->priv;
+       uint16_t tmp;
+
+       /* enable interrupt, disable spare enable */
+       tmp = readw(host->regs + NFC_CONFIG1);
+       tmp &= ~NFC_INT_MSK;
+       tmp &= ~NFC_SP_EN;
+       if (nand_chip->ecc.mode == NAND_ECC_HW) {
+               tmp |= NFC_ECC_EN;
+       } else {
+               tmp &= ~NFC_ECC_EN;
+       }
+       writew(tmp, host->regs + NFC_CONFIG1);
+       /* preset operation */
+
+       /* Unlock the internal RAM Buffer */
+       writew(0x2, host->regs + NFC_CONFIG);
+
+       /* Blocks to be unlocked */
+       if (nfc_is_v21()) {
+               writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
+               writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
+       } else if (nfc_is_v1()) {
+               writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
+               writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
+       } else
+               BUG();
+
+       /* Unlock Block Command for given address range */
+       writew(0x4, host->regs + NFC_WRPROT);
+}
+
 /* Used by the upper layer to write command to NAND Flash for
  * different operations to be carried out on NAND Flash */
 static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
@@ -559,6 +603,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
 
        /* Command pre-processing step */
        switch (command) {
+       case NAND_CMD_RESET:
+               send_cmd(host, command, false);
+               preset(mtd);
+               break;
 
        case NAND_CMD_STATUS:
                host->buf_start = 0;
@@ -679,7 +727,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
        struct mxc_nand_platform_data *pdata = pdev->dev.platform_data;
        struct mxc_nand_host *host;
        struct resource *res;
-       uint16_t tmp;
        int err = 0, nr_parts = 0;
        struct nand_ecclayout *oob_smallpage, *oob_largepage;
 
@@ -743,51 +790,17 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                host->spare_len = 64;
                oob_smallpage = &nandv2_hw_eccoob_smallpage;
                oob_largepage = &nandv2_hw_eccoob_largepage;
+               this->ecc.bytes = 9;
        } else if (nfc_is_v1()) {
                host->regs = host->base;
                host->spare0 = host->base + 0x800;
                host->spare_len = 16;
                oob_smallpage = &nandv1_hw_eccoob_smallpage;
                oob_largepage = &nandv1_hw_eccoob_largepage;
-       } else
-               BUG();
-
-       /* disable interrupt and spare enable */
-       tmp = readw(host->regs + NFC_CONFIG1);
-       tmp |= NFC_INT_MSK;
-       tmp &= ~NFC_SP_EN;
-       writew(tmp, host->regs + NFC_CONFIG1);
-
-       init_waitqueue_head(&host->irq_waitq);
-
-       host->irq = platform_get_irq(pdev, 0);
-
-       err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host);
-       if (err)
-               goto eirq;
-
-       /* Reset NAND */
-       this->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
-
-       /* preset operation */
-       /* Unlock the internal RAM Buffer */
-       writew(0x2, host->regs + NFC_CONFIG);
-
-       /* Blocks to be unlocked */
-       if (nfc_is_v21()) {
-               writew(0x0, host->regs + NFC_V21_UNLOCKSTART_BLKADDR);
-               writew(0xffff, host->regs + NFC_V21_UNLOCKEND_BLKADDR);
-               this->ecc.bytes = 9;
-       } else if (nfc_is_v1()) {
-               writew(0x0, host->regs + NFC_V1_UNLOCKSTART_BLKADDR);
-               writew(0x4000, host->regs + NFC_V1_UNLOCKEND_BLKADDR);
                this->ecc.bytes = 3;
        } else
                BUG();
 
-       /* Unlock Block Command for given address range */
-       writew(0x4, host->regs + NFC_WRPROT);
-
        this->ecc.size = 512;
        this->ecc.layout = oob_smallpage;
 
@@ -796,14 +809,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                this->ecc.hwctl = mxc_nand_enable_hwecc;
                this->ecc.correct = mxc_nand_correct_data;
                this->ecc.mode = NAND_ECC_HW;
-               tmp = readw(host->regs + NFC_CONFIG1);
-               tmp |= NFC_ECC_EN;
-               writew(tmp, host->regs + NFC_CONFIG1);
        } else {
                this->ecc.mode = NAND_ECC_SOFT;
-               tmp = readw(host->regs + NFC_CONFIG1);
-               tmp &= ~NFC_ECC_EN;
-               writew(tmp, host->regs + NFC_CONFIG1);
        }
 
        /* NAND bus width determines access funtions used by upper layer */
@@ -817,6 +824,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
                this->options |= NAND_USE_FLASH_BBT;
        }
 
+       init_waitqueue_head(&host->irq_waitq);
+
+       host->irq = platform_get_irq(pdev, 0);
+
+       err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host);
+       if (err)
+               goto eirq;
+
        /* first scan to find the device and get the page size */
        if (nand_scan_ident(mtd, 1)) {
                err = -ENXIO;
index ead59f4..544ccfd 100644 (file)
@@ -199,8 +199,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
        writel(pdata->portsc, hcd->regs + PORTSC_OFFSET);
        mdelay(10);
 
-       /* setup USBCONTROL. */
-       ret = mxc_set_usbcontrol(pdev->id, pdata->flags);
+       /* setup specific usb hw */
+       ret = mxc_initialize_usb_hw(pdev->id, pdata->flags);
        if (ret < 0)
                goto err_init;
 
index 43eaf5c..3196c84 100644 (file)
@@ -108,6 +108,9 @@ struct mmc_host_ops {
        int     (*get_cd)(struct mmc_host *host);
 
        void    (*enable_sdio_irq)(struct mmc_host *host, int enable);
+
+       /* optional callback for HC quirks */
+       void    (*init_card)(struct mmc_host *host, struct mmc_card *card);
 };
 
 struct mmc_card;