Commit 9bfe99a8 authored by Russell King's avatar Russell King

Merge branch 'for-rmk' of git://git.pengutronix.de/git/imx/linux-2.6 into devel-stable

parents f72caf7e 54c1f636
...@@ -809,7 +809,22 @@ CONFIG_SSB_POSSIBLE=y ...@@ -809,7 +809,22 @@ CONFIG_SSB_POSSIBLE=y
CONFIG_DUMMY_CONSOLE=y CONFIG_DUMMY_CONSOLE=y
# CONFIG_SOUND is not set # CONFIG_SOUND is not set
# CONFIG_HID_SUPPORT 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=y
# CONFIG_MMC_DEBUG is not set # CONFIG_MMC_DEBUG is not set
# CONFIG_MMC_UNSAFE_RESUME is not set # CONFIG_MMC_UNSAFE_RESUME is not set
......
...@@ -109,12 +109,7 @@ DEFINE_IMX_GPT_DEVICE(4, MX27_GPT5_BASE_ADDR, MX27_INT_GPT5); ...@@ -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); DEFINE_IMX_GPT_DEVICE(5, MX27_GPT6_BASE_ADDR, MX27_INT_GPT6);
#endif #endif
/* /* Watchdog: i.MX1 has seperate driver, i.MX21 and i.MX27 are equal */
* Watchdog:
* - i.MX1
* - i.MX21
* - i.MX27
*/
static struct resource mxc_wdt_resources[] = { static struct resource mxc_wdt_resources[] = {
{ {
.start = MX2x_WDOG_BASE_ADDR, .start = MX2x_WDOG_BASE_ADDR,
...@@ -124,7 +119,7 @@ static struct resource mxc_wdt_resources[] = { ...@@ -124,7 +119,7 @@ static struct resource mxc_wdt_resources[] = {
}; };
struct platform_device mxc_wdt = { struct platform_device mxc_wdt = {
.name = "mxc_wdt", .name = "imx2-wdt",
.id = 0, .id = 0,
.num_resources = ARRAY_SIZE(mxc_wdt_resources), .num_resources = ARRAY_SIZE(mxc_wdt_resources),
.resource = mxc_wdt_resources, .resource = mxc_wdt_resources,
......
...@@ -145,6 +145,7 @@ static struct mxc_nand_platform_data pca100_nand_board_info = { ...@@ -145,6 +145,7 @@ static struct mxc_nand_platform_data pca100_nand_board_info = {
static struct platform_device *platform_devices[] __initdata = { static struct platform_device *platform_devices[] __initdata = {
&mxc_w1_master_device, &mxc_w1_master_device,
&mxc_fec_device, &mxc_fec_device,
&mxc_wdt,
}; };
static struct imxi2c_platform_data pca100_i2c_1_data = { static struct imxi2c_platform_data pca100_i2c_1_data = {
......
...@@ -182,6 +182,7 @@ static struct platform_device *platform_devices[] __initdata = { ...@@ -182,6 +182,7 @@ static struct platform_device *platform_devices[] __initdata = {
&mxc_w1_master_device, &mxc_w1_master_device,
&mxc_fec_device, &mxc_fec_device,
&pcm038_sram_mtd_device, &pcm038_sram_mtd_device,
&mxc_wdt,
}; };
/* On pcm038 there's a sram attached to CS1, we enable the chipselect here and /* On pcm038 there's a sram attached to CS1, we enable the chipselect here and
......
...@@ -500,3 +500,18 @@ struct platform_device mx25_fb_device = { ...@@ -500,3 +500,18 @@ struct platform_device mx25_fb_device = {
.coherent_dma_mask = 0xFFFFFFFF, .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,
};
...@@ -21,3 +21,4 @@ extern struct platform_device mx25_fec_device; ...@@ -21,3 +21,4 @@ extern struct platform_device mx25_fec_device;
extern struct platform_device mxc_nand_device; extern struct platform_device mxc_nand_device;
extern struct platform_device mx25_rtc_device; extern struct platform_device mx25_rtc_device;
extern struct platform_device mx25_fb_device; extern struct platform_device mx25_fb_device;
extern struct platform_device mxc_wdt;
...@@ -82,6 +82,7 @@ config MACH_MX31MOBOARD ...@@ -82,6 +82,7 @@ config MACH_MX31MOBOARD
config MACH_MX31LILLY config MACH_MX31LILLY
bool "Support MX31 LILLY-1131 platforms (INCO startec)" bool "Support MX31 LILLY-1131 platforms (INCO startec)"
select ARCH_MX31 select ARCH_MX31
select MXC_ULPI if USB_ULPI
help help
Include support for mx31 based LILLY1131 modules. This includes Include support for mx31 based LILLY1131 modules. This includes
specific configurations for the board and its peripherals. specific configurations for the board and its peripherals.
......
...@@ -582,12 +582,50 @@ static struct resource imx_wdt_resources[] = { ...@@ -582,12 +582,50 @@ static struct resource imx_wdt_resources[] = {
}; };
struct platform_device imx_wdt_device0 = { struct platform_device imx_wdt_device0 = {
.name = "imx-wdt", .name = "imx2-wdt",
.id = 0, .id = 0,
.num_resources = ARRAY_SIZE(imx_wdt_resources), .num_resources = ARRAY_SIZE(imx_wdt_resources),
.resource = 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) static int __init mx3_devices_init(void)
{ {
if (cpu_is_mx31()) { if (cpu_is_mx31()) {
......
...@@ -27,3 +27,5 @@ extern struct platform_device imx_ssi_device0; ...@@ -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_ssi_device1; extern struct platform_device imx_ssi_device1;
extern struct platform_device imx_wdt_device0; extern struct platform_device imx_wdt_device0;
extern struct platform_device imx_rtc_device0;
extern struct platform_device imx_kpp_device;
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <linux/delay.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h> #include <linux/clk.h>
...@@ -26,6 +27,8 @@ ...@@ -26,6 +27,8 @@
#include <linux/mfd/mc13783.h> #include <linux/mfd/mc13783.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/regulator/machine.h> #include <linux/regulator/machine.h>
#include <linux/fsl_devices.h>
#include <linux/input/matrix_keypad.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
...@@ -65,6 +68,50 @@ static int mx31_3ds_pins[] = { ...@@ -65,6 +68,50 @@ static int mx31_3ds_pins[] = {
MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */ MX31_PIN_CSPI2_SS2__SS2, /*CS for MC13783 */
/* MC13783 IRQ */ /* MC13783 IRQ */
IOMUX_MODE(MX31_PIN_GPIO1_3, IOMUX_CONFIG_GPIO), 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 */ /* Regulators */
...@@ -126,6 +173,41 @@ static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = { ...@@ -126,6 +173,41 @@ static struct mxc_nand_platform_data imx31_3ds_nand_flash_pdata = {
#endif #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 = { static struct imxuart_platform_data uart_pdata = {
.flags = IMXUART_HAVE_RTSCTS, .flags = IMXUART_HAVE_RTSCTS,
}; };
...@@ -315,6 +397,11 @@ static void __init mxc_board_init(void) ...@@ -315,6 +397,11 @@ static void __init mxc_board_init(void)
spi_register_board_info(mx31_3ds_spi_devs, spi_register_board_info(mx31_3ds_spi_devs,
ARRAY_SIZE(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()) if (!mx31_3ds_init_expio())
platform_device_register(&smsc911x_device); platform_device_register(&smsc911x_device);
} }
......
...@@ -27,12 +27,15 @@ ...@@ -27,12 +27,15 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/gpio.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/smsc911x.h> #include <linux/smsc911x.h>
#include <linux/mtd/physmap.h> #include <linux/mtd/physmap.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/mfd/mc13783.h> #include <linux/mfd/mc13783.h>
#include <linux/usb/otg.h>
#include <linux/usb/ulpi.h>
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/mach/arch.h> #include <asm/mach/arch.h>
...@@ -44,6 +47,8 @@ ...@@ -44,6 +47,8 @@
#include <mach/iomux-mx3.h> #include <mach/iomux-mx3.h>
#include <mach/board-mx31lilly.h> #include <mach/board-mx31lilly.h>
#include <mach/spi.h> #include <mach/spi.h>
#include <mach/mxc_ehci.h>
#include <mach/ulpi.h>
#include "devices.h" #include "devices.h"
...@@ -108,6 +113,137 @@ static struct platform_device physmap_flash_device = { ...@@ -108,6 +113,137 @@ static struct platform_device physmap_flash_device = {
.num_resources = 1, .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 = { static struct platform_device *devices[] __initdata = {
&smsc91x_device, &smsc91x_device,
&physmap_flash_device, &physmap_flash_device,
...@@ -183,6 +319,15 @@ static void __init mx31lilly_board_init(void) ...@@ -183,6 +319,15 @@ static void __init mx31lilly_board_init(void)
spi_register_board_info(&mc13783_dev, 1); spi_register_board_info(&mc13783_dev, 1);
platform_add_devices(devices, ARRAY_SIZE(devices)); 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) static void __init mx31lilly_timer_init(void)
......
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <linux/fsl_devices.h>
#include <linux/gfp.h> #include <linux/gfp.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/init.h> #include <linux/init.h>
...@@ -306,84 +305,56 @@ static struct imxmmc_platform_data sdhc1_pdata = { ...@@ -306,84 +305,56 @@ static struct imxmmc_platform_data sdhc1_pdata = {
* this pin is dedicated for all mx31moboard systems, so we do it here * this pin is dedicated for all mx31moboard systems, so we do it here
*/ */
#define USB_RESET_B IOMUX_TO_GPIO(MX31_PIN_GPIO1_0) #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 | \ #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) #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) #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_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); gpio_request(OTG_EN_B, "usb-udc-en");
mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, USB_PAD_CFG); gpio_direction_output(OTG_EN_B, 0);
mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, USB_PAD_CFG); gpio_request(USBH2_EN_B, "usbh2-en");
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_direction_output(USBH2_EN_B, 0); 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) #if defined(CONFIG_USB_ULPI)
{
gpio_free(USBH2_EN_B);
return 0;
}
static struct mxc_usbh_platform_data usbh2_pdata = { 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, .portsc = MXC_EHCI_MODE_ULPI | MXC_EHCI_UTMI_8BIT,
.flags = MXC_EHCI_POWER_PINS_ENABLED, .flags = MXC_EHCI_POWER_PINS_ENABLED,
}; };
...@@ -508,8 +479,6 @@ static void __init mxc_board_init(void) ...@@ -508,8 +479,6 @@ static void __init mxc_board_init(void)
usb_xcvr_reset(); usb_xcvr_reset();
moboard_usbotg_init();
mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
moboard_usbh2_init(); moboard_usbh2_init();
switch (mx31moboard_baseboard) { switch (mx31moboard_baseboard) {
...@@ -522,7 +491,8 @@ static void __init mxc_board_init(void) ...@@ -522,7 +491,8 @@ static void __init mxc_board_init(void)
mx31moboard_marxbot_init(); mx31moboard_marxbot_init();
break; break;
case MX31SMARTBOT: case MX31SMARTBOT:
mx31moboard_smartbot_init(); case MX31EYEBOT:
mx31moboard_smartbot_init(mx31moboard_baseboard);
break; break;
default: default:
printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n",
......
...@@ -449,6 +449,7 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size) ...@@ -449,6 +449,7 @@ static int __init pcm037_camera_alloc_dma(const size_t buf_size)
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&pcm037_flash, &pcm037_flash,
&pcm037_sram_device, &pcm037_sram_device,
&imx_wdt_device0,
&pcm037_mt9t031, &pcm037_mt9t031,
&pcm037_mt9v022, &pcm037_mt9v022,
}; };
......
...@@ -150,6 +150,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = { ...@@ -150,6 +150,7 @@ static struct i2c_board_info pcm043_i2c_devices[] = {
static struct platform_device *devices[] __initdata = { static struct platform_device *devices[] __initdata = {
&pcm043_flash, &pcm043_flash,
&mxc_fec_device, &mxc_fec_device,
&imx_wdt_device0,
}; };
static struct pad_desc pcm043_pads[] = { static struct pad_desc pcm043_pads[] = {
......
...@@ -206,5 +206,6 @@ void __init mx31lite_db_init(void) ...@@ -206,5 +206,6 @@ void __init mx31lite_db_init(void)
mxc_register_device(&mxc_spi_device0, &spi0_pdata); mxc_register_device(&mxc_spi_device0, &spi0_pdata);
platform_device_register(&litekit_led_device); platform_device_register(&litekit_led_device);
mxc_register_device(&imx_wdt_device0, NULL); mxc_register_device(&imx_wdt_device0, NULL);
mxc_register_device(&imx_rtc_device0, NULL);
} }
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/fsl_devices.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
...@@ -213,6 +214,12 @@ static int __init devboard_usbh1_init(void) ...@@ -213,6 +214,12 @@ static int __init devboard_usbh1_init(void)
return mxc_register_device(&mxc_usbh1, &usbh1_pdata); 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. * system init for baseboard usage. Will be called by mx31moboard init.
*/ */
...@@ -229,5 +236,7 @@ void __init mx31moboard_devboard_init(void) ...@@ -229,5 +236,7 @@ void __init mx31moboard_devboard_init(void)
devboard_init_sel_gpios(); devboard_init_sel_gpios();
mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
devboard_usbh1_init(); devboard_usbh1_init();
} }
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/fsl_devices.h>
#include <linux/usb/otg.h> #include <linux/usb/otg.h>
...@@ -329,6 +330,11 @@ static int __init marxbot_usbh1_init(void) ...@@ -329,6 +330,11 @@ static int __init marxbot_usbh1_init(void)
return mxc_register_device(&mxc_usbh1, &usbh1_pdata); 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. * system init for baseboard usage. Will be called by mx31moboard init.
*/ */
...@@ -356,5 +362,7 @@ void __init mx31moboard_marxbot_init(void) ...@@ -356,5 +362,7 @@ void __init mx31moboard_marxbot_init(void)
gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0)); gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_LCS0));
gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false); gpio_export(IOMUX_TO_GPIO(MX31_PIN_LCS0), false);
mxc_register_device(&mxc_otg_udc_device, &usb_pdata);
marxbot_usbh1_init(); marxbot_usbh1_init();
} }
...@@ -23,11 +23,18 @@ ...@@ -23,11 +23,18 @@
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/types.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/common.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/imx-uart.h> #include <mach/imx-uart.h>
#include <mach/iomux-mx3.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> #include <media/soc_camera.h>
...@@ -116,10 +123,33 @@ static int __init smartbot_cam_init(void) ...@@ -116,10 +123,33 @@ static int __init smartbot_cam_init(void)
return 0; 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 POWER_EN IOMUX_TO_GPIO(MX31_PIN_DTR_DCE1)
#define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1) #define DSPIC_RST_B IOMUX_TO_GPIO(MX31_PIN_DSR_DCE1)
#define TRSLAT_RST_B IOMUX_TO_GPIO(MX31_PIN_RI_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) static void smartbot_resets_init(void)
{ {
...@@ -138,15 +168,15 @@ static void smartbot_resets_init(void) ...@@ -138,15 +168,15 @@ static void smartbot_resets_init(void)
gpio_export(TRSLAT_RST_B, false); gpio_export(TRSLAT_RST_B, false);
} }
if (!gpio_request(SEL3, "sel3")) { if (!gpio_request(TRSLAT_SRC_CHOICE, "translator-src-choice")) {
gpio_direction_input(SEL3); gpio_direction_output(TRSLAT_SRC_CHOICE, 0);
gpio_export(SEL3, true); gpio_export(TRSLAT_SRC_CHOICE, false);
} }
} }
/* /*
* system init for baseboard usage. Will be called by mx31moboard init. * 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"); printk(KERN_INFO "Initializing mx31smartbot peripherals\n");
...@@ -155,6 +185,19 @@ void __init mx31moboard_smartbot_init(void) ...@@ -155,6 +185,19 @@ void __init mx31moboard_smartbot_init(void)
mxc_register_device(&mxc_uart_device1, &uart_pdata); 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_resets_init();
smartbot_cam_init(); smartbot_cam_init();
......
...@@ -12,11 +12,16 @@ ...@@ -12,11 +12,16 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/platform_device.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/common.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/imx-uart.h> #include <mach/imx-uart.h>
#include <mach/iomux-mx51.h> #include <mach/iomux-mx51.h>
#include <mach/mxc_ehci.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/setup.h> #include <asm/setup.h>
...@@ -26,6 +31,18 @@ ...@@ -26,6 +31,18 @@
#include "devices.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 = { static struct platform_device *devices[] __initdata = {
&mxc_fec_device, &mxc_fec_device,
}; };
...@@ -46,6 +63,22 @@ static struct pad_desc mx51babbage_pads[] = { ...@@ -46,6 +63,22 @@ static struct pad_desc mx51babbage_pads[] = {
MX51_PAD_EIM_D26__UART3_TXD, MX51_PAD_EIM_D26__UART3_TXD,
MX51_PAD_EIM_D27__UART3_RTS, MX51_PAD_EIM_D27__UART3_RTS,
MX51_PAD_EIM_D24__UART3_CTS, 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 */ /* Serial ports */
...@@ -66,15 +99,149 @@ static inline void mxc_init_imx_uart(void) ...@@ -66,15 +99,149 @@ static inline void mxc_init_imx_uart(void)
} }
#endif /* SERIAL_IMX */ #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. * Board specific initialization.
*/ */
static void __init mxc_board_init(void) 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, mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
ARRAY_SIZE(mx51babbage_pads)); ARRAY_SIZE(mx51babbage_pads));
mxc_init_imx_uart(); mxc_init_imx_uart();
platform_add_devices(devices, ARRAY_SIZE(devices)); 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) static void __init mx51_babbage_timer_init(void)
......
...@@ -37,6 +37,7 @@ static struct clk lp_apm_clk; ...@@ -37,6 +37,7 @@ static struct clk lp_apm_clk;
static struct clk periph_apm_clk; static struct clk periph_apm_clk;
static struct clk ahb_clk; static struct clk ahb_clk;
static struct clk ipg_clk; static struct clk ipg_clk;
static struct clk usboh3_clk;
#define MAX_DPLL_WAIT_TRIES 1000 /* 1000 * udelay(1) = 1ms */ #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) ...@@ -570,6 +571,35 @@ static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
return 0; 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) static unsigned long get_high_reference_clock_rate(struct clk *clk)
{ {
return external_high_reference; return external_high_reference;
...@@ -691,6 +721,12 @@ static struct clk uart_root_clk = { ...@@ -691,6 +721,12 @@ static struct clk uart_root_clk = {
.set_parent = _clk_uart_set_parent, .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 = { static struct clk ahb_max_clk = {
.parent = &ahb_clk, .parent = &ahb_clk,
.enable_reg = MXC_CCM_CCGR0, .enable_reg = MXC_CCM_CCGR0,
...@@ -779,6 +815,12 @@ static struct clk_lookup lookups[] = { ...@@ -779,6 +815,12 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
_REGISTER_CLOCK(NULL, "gpt", gpt_clk) _REGISTER_CLOCK(NULL, "gpt", gpt_clk)
_REGISTER_CLOCK("fec.0", NULL, fec_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) static void clk_tree_init(void)
...@@ -819,6 +861,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc, ...@@ -819,6 +861,9 @@ int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
clk_enable(&cpu_clk); clk_enable(&cpu_clk);
clk_enable(&main_bus_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 */ /* System timer */
mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR), mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
MX51_MXC_INT_GPT); MX51_MXC_INT_GPT);
......
/* /*
* Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com> * 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 * The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License * License. You may obtain a copy of the GNU General Public License
...@@ -10,8 +11,11 @@ ...@@ -10,8 +11,11 @@
*/ */
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/gpio.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/imx-uart.h> #include <mach/imx-uart.h>
#include <mach/irqs.h>
static struct resource uart0[] = { static struct resource uart0[] = {
{ {
...@@ -89,8 +93,109 @@ struct platform_device mxc_fec_device = { ...@@ -89,8 +93,109 @@ struct platform_device mxc_fec_device = {
.resource = mxc_fec_resources, .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) int __init mxc_register_gpios(void)
{ {
return 0; return mxc_gpio_init(mxc_gpio_ports, ARRAY_SIZE(mxc_gpio_ports));
} }
...@@ -2,3 +2,7 @@ extern struct platform_device mxc_uart_device0; ...@@ -2,3 +2,7 @@ extern struct platform_device mxc_uart_device0;
extern struct platform_device mxc_uart_device1; extern struct platform_device mxc_uart_device1;
extern struct platform_device mxc_uart_device2; extern struct platform_device mxc_uart_device2;
extern struct platform_device mxc_fec_device; 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;
/* /*
* Copyright (c) 2009 Daniel Mack <daniel@caiaq.de> * 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 * 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 * under the terms of the GNU General Public License as published by the
...@@ -50,7 +51,26 @@ ...@@ -50,7 +51,26 @@
#define MX35_H1_TLL_BIT (1 << 5) #define MX35_H1_TLL_BIT (1 << 5)
#define MX35_H1_USBTE_BIT (1 << 4) #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; unsigned int v;
#ifdef CONFIG_ARCH_MX3 #ifdef CONFIG_ARCH_MX3
...@@ -186,9 +206,85 @@ int mxc_set_usbcontrol(int port, unsigned int flags) ...@@ -186,9 +206,85 @@ int mxc_set_usbcontrol(int port, unsigned int flags)
return 0; return 0;
} }
#endif /* CONFIG_MACH_MX27 */ #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 printk(KERN_WARNING
"%s() unable to setup USBCONTROL for this CPU\n", __func__); "%s() unable to setup USBCONTROL for this CPU\n", __func__);
return -EINVAL; return -EINVAL;
} }
EXPORT_SYMBOL(mxc_set_usbcontrol); EXPORT_SYMBOL(mxc_initialize_usb_hw);
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
* *
* Based on code from Freescale, * 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 * This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License * modify it under the terms of the GNU General Public License
...@@ -38,7 +38,6 @@ static int gpio_table_size; ...@@ -38,7 +38,6 @@ static int gpio_table_size;
#define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10) #define GPIO_ICR2 (cpu_is_mx1_mx2() ? 0x2C : 0x10)
#define GPIO_IMR (cpu_is_mx1_mx2() ? 0x30 : 0x14) #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_ISR (cpu_is_mx1_mx2() ? 0x34 : 0x18)
#define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0) #define GPIO_INT_LOW_LEV (cpu_is_mx1_mx2() ? 0x3 : 0x0)
#define GPIO_INT_HIGH_LEV (cpu_is_mx1_mx2() ? 0x2 : 0x1) #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) ...@@ -289,7 +288,7 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
/* its a serious configuration bug when it fails */ /* its a serious configuration bug when it fails */
BUG_ON( gpiochip_add(&port[i].chip) < 0 ); 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 */ /* setup one handler for each entry */
set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler); set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
set_irq_data(port[i].irq, &port[i]); set_irq_data(port[i].irq, &port[i]);
......
...@@ -26,6 +26,7 @@ enum mx31moboard_boards { ...@@ -26,6 +26,7 @@ enum mx31moboard_boards {
MX31DEVBOARD = 1, MX31DEVBOARD = 1,
MX31MARXBOT = 2, MX31MARXBOT = 2,
MX31SMARTBOT = 3, MX31SMARTBOT = 3,
MX31EYEBOT = 4,
}; };
/* /*
...@@ -35,7 +36,7 @@ enum mx31moboard_boards { ...@@ -35,7 +36,7 @@ enum mx31moboard_boards {
extern void mx31moboard_devboard_init(void); extern void mx31moboard_devboard_init(void);
extern void mx31moboard_marxbot_init(void); extern void mx31moboard_marxbot_init(void);
extern void mx31moboard_smartbot_init(void); extern void mx31moboard_smartbot_init(int board);
#endif #endif
......
...@@ -719,6 +719,23 @@ enum iomux_pins { ...@@ -719,6 +719,23 @@ enum iomux_pins {
#define MX31_PIN_SRXD5__SRXD5 IOMUX_MODE(MX31_PIN_SRXD5, IOMUX_CONFIG_FUNC) #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_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_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, * XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed with cspi2_ss0,
......
/* /*
* Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com> * 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 * The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License * License. You may obtain a copy of the GNU General Public License
...@@ -37,6 +38,11 @@ typedef enum iomux_config { ...@@ -37,6 +38,11 @@ typedef enum iomux_config {
PAD_CTL_SRE_FAST) PAD_CTL_SRE_FAST)
#define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \ #define MX51_UART3_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
PAD_CTL_SRE_FAST) 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> * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
...@@ -57,6 +63,7 @@ typedef enum iomux_config { ...@@ -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_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_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_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_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) #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 { ...@@ -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_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_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_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_USBH1_CLK__USBH1_CLK IOMUX_PAD(0x678, 0x278, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_USBH1_PAD_CTRL)
#define MX51_PAD_GPIO_1_26__USBH1_DIR IOMUX_PAD(0x67C, 0x27C, 2, 0x0, 0, NO_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_GPIO_1_27__USBH1_STP IOMUX_PAD(0x680, 0x280, 2, 0x0, 0, NO_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_GPIO_1_28__USBH1_NXT IOMUX_PAD(0x684, 0x284, 2, 0x0, 0, NO_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_GPIO_1_11__USBH1_DATA0 IOMUX_PAD(0x688, 0x288, 2, 0x0, 0, NO_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_GPIO_1_12__USBH1_DATA1 IOMUX_PAD(0x68C, 0x28C, 2, 0x0, 0, NO_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_GPIO_1_13__USBH1_DATA2 IOMUX_PAD(0x690, 0x290, 2, 0x0, 0, NO_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_GPIO_1_14__USBH1_DATA3 IOMUX_PAD(0x694, 0x294, 2, 0x0, 0, NO_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_GPIO_1_15__USBH1_DATA4 IOMUX_PAD(0x698, 0x298, 2, 0x0, 0, NO_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_GPIO_1_16__USBH1_DATA5 IOMUX_PAD(0x69C, 0x29C, 2, 0x0, 0, NO_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_GPIO_1_17__USBH1_DATA6 IOMUX_PAD(0x6A0, 0x2A0, 2, 0x0, 0, NO_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_GPIO_1_18__USBH1_DATA7 IOMUX_PAD(0x6A4, 0x2A4, 2, 0x0, 0, NO_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_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_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) #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 { ...@@ -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_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_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_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, \ #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)) (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) #define MX51_PAD_GPIO_1_9__GPIO1_9 IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
......
...@@ -25,6 +25,18 @@ ...@@ -25,6 +25,18 @@
#define MXC_EHCI_INTERNAL_PHY (1 << 7) #define MXC_EHCI_INTERNAL_PHY (1 << 7)
#define MXC_EHCI_IPPUE_DOWN (1 << 8) #define MXC_EHCI_IPPUE_DOWN (1 << 8)
#define MXC_EHCI_IPPUE_UP (1 << 9) #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 { struct mxc_usbh_platform_data {
int (*init)(struct platform_device *pdev); int (*init)(struct platform_device *pdev);
...@@ -35,7 +47,7 @@ struct mxc_usbh_platform_data { ...@@ -35,7 +47,7 @@ struct mxc_usbh_platform_data {
struct otg_transceiver *otg; 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 */ #endif /* __INCLUDE_ASM_ARCH_MXC_EHCI_H */
...@@ -54,14 +54,14 @@ ...@@ -54,14 +54,14 @@
#define MX2_TSTAT_COMP (1 << 0) #define MX2_TSTAT_COMP (1 << 0)
/* MX31, MX35, MX25, MXC91231, MX5 */ /* MX31, MX35, MX25, MXC91231, MX5 */
#define MX3_TCTL_WAITEN (1 << 3) /* Wait enable mode */ #define V2_TCTL_WAITEN (1 << 3) /* Wait enable mode */
#define MX3_TCTL_CLK_IPG (1 << 6) #define V2_TCTL_CLK_IPG (1 << 6)
#define MX3_TCTL_FRR (1 << 9) #define V2_TCTL_FRR (1 << 9)
#define MX3_IR 0x0c #define V2_IR 0x0c
#define MX3_TSTAT 0x08 #define V2_TSTAT 0x08
#define MX3_TSTAT_OF1 (1 << 0) #define V2_TSTAT_OF1 (1 << 0)
#define MX3_TCN 0x24 #define V2_TCN 0x24
#define MX3_TCMP 0x10 #define V2_TCMP 0x10
#define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27()) #define timer_is_v1() (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
#define timer_is_v2() (!timer_is_v1()) #define timer_is_v2() (!timer_is_v1())
...@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void) ...@@ -76,7 +76,7 @@ static inline void gpt_irq_disable(void)
unsigned int tmp; unsigned int tmp;
if (timer_is_v2()) if (timer_is_v2())
__raw_writel(0, timer_base + MX3_IR); __raw_writel(0, timer_base + V2_IR);
else { else {
tmp = __raw_readl(timer_base + MXC_TCTL); tmp = __raw_readl(timer_base + MXC_TCTL);
__raw_writel(tmp & ~MX1_2_TCTL_IRQEN, 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) ...@@ -86,7 +86,7 @@ static inline void gpt_irq_disable(void)
static inline void gpt_irq_enable(void) static inline void gpt_irq_enable(void)
{ {
if (timer_is_v2()) if (timer_is_v2())
__raw_writel(1<<0, timer_base + MX3_IR); __raw_writel(1<<0, timer_base + V2_IR);
else { else {
__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN, __raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
timer_base + MXC_TCTL); timer_base + MXC_TCTL);
...@@ -102,7 +102,7 @@ static void gpt_irq_acknowledge(void) ...@@ -102,7 +102,7 @@ static void gpt_irq_acknowledge(void)
__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, __raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP,
timer_base + MX1_2_TSTAT); timer_base + MX1_2_TSTAT);
} else if (timer_is_v2()) } 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) static cycle_t mx1_2_get_cycles(struct clocksource *cs)
...@@ -110,9 +110,9 @@ 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); 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 = { static struct clocksource clocksource_mxc = {
...@@ -129,7 +129,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk) ...@@ -129,7 +129,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
unsigned int c = clk_get_rate(timer_clk); unsigned int c = clk_get_rate(timer_clk);
if (timer_is_v2()) if (timer_is_v2())
clocksource_mxc.read = mx3_get_cycles; clocksource_mxc.read = v2_get_cycles;
clocksource_mxc.mult = clocksource_hz2mult(c, clocksource_mxc.mult = clocksource_hz2mult(c,
clocksource_mxc.shift); clocksource_mxc.shift);
...@@ -153,16 +153,16 @@ static int mx1_2_set_next_event(unsigned long evt, ...@@ -153,16 +153,16 @@ static int mx1_2_set_next_event(unsigned long evt,
-ETIME : 0; -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) struct clock_event_device *unused)
{ {
unsigned long tcmp; 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; -ETIME : 0;
} }
...@@ -192,8 +192,8 @@ static void mxc_set_mode(enum clock_event_mode mode, ...@@ -192,8 +192,8 @@ static void mxc_set_mode(enum clock_event_mode mode,
if (mode != clockevent_mode) { if (mode != clockevent_mode) {
/* Set event time into far-far future */ /* Set event time into far-far future */
if (timer_is_v2()) if (timer_is_v2())
__raw_writel(__raw_readl(timer_base + MX3_TCN) - 3, __raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
timer_base + MX3_TCMP); timer_base + V2_TCMP);
else else
__raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3, __raw_writel(__raw_readl(timer_base + MX1_2_TCN) - 3,
timer_base + MX1_2_TCMP); timer_base + MX1_2_TCMP);
...@@ -245,7 +245,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id) ...@@ -245,7 +245,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
uint32_t tstat; uint32_t tstat;
if (timer_is_v2()) if (timer_is_v2())
tstat = __raw_readl(timer_base + MX3_TSTAT); tstat = __raw_readl(timer_base + V2_TSTAT);
else else
tstat = __raw_readl(timer_base + MX1_2_TSTAT); tstat = __raw_readl(timer_base + MX1_2_TSTAT);
...@@ -276,7 +276,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk) ...@@ -276,7 +276,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
unsigned int c = clk_get_rate(timer_clk); unsigned int c = clk_get_rate(timer_clk);
if (timer_is_v2()) 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.mult = div_sc(c, NSEC_PER_SEC,
clockevent_mxc.shift); clockevent_mxc.shift);
...@@ -308,7 +308,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq) ...@@ -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 */ __raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
if (timer_is_v2()) 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 else
tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN; tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
......
/* /*
* 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 * The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License * License. You may obtain a copy of the GNU General Public License
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <mach/hardware.h> #include <mach/hardware.h>
#include <mach/common.h>
/* /*
***************************************** *****************************************
...@@ -144,6 +145,7 @@ void __init tzic_init_irq(void __iomem *irqbase) ...@@ -144,6 +145,7 @@ void __init tzic_init_irq(void __iomem *irqbase)
set_irq_handler(i, handle_level_irq); set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID); set_irq_flags(i, IRQF_VALID);
} }
mxc_register_gpios();
pr_info("TrustZone Interrupt Controller (TZIC) initialized\n"); pr_info("TrustZone Interrupt Controller (TZIC) initialized\n");
} }
......
...@@ -295,6 +295,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, ...@@ -295,6 +295,12 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr,
card->type = MMC_TYPE_SDIO; 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. * For native busses: set card RCA and quit open drain mode.
*/ */
......
...@@ -119,6 +119,7 @@ struct mxcmci_host { ...@@ -119,6 +119,7 @@ struct mxcmci_host {
int detect_irq; int detect_irq;
int dma; int dma;
int do_dma; int do_dma;
int use_sdio;
unsigned int power_mode; unsigned int power_mode;
struct imxmmc_platform_data *pdata; struct imxmmc_platform_data *pdata;
...@@ -138,6 +139,7 @@ struct mxcmci_host { ...@@ -138,6 +139,7 @@ struct mxcmci_host {
int clock; int clock;
struct work_struct datawork; struct work_struct datawork;
spinlock_t lock;
}; };
static void mxcmci_set_clk_rate(struct mxcmci_host *host, unsigned int clk_ios); 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) ...@@ -151,6 +153,8 @@ static void mxcmci_softreset(struct mxcmci_host *host)
{ {
int i; int i;
dev_dbg(mmc_dev(host->mmc), "mxcmci_softreset\n");
/* reset sequence */ /* reset sequence */
writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK); writew(STR_STP_CLK_RESET, host->base + MMC_REG_STR_STP_CLK);
writew(STR_STP_CLK_RESET | STR_STP_CLK_START_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) ...@@ -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, static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
unsigned int cmdat) unsigned int cmdat)
{ {
u32 int_cntr;
unsigned long flags;
WARN_ON(host->cmd != NULL); WARN_ON(host->cmd != NULL);
host->cmd = cmd; host->cmd = cmd;
...@@ -247,12 +254,16 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd, ...@@ -247,12 +254,16 @@ static int mxcmci_start_cmd(struct mxcmci_host *host, struct mmc_command *cmd,
return -EINVAL; return -EINVAL;
} }
int_cntr = INT_END_CMD_RES_EN;
if (mxcmci_use_dma(host)) if (mxcmci_use_dma(host))
writel(INT_READ_OP_EN | INT_WRITE_OP_DONE_EN | int_cntr |= INT_READ_OP_EN | INT_WRITE_OP_DONE_EN;
INT_END_CMD_RES_EN,
host->base + MMC_REG_INT_CNTR); spin_lock_irqsave(&host->lock, flags);
else if (host->use_sdio)
writel(INT_END_CMD_RES_EN, host->base + MMC_REG_INT_CNTR); 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); writew(cmd->opcode, host->base + MMC_REG_CMD);
writel(cmd->arg, host->base + MMC_REG_ARG); 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, ...@@ -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, static void mxcmci_finish_request(struct mxcmci_host *host,
struct mmc_request *req) 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->req = NULL;
host->cmd = NULL; host->cmd = NULL;
...@@ -290,16 +308,25 @@ static int mxcmci_finish_data(struct mxcmci_host *host, unsigned int stat) ...@@ -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", dev_dbg(mmc_dev(host->mmc), "request failed. status: 0x%08x\n",
stat); stat);
if (stat & STATUS_CRC_READ_ERR) { if (stat & STATUS_CRC_READ_ERR) {
dev_err(mmc_dev(host->mmc), "%s: -EILSEQ\n", __func__);
data->error = -EILSEQ; data->error = -EILSEQ;
} else if (stat & STATUS_CRC_WRITE_ERR) { } else if (stat & STATUS_CRC_WRITE_ERR) {
u32 err_code = (stat >> 9) & 0x3; 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; data->error = -ETIMEDOUT;
else } else {
dev_err(mmc_dev(host->mmc),
"%s: -EILSEQ\n", __func__);
data->error = -EILSEQ; data->error = -EILSEQ;
}
} else if (stat & STATUS_TIME_OUT_READ) { } else if (stat & STATUS_TIME_OUT_READ) {
dev_err(mmc_dev(host->mmc),
"%s: read -ETIMEDOUT\n", __func__);
data->error = -ETIMEDOUT; data->error = -ETIMEDOUT;
} else { } else {
dev_err(mmc_dev(host->mmc), "%s: -EIO\n", __func__);
data->error = -EIO; data->error = -EIO;
} }
} else { } else {
...@@ -433,8 +460,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host) ...@@ -433,8 +460,6 @@ static int mxcmci_transfer_data(struct mxcmci_host *host)
struct scatterlist *sg; struct scatterlist *sg;
int stat, i; int stat, i;
host->datasize = 0;
host->data = data; host->data = data;
host->datasize = 0; host->datasize = 0;
...@@ -464,6 +489,9 @@ static void mxcmci_datawork(struct work_struct *work) ...@@ -464,6 +489,9 @@ static void mxcmci_datawork(struct work_struct *work)
struct mxcmci_host *host = container_of(work, struct mxcmci_host, struct mxcmci_host *host = container_of(work, struct mxcmci_host,
datawork); datawork);
int datastat = mxcmci_transfer_data(host); 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); mxcmci_finish_data(host, datastat);
if (host->req->stop) { if (host->req->stop) {
...@@ -523,15 +551,35 @@ static void mxcmci_cmd_done(struct mxcmci_host *host, unsigned int stat) ...@@ -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) static irqreturn_t mxcmci_irq(int irq, void *devid)
{ {
struct mxcmci_host *host = devid; struct mxcmci_host *host = devid;
unsigned long flags;
bool sdio_irq;
u32 stat; u32 stat;
stat = readl(host->base + MMC_REG_STATUS); 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); 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) if (stat & STATUS_END_CMD_RESP)
mxcmci_cmd_done(host, stat); mxcmci_cmd_done(host, stat);
#ifdef HAS_DMA #ifdef HAS_DMA
if (mxcmci_use_dma(host) && if (mxcmci_use_dma(host) &&
(stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE))) (stat & (STATUS_DATA_TRANS_DONE | STATUS_WRITE_OP_DONE)))
...@@ -668,11 +716,46 @@ static int mxcmci_get_ro(struct mmc_host *mmc) ...@@ -668,11 +716,46 @@ static int mxcmci_get_ro(struct mmc_host *mmc)
return -ENOSYS; 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 = { static const struct mmc_host_ops mxcmci_ops = {
.request = mxcmci_request, .request = mxcmci_request,
.set_ios = mxcmci_set_ios, .set_ios = mxcmci_set_ios,
.get_ro = mxcmci_get_ro, .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) static int mxcmci_probe(struct platform_device *pdev)
...@@ -700,7 +783,7 @@ 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->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 core transfer sizes tunable parameters */
mmc->max_hw_segs = 64; mmc->max_hw_segs = 64;
...@@ -719,6 +802,7 @@ static int mxcmci_probe(struct platform_device *pdev) ...@@ -719,6 +802,7 @@ static int mxcmci_probe(struct platform_device *pdev)
host->mmc = mmc; host->mmc = mmc;
host->pdata = pdev->dev.platform_data; host->pdata = pdev->dev.platform_data;
spin_lock_init(&host->lock);
if (host->pdata && host->pdata->ocr_avail) if (host->pdata && host->pdata->ocr_avail)
mmc->ocr_avail = host->pdata->ocr_avail; mmc->ocr_avail = host->pdata->ocr_avail;
......
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
#define DRIVER_NAME "mxc_nand" #define DRIVER_NAME "mxc_nand"
#define nfc_is_v21() (cpu_is_mx25() || cpu_is_mx35()) #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 */ /* Addresses for NFC registers */
#define NFC_BUF_SIZE 0xE00 #define NFC_BUF_SIZE 0xE00
...@@ -168,11 +168,7 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) ...@@ -168,11 +168,7 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id)
{ {
struct mxc_nand_host *host = dev_id; struct mxc_nand_host *host = dev_id;
uint16_t tmp; disable_irq_nosync(irq);
tmp = readw(host->regs + NFC_CONFIG1);
tmp |= NFC_INT_MSK; /* Disable interrupt */
writew(tmp, host->regs + NFC_CONFIG1);
wake_up(&host->irq_waitq); wake_up(&host->irq_waitq);
...@@ -184,15 +180,13 @@ static irqreturn_t mxc_nfc_irq(int irq, void *dev_id) ...@@ -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) static void wait_op_done(struct mxc_nand_host *host, int useirq)
{ {
uint32_t tmp; uint16_t tmp;
int max_retries = 2000; int max_retries = 8000;
if (useirq) { if (useirq) {
if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) { if ((readw(host->regs + NFC_CONFIG2) & NFC_INT) == 0) {
tmp = readw(host->regs + NFC_CONFIG1); enable_irq(host->irq);
tmp &= ~NFC_INT_MSK; /* Enable interrupt */
writew(tmp, host->regs + NFC_CONFIG1);
wait_event(host->irq_waitq, wait_event(host->irq_waitq,
readw(host->regs + NFC_CONFIG2) & NFC_INT); 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) ...@@ -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(cmd, host->regs + NFC_FLASH_CMD);
writew(NFC_CMD, host->regs + NFC_CONFIG2); writew(NFC_CMD, host->regs + NFC_CONFIG2);
/* Wait for operation to complete */ if (cpu_is_mx21() && (cmd == NAND_CMD_RESET)) {
wait_op_done(host, useirq); 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 /* 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) ...@@ -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 /* Used by the upper layer to write command to NAND Flash for
* different operations to be carried out on NAND Flash */ * different operations to be carried out on NAND Flash */
static void mxc_nand_command(struct mtd_info *mtd, unsigned command, 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, ...@@ -559,6 +603,10 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
/* Command pre-processing step */ /* Command pre-processing step */
switch (command) { switch (command) {
case NAND_CMD_RESET:
send_cmd(host, command, false);
preset(mtd);
break;
case NAND_CMD_STATUS: case NAND_CMD_STATUS:
host->buf_start = 0; host->buf_start = 0;
...@@ -679,7 +727,6 @@ static int __init mxcnd_probe(struct platform_device *pdev) ...@@ -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_platform_data *pdata = pdev->dev.platform_data;
struct mxc_nand_host *host; struct mxc_nand_host *host;
struct resource *res; struct resource *res;
uint16_t tmp;
int err = 0, nr_parts = 0; int err = 0, nr_parts = 0;
struct nand_ecclayout *oob_smallpage, *oob_largepage; struct nand_ecclayout *oob_smallpage, *oob_largepage;
...@@ -743,51 +790,17 @@ static int __init mxcnd_probe(struct platform_device *pdev) ...@@ -743,51 +790,17 @@ static int __init mxcnd_probe(struct platform_device *pdev)
host->spare_len = 64; host->spare_len = 64;
oob_smallpage = &nandv2_hw_eccoob_smallpage; oob_smallpage = &nandv2_hw_eccoob_smallpage;
oob_largepage = &nandv2_hw_eccoob_largepage; oob_largepage = &nandv2_hw_eccoob_largepage;
this->ecc.bytes = 9;
} else if (nfc_is_v1()) { } else if (nfc_is_v1()) {
host->regs = host->base; host->regs = host->base;
host->spare0 = host->base + 0x800; host->spare0 = host->base + 0x800;
host->spare_len = 16; host->spare_len = 16;
oob_smallpage = &nandv1_hw_eccoob_smallpage; oob_smallpage = &nandv1_hw_eccoob_smallpage;
oob_largepage = &nandv1_hw_eccoob_largepage; 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; this->ecc.bytes = 3;
} else } else
BUG(); BUG();
/* Unlock Block Command for given address range */
writew(0x4, host->regs + NFC_WRPROT);
this->ecc.size = 512; this->ecc.size = 512;
this->ecc.layout = oob_smallpage; this->ecc.layout = oob_smallpage;
...@@ -796,14 +809,8 @@ static int __init mxcnd_probe(struct platform_device *pdev) ...@@ -796,14 +809,8 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->ecc.hwctl = mxc_nand_enable_hwecc; this->ecc.hwctl = mxc_nand_enable_hwecc;
this->ecc.correct = mxc_nand_correct_data; this->ecc.correct = mxc_nand_correct_data;
this->ecc.mode = NAND_ECC_HW; this->ecc.mode = NAND_ECC_HW;
tmp = readw(host->regs + NFC_CONFIG1);
tmp |= NFC_ECC_EN;
writew(tmp, host->regs + NFC_CONFIG1);
} else { } else {
this->ecc.mode = NAND_ECC_SOFT; 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 */ /* NAND bus width determines access funtions used by upper layer */
...@@ -817,6 +824,14 @@ static int __init mxcnd_probe(struct platform_device *pdev) ...@@ -817,6 +824,14 @@ static int __init mxcnd_probe(struct platform_device *pdev)
this->options |= NAND_USE_FLASH_BBT; 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 */ /* first scan to find the device and get the page size */
if (nand_scan_ident(mtd, 1)) { if (nand_scan_ident(mtd, 1)) {
err = -ENXIO; err = -ENXIO;
......
...@@ -199,8 +199,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev) ...@@ -199,8 +199,8 @@ static int ehci_mxc_drv_probe(struct platform_device *pdev)
writel(pdata->portsc, hcd->regs + PORTSC_OFFSET); writel(pdata->portsc, hcd->regs + PORTSC_OFFSET);
mdelay(10); mdelay(10);
/* setup USBCONTROL. */ /* setup specific usb hw */
ret = mxc_set_usbcontrol(pdev->id, pdata->flags); ret = mxc_initialize_usb_hw(pdev->id, pdata->flags);
if (ret < 0) if (ret < 0)
goto err_init; goto err_init;
......
...@@ -108,6 +108,9 @@ struct mmc_host_ops { ...@@ -108,6 +108,9 @@ struct mmc_host_ops {
int (*get_cd)(struct mmc_host *host); int (*get_cd)(struct mmc_host *host);
void (*enable_sdio_irq)(struct mmc_host *host, int enable); 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; struct mmc_card;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment