From ded518c60967793706f19b2c63dc43deac29ef6f Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 24 Mar 2010 14:32:17 +0300 Subject: imx3: Add rtc platform device support This patch adds support for build-in RTC device found on Freescale imx31 and imx35 SoCs. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index f891115..1ffed28 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -588,6 +588,25 @@ struct platform_device imx_wdt_device0 = { .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 int __init mx3_devices_init(void) { if (cpu_is_mx31()) { diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index 4f77eb5..b1687ad7 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -27,3 +27,4 @@ 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; -- cgit v0.10.2 From 8bcc84ad61a601f4d8fc960d5e6495d6fc88177b Mon Sep 17 00:00:00 2001 From: Vladimir Zapolskiy Date: Wed, 24 Mar 2010 14:32:18 +0300 Subject: imx31: add rtc device on litekit board. This patch adds support for SoC build-in RTC device on litekit board. Signed-off-by: Vladimir Zapolskiy Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31lite-db.c b/arch/arm/mach-mx3/mx31lite-db.c index 093c595..5f05bfb 100644 --- a/arch/arm/mach-mx3/mx31lite-db.c +++ b/arch/arm/mach-mx3/mx31lite-db.c @@ -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); } -- cgit v0.10.2 From 7422f27a8ad7f6a7474e324a61e5a7f8be166c25 Mon Sep 17 00:00:00 2001 From: Ivo Clarysse Date: Thu, 8 Apr 2010 16:14:44 +0200 Subject: MXC: mxc_nand: set NFC registers after reset This patch allows the mxc_nand driver to reset the NAND flash controller. NFC registers are (re-)set after completion of the reset, as a reset will have reverted the NFC registers to their default values. Signed-off-by: Ivo Clarysse Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index b2900d8..ed27d38 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -542,6 +542,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; + + /* disable 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 +594,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 +718,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 +781,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 +800,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 +815,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, 0, 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; -- cgit v0.10.2 From 63f4079b6a90e2a8ee64c5900a6d4d0bcb79bc65 Mon Sep 17 00:00:00 2001 From: Ivo Clarysse Date: Thu, 8 Apr 2010 16:16:51 +0200 Subject: MXC: mxc_nand: support i.MX21 On i.MX21 SoCs, if the NFC_CONFIG1:NFC_INT_MASK bit is set, NFC_CONFIG2:NFC_INT always reads out zero, even if an operation is completed. This patch uses enable_irq and disable_irq_nosync instead of NFC_CONFIG1:NFC_INT_MASK to mask NFC interrupts. This allows NFC_CONFIG2:NFC_INT to also be used to detect operation completion on i.MX21. The i.MX21 NFC does not signal reset completion using NFC_CONFIG1:NFC_INT_MASK, so instead reset completion is tested by checking if NFC_CONFIG2 becomes 0. Signed-off-by: Ivo Clarysse Signed-off-by: Sascha Hauer diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index ed27d38..fb03aff 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -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 @@ -548,9 +557,9 @@ static void preset(struct mtd_info *mtd) struct mxc_nand_host *host = nand_chip->priv; uint16_t tmp; - /* disable interrupt, disable spare enable */ + /* enable interrupt, disable spare enable */ tmp = readw(host->regs + NFC_CONFIG1); - tmp |= NFC_INT_MSK; + tmp &= ~NFC_INT_MSK; tmp &= ~NFC_SP_EN; if (nand_chip->ecc.mode == NAND_ECC_HW) { tmp |= NFC_ECC_EN; @@ -819,7 +828,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) host->irq = platform_get_irq(pdev, 0); - err = request_irq(host->irq, mxc_nfc_irq, 0, DRIVER_NAME, host); + err = request_irq(host->irq, mxc_nfc_irq, IRQF_DISABLED, DRIVER_NAME, host); if (err) goto eirq; -- cgit v0.10.2 From 066fb8472036805e31ee002097f619815e25a127 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 13 Apr 2010 20:11:37 +0200 Subject: ARM: mx3/lilly1131: add USB support Signed-off-by: Daniel Mack Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 170f68e..344753f 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -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. diff --git a/arch/arm/mach-mx3/mach-mx31lilly.c b/arch/arm/mach-mx3/mach-mx31lilly.c index 80847b0..d3d5877 100644 --- a/arch/arm/mach-mx3/mach-mx31lilly.c +++ b/arch/arm/mach-mx3/mach-mx31lilly.c @@ -27,12 +27,15 @@ #include #include #include +#include #include #include #include #include #include #include +#include +#include #include #include @@ -44,6 +47,8 @@ #include #include #include +#include +#include #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) -- cgit v0.10.2 From 4725f6f17691f4602e3e31d785da5a461a16ccfe Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:23 +0200 Subject: ARM: MXC: mxcmmc: misc cleanups MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Be more verbose on error messages and add one debug message. Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: Michał Mirosław Signed-off-by: Sascha Hauer diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 2df9041..44a53ee 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -151,6 +151,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, @@ -290,16 +292,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 +444,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; -- cgit v0.10.2 From f441b993101d4ee95222ccbaad1e0dd53ea90b64 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:24 +0200 Subject: ARM: MXC: mxcmmc: Teach the driver SDIO operations MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Successfully tested on MX31 hardware using libertas SDIO peripherals. Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: Michał Mirosław Signed-off-by: Sascha Hauer diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 44a53ee..51e880c 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -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); @@ -226,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; @@ -249,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); @@ -266,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; @@ -532,15 +548,27 @@ 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, 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); + + 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))) @@ -677,11 +705,30 @@ 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 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, }; static int mxcmci_probe(struct platform_device *pdev) @@ -709,7 +756,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; @@ -728,6 +775,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; -- cgit v0.10.2 From 3fcb027d7fd749569665d34a79ce2a8e00bc2ed6 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Thu, 1 Apr 2010 10:03:25 +0200 Subject: ARM: MXC: mxcmmc: work around a bug in the SDHC busy line handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. Another way is playing tricks with the DMA engine, but this isn't mainline yet. So for now, we live with the performance drawback of 1-bit transfers until a nicer solution is found. This patch introduces a new host controller callback 'init_card' which is for now only called from mmc_sdio_init_card(). Signed-off-by: Daniel Mack Cc: Sascha Hauer Cc: Dan Williams Cc: Volker Ernst Cc: Jiri Kosina Cc: Michał Mirosław Signed-off-by: Sascha Hauer diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index 2dd4cfe..b9dee28 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -296,6 +296,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. */ if (!powered_resume && !mmc_host_is_spi(host)) { diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 51e880c..2c53024 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -724,11 +724,27 @@ static void mxcmci_enable_sdio_irq(struct mmc_host *mmc, int enable) 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, .enable_sdio_irq = mxcmci_enable_sdio_irq, + .init_card = mxcmci_init_card, }; static int mxcmci_probe(struct platform_device *pdev) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 43eaf5c..3196c84 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -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; -- cgit v0.10.2 From 38a66f51e71c8d3e24c221614c57b9e8b37a46b3 Mon Sep 17 00:00:00 2001 From: Amit Kucheria Date: Wed, 21 Apr 2010 21:34:36 +0300 Subject: mxc: Change gpt timer code to be more generic by using V2 instead of MX3 Replace mx3_ with v2_ since the register layout is the same for all SoCs using version 2 of the timer (mx25, mx31, mx37 and now mx51) Signed-off-by: Amit Kucheria Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index c1ce51a..714bdef 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -54,14 +54,14 @@ #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); @@ -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; -- cgit v0.10.2 From e24798e637f5d5222f9fd767aefbea15de456e4a Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Thu, 22 Apr 2010 16:28:42 +0300 Subject: mx5: Add registration of GPIOs for MX5 devices Register the gpio irqs on Freescale's MX51 Babbage HW. Signed-off-by: Dinh Nguyen Signed-off-by: Amit Kucheria Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index d6fd396..5070ae1 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -1,5 +1,6 @@ /* * Copyright 2009 Amit Kucheria + * 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 @@ -10,8 +11,10 @@ */ #include +#include #include #include +#include static struct resource uart0[] = { { @@ -89,8 +92,34 @@ struct platform_device mxc_fec_device = { .resource = mxc_fec_resources, }; -/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */ +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)); } diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index 70b2389..71437c6 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -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]); diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index afa6709..9b86d2a 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c @@ -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 #include +#include /* ***************************************** @@ -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"); } -- cgit v0.10.2 From d943f2c82144b0fb8aaebfbc6659c02cc3340527 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Fri, 23 Apr 2010 06:49:43 +0200 Subject: arm/plat-mxc: Fix forgotten renaming in timer.c Commit "mxc: Change gpt timer code to be more generic by using V2 instead of MX3" forgot to replace one occurence causing a build failure. Signed-off-by: Wolfram Sang Cc: Amit Kucheria Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 714bdef..f9a1b05 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -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) -- cgit v0.10.2 From 282f152219020c14064efa78374309e1df6a23a2 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:23 -0500 Subject: mxc: Update GPIO for USB support on Freescale MX51 Babbage HW This patch is part of enabling USB for Freescale MX51 Babbage HW. This patch updates the iomux pins for USB, and gpio line for reset the USB hub on the MX51 Babbage HW. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index b4f975e..80528cc 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -1,5 +1,6 @@ /* * Copyright (C) 2009-2010 Amit Kucheria + * 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___ @@ -208,18 +214,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 +306,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) -- cgit v0.10.2 From c53bdf1c4488ce196e9a0056285e7b4a36f6f76a Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:24 -0500 Subject: mx5: Add USB device definitions for Freescale MX51 Babbage HW This patch is part of enabling USB for Freescale MX51 Babbage HW. This patch adds device structures for USB Host1 and OTG port, and adds clocking information for USB HW. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 8f85f73..dcca330 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -761,6 +761,10 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); +/* USB */ +DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET, + NULL, NULL, &pll3_sw_clk, NULL); + /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -778,6 +782,10 @@ 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) }; static void clk_tree_init(void) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 5070ae1..e6262f3 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -92,6 +93,54 @@ struct platform_device mxc_fec_device = { .resource = mxc_fec_resources, }; +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, + }, +}; + +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 mxc_gpio_port mxc_gpio_ports[] = { { .chip.label = "gpio-0", diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index f339ab8..95c45f9 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -2,3 +2,5 @@ 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; -- cgit v0.10.2 From 231637f5f2c7f3795d1b0c9b59fda27a23ffdc3e Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:25 -0500 Subject: mx5: Enable board specific functions for enabling USB host on Babbage This patch enables USB host functionality for Host1 and OTG port on Freescale MX51 Babbage HW. This patch contains the board specific HW initialization of the USB HW. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Reviewed-by: Daniel Mack Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index ee67a71..99f7ea9 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -12,11 +12,15 @@ #include #include +#include +#include +#include #include #include #include #include +#include #include #include @@ -26,6 +30,17 @@ #include "devices.h" +#define BABBAGE_USB_HUB_RESET (0*32 + 7) /* GPIO_1_7 */ +#define BABBAGE_USBH1_STP (0*32 + 27) /* GPIO_1_27 */ + +/* 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 +61,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 +97,113 @@ 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; + 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); + 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 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), +}; + /* * 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)); + + mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + + 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) -- cgit v0.10.2 From 5a25ad84e01173bb225285eb50f9af48ed1a7598 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:26 -0500 Subject: mxc: Add generic USB HW initialization for MX51 This patch adds USB HW initializiation code to /plat-mxc/ehci.c. -Sets some specific PHY settings Renames mxc_set_usbcontrol to mxc_initialize_usb_hw. Adds new register bit defines for the USB HW on Freescale SoCs. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Reviewed-by: Daniel Mack Signed-off-by: Sascha Hauer diff --git a/arch/arm/plat-mxc/ehci.c b/arch/arm/plat-mxc/ehci.c index cb0b63874..2a864617 100644 --- a/arch/arm/plat-mxc/ehci.c +++ b/arch/arm/plat-mxc/ehci.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2009 Daniel Mack + * 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 @@ -50,7 +51,26 @@ #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); diff --git a/arch/arm/plat-mxc/include/mach/mxc_ehci.h b/arch/arm/plat-mxc/include/mach/mxc_ehci.h index 4b9b836..7fc5f99 100644 --- a/arch/arm/plat-mxc/include/mach/mxc_ehci.h +++ b/arch/arm/plat-mxc/include/mach/mxc_ehci.h @@ -25,6 +25,18 @@ #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 */ diff --git a/drivers/usb/host/ehci-mxc.c b/drivers/usb/host/ehci-mxc.c index ead59f4..544ccfd 100644 --- a/drivers/usb/host/ehci-mxc.c +++ b/drivers/usb/host/ehci-mxc.c @@ -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; -- cgit v0.10.2 From 28a2afe0df1078d479923142a708adfe65fbf8b7 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Fri, 30 Apr 2010 15:48:27 -0500 Subject: mx5: Add USB to Freescale MX51 defconfig Update mx51_defconfig to include USB EHCI by default. This patch applies to 2.6.34-rc6. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/configs/mx51_defconfig b/arch/arm/configs/mx51_defconfig index c88e952..a708fd6 100644 --- a/arch/arm/configs/mx51_defconfig +++ b/arch/arm/configs/mx51_defconfig @@ -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 -- cgit v0.10.2 From 7176441b95b4a04ad7cbac71d0d3614a7634d727 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Wed, 5 May 2010 11:34:21 +0200 Subject: mx31smartbot: change the config of a gpio Since it is finally used on the handbot as a configuration input for the translator. Signed-off-by: Valentin Longchamp Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c index 52a69fc..83d2b9f 100644 --- a/arch/arm/mach-mx3/mx31moboard-smartbot.c +++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c @@ -119,7 +119,7 @@ static int __init smartbot_cam_init(void) #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,9 +138,9 @@ 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); } } /* -- cgit v0.10.2 From c79504e73a0e84c4db7a2315dcdd6987b0c52566 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 10 May 2010 13:45:58 -0500 Subject: mx5: change usb clock source from pll3 to pll2 For power management reasons, pll2 should be used to source the USBOH3 clock for mx51. PLL3 can be completely gated off when USB is not used. This patch applies to 2.6.34-rc7. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index dcca330..566cfda 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -36,6 +36,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 */ @@ -569,6 +570,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; @@ -690,6 +720,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, @@ -761,10 +797,6 @@ DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET, DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET, NULL, NULL, &ipg_clk, NULL); -/* USB */ -DEFINE_CLOCK(usboh3_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG14_OFFSET, - NULL, NULL, &pll3_sw_clk, NULL); - /* FEC */ DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET, NULL, NULL, &ipg_clk, NULL); @@ -826,6 +858,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); -- cgit v0.10.2 From 2ba5a2c0d8e0f62916a885170f28786141f08f76 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 10 May 2010 13:45:59 -0500 Subject: mx5: enable usb gadget for freescale mx51 babbage board This patch enables usb gadget for freescale mx51 babbage hw. By default, the OTG port will be in device mode. To put the OTG port into Host mode, pass "otg_mode=host" in the exec command. This patch applies to 2.6.34-rc7. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index 99f7ea9..dacf506 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -179,12 +180,32 @@ static struct mxc_usbh_platform_data dr_utmi_config = { .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. */ @@ -197,7 +218,12 @@ static void __init mxc_board_init(void) mxc_init_imx_uart(); platform_add_devices(devices, ARRAY_SIZE(devices)); - mxc_register_device(&mxc_usbdr_host_device, &dr_utmi_config); + 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); diff --git a/arch/arm/mach-mx5/clock-mx51.c b/arch/arm/mach-mx5/clock-mx51.c index 566cfda..9b93de3 100644 --- a/arch/arm/mach-mx5/clock-mx51.c +++ b/arch/arm/mach-mx5/clock-mx51.c @@ -818,6 +818,8 @@ static struct clk_lookup lookups[] = { _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) diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index e6262f3..23850e6 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -107,6 +107,18 @@ static struct resource usbotg_resources[] = { }, }; +/* 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, diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index 95c45f9..0494d6b 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -4,3 +4,4 @@ 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; -- cgit v0.10.2 From 25783602050600b294086d6a0be9a0c2cfe8a3e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20R=C3=A9tornaz?= Date: Tue, 11 May 2010 16:57:49 +0200 Subject: mx31moboard: Fix usb PHY reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Setup the pad with correct pull-up/down before doing the reset. Assert the PHY enable signal so the reset is really done. Signed-off-by: Philippe Rétornaz Acked-by: Valentin Longchamp Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index fccb920..5c44489 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c @@ -306,37 +306,51 @@ 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) +#define USBH2_EN_B IOMUX_TO_GPIO(MX31_PIN_SCK6) -static void moboard_usbotg_init(void) +static void usb_xcvr_reset(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); + 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); 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); + + 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 struct fsl_usb2_platform_data usb_pdata = { @@ -346,44 +360,7 @@ static struct fsl_usb2_platform_data usb_pdata = { #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) -{ - int ret; - - mxc_iomux_set_gpr(MUX_PGP_UH2, true); - - 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_direction_output(USBH2_EN_B, 0); - - return 0; -} - -static int moboard_usbh2_hw_exit(struct platform_device *pdev) -{ - gpio_free(USBH2_EN_B); - return 0; -} - 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,7 +485,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(); -- cgit v0.10.2 From 66c202ad9a58905e0e6a0fa3976020a7ab0fa6df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20R=C3=A9tornaz?= Date: Tue, 11 May 2010 16:57:50 +0200 Subject: mx31moboard: Move usb OTG device registration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In preparation for a new robot which needs the OTG port as host. This moves the OTG device registration into board initialisation. Signed-off-by: Philippe Rétornaz Acked-by: Valentin Longchamp Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index 5c44489..4bb011a 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c @@ -18,7 +18,6 @@ #include #include -#include #include #include #include @@ -353,11 +352,6 @@ static void usb_xcvr_reset(void) mdelay(1); } -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 usbh2_pdata = { @@ -485,7 +479,6 @@ static void __init mxc_board_init(void) usb_xcvr_reset(); - mxc_register_device(&mxc_otg_udc_device, &usb_pdata); moboard_usbh2_init(); switch (mx31moboard_baseboard) { diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c index 11b906c..582299c 100644 --- a/arch/arm/mach-mx3/mx31moboard-devboard.c +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -22,6 +22,7 @@ #include #include #include +#include #include @@ -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(); } diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c index ffb105e..4930f8c 100644 --- a/arch/arm/mach-mx3/mx31moboard-marxbot.c +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -25,6 +25,7 @@ #include #include #include +#include #include @@ -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(); } diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c index 83d2b9f..ac1a163 100644 --- a/arch/arm/mach-mx3/mx31moboard-smartbot.c +++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -116,6 +117,11 @@ 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, +}; + #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) @@ -155,6 +161,8 @@ void __init mx31moboard_smartbot_init(void) mxc_register_device(&mxc_uart_device1, &uart_pdata); + mxc_register_device(&mxc_otg_udc_device, &usb_pdata); + smartbot_resets_init(); smartbot_cam_init(); -- cgit v0.10.2 From 3a47b1a4f16285bc1b96941782a896afc4711e97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philippe=20R=C3=A9tornaz?= Date: Tue, 11 May 2010 16:57:51 +0200 Subject: mx31moboard: OTG host support for smartbot board MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Eyebot robot needs the OTG port in host mode on the smartbot. Add a new board definition so we can select the usb host/device mode at boot with the mx31moboard_baseboard boot parameter. Signed-off-by: Philippe Rétornaz Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31moboard.c b/arch/arm/mach-mx3/mach-mx31moboard.c index 4bb011a..33a8d35 100644 --- a/arch/arm/mach-mx3/mach-mx31moboard.c +++ b/arch/arm/mach-mx3/mach-mx31moboard.c @@ -491,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", diff --git a/arch/arm/mach-mx3/mx31moboard-smartbot.c b/arch/arm/mach-mx3/mx31moboard-smartbot.c index ac1a163..293eea6 100644 --- a/arch/arm/mach-mx3/mx31moboard-smartbot.c +++ b/arch/arm/mach-mx3/mx31moboard-smartbot.c @@ -25,10 +25,16 @@ #include #include +#include +#include + #include #include #include #include +#include +#include +#include #include @@ -122,6 +128,24 @@ static struct fsl_usb2_platform_data usb_pdata = { .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) @@ -152,7 +176,7 @@ static void smartbot_resets_init(void) /* * 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"); @@ -161,7 +185,18 @@ void __init mx31moboard_smartbot_init(void) mxc_register_device(&mxc_uart_device1, &uart_pdata); - mxc_register_device(&mxc_otg_udc_device, &usb_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(); diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h index fc5fec9..36ff3ce 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h @@ -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 -- cgit v0.10.2 From a2ef4562c25317f3d0731e79eb432db8ed9eb1ca Mon Sep 17 00:00:00 2001 From: Magnus Lilja Date: Fri, 14 May 2010 17:08:29 +0200 Subject: MXC: Add USB OTG (device) for i.MX31 PDK (3DS) board. Tested on actual hardware using the g_ether and g_serial gadget drivers. Signed-off-by: Magnus Lilja Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index f54af1e..55d6117 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -16,6 +16,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ +#include #include #include #include @@ -26,6 +27,7 @@ #include #include #include +#include #include #include @@ -65,6 +67,21 @@ 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, }; /* Regulators */ @@ -126,6 +143,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 +367,9 @@ static void __init mxc_board_init(void) spi_register_board_info(mx31_3ds_spi_devs, ARRAY_SIZE(mx31_3ds_spi_devs)); + mx31_3ds_usbotg_init(); + mxc_register_device(&mxc_otg_udc_device, &usbotg_pdata); + if (!mx31_3ds_init_expio()) platform_device_register(&smsc911x_device); } -- cgit v0.10.2 From 4a31f2eff3b8fcf009db35f89eb222ed7835b6b9 Mon Sep 17 00:00:00 2001 From: Daniel Mack Date: Tue, 27 Apr 2010 12:24:42 +0200 Subject: ARM: mx3: Fix a race condition in mxcmmc From cefcdab08d1c9636c4a7290bc2bbe937d051bce4 Mon Sep 17 00:00:00 2001 From: Volker Ernst Date: Mon, 26 Apr 2010 22:51:07 +0200 Subject: [PATCH] ARM: mx3: Fix a race condition in mxcmmc This fixes a race condition regarding interrupt bits in the SDHC controller driver code. In case of PIO-transfer it does not clear SDHC-status bit#11/12 in the INT-handler anymore. INT-handler might be called during an ongoing PIO-data-transfer (with some other INT-flag set) and PIO-transfer depends on these bits being set to detect the end of the data-transfer. This also means that at the end of PIO- transfer that PIO-software has to clear these bits itself. However in case of DMA-transfer these bits have to be cleared in the INT-handler, because they are used to generate INTs then. Works solid, no more problems here, can transfer big files. Signed-off-by: Volker Ernst Acked-by: Daniel Mack Cc: Andy Green Signed-off-by: Sascha Hauer diff --git a/drivers/mmc/host/mxcmmc.c b/drivers/mmc/host/mxcmmc.c index 2c53024..ec18e3b 100644 --- a/drivers/mmc/host/mxcmmc.c +++ b/drivers/mmc/host/mxcmmc.c @@ -489,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) { @@ -553,7 +556,8 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) u32 stat; stat = readl(host->base + MMC_REG_STATUS); - writel(stat & ~STATUS_SDIO_INT_ACTIVE, 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); @@ -561,6 +565,13 @@ static irqreturn_t mxcmci_irq(int irq, void *devid) 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); -- cgit v0.10.2 From 6d38c1cf520e9e1d544242e2ae471677d7a78463 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 29 Apr 2010 10:03:18 +0200 Subject: arm/mach-mx2/3: Fix watchdog-devices to match the current driver Signed-off-by: Wolfram Sang Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index b91e412..a9377ce 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -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, diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 1ffed28..81a1dba 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -582,7 +582,7 @@ 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, -- cgit v0.10.2 From 3170ba546f8d4d2c35809f311c67311f896199f5 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 29 Apr 2010 10:03:19 +0200 Subject: arm/mach-mx3: add watchdog device to Phytec-boards Signed-off-by: Wolfram Sang Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-pcm037.c b/arch/arm/mach-mx3/mach-pcm037.c index 2df1ec5..5024284 100644 --- a/arch/arm/mach-mx3/mach-pcm037.c +++ b/arch/arm/mach-mx3/mach-pcm037.c @@ -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, }; diff --git a/arch/arm/mach-mx3/mach-pcm043.c b/arch/arm/mach-mx3/mach-pcm043.c index 1bf1ec2..78d9185 100644 --- a/arch/arm/mach-mx3/mach-pcm043.c +++ b/arch/arm/mach-mx3/mach-pcm043.c @@ -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[] = { -- cgit v0.10.2 From f13899da00e1b815211cf246c7d2704db3c18e37 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Thu, 29 Apr 2010 10:03:20 +0200 Subject: arm/mach-mx2: add watchdog device to Phytec-boards Signed-off-by: Wolfram Sang Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx2/mach-pca100.c b/arch/arm/mach-mx2/mach-pca100.c index 778fff2..a87422e 100644 --- a/arch/arm/mach-mx2/mach-pca100.c +++ b/arch/arm/mach-mx2/mach-pca100.c @@ -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 = { diff --git a/arch/arm/mach-mx2/mach-pcm038.c b/arch/arm/mach-mx2/mach-pcm038.c index 035fbe0..36c8943 100644 --- a/arch/arm/mach-mx2/mach-pcm038.c +++ b/arch/arm/mach-mx2/mach-pcm038.c @@ -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 -- cgit v0.10.2 From 5ab0a2758c887fc3094dac06d1838d8df709a09d Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 17 May 2010 12:33:42 +0200 Subject: arm/mx25: add watchdog device Signed-off-by: Wolfram Sang Tested-by: Juergen Beisert Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c index 3f4b8a0..3a405fa 100644 --- a/arch/arm/mach-mx25/devices.c +++ b/arch/arm/mach-mx25/devices.c @@ -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, +}; diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h index 39560e1..cee12c0 100644 --- a/arch/arm/mach-mx25/devices.h +++ b/arch/arm/mach-mx25/devices.h @@ -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; -- cgit v0.10.2 From 4a870fc898db90033585cef35d89cf931e189fa4 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Mon, 17 May 2010 12:33:43 +0200 Subject: arm/mx51: add watchdog device Signed-off-by: Wolfram Sang Cc: Sascha Hauer Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c index 23850e6..7130449 100644 --- a/arch/arm/mach-mx5/devices.c +++ b/arch/arm/mach-mx5/devices.c @@ -153,6 +153,21 @@ struct platform_device mxc_usbh1_device = { }, }; +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", diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h index 0494d6b..c879ae7 100644 --- a/arch/arm/mach-mx5/devices.h +++ b/arch/arm/mach-mx5/devices.h @@ -5,3 +5,4 @@ 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; -- cgit v0.10.2 From d6b273bfdfd3667387f2516c4a3602b691535ee3 Mon Sep 17 00:00:00 2001 From: Dinh Nguyen Date: Mon, 17 May 2010 10:46:01 -0500 Subject: mx5: bring usb phy out of reset on freescale mx51 babbage hw This patch de-asserts the reset line that is connected to the USB ULPI PHY on USB Host1. This patch should be included with the original USB host enablement set of patches of mx51 babbage hw, but was accidentily left out. Signed-off-by: Dinh Nguyen Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c index dacf506..ed885f9 100644 --- a/arch/arm/mach-mx5/board-mx51_babbage.c +++ b/arch/arm/mach-mx5/board-mx51_babbage.c @@ -33,6 +33,7 @@ #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 @@ -101,6 +102,7 @@ static inline void mxc_init_imx_uart(void) 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 */ @@ -115,6 +117,16 @@ static int gpio_usbh1_active(void) 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; } diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h index 80528cc..ab0f95d 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx51.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h @@ -63,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) -- cgit v0.10.2 From b1e89955be882bab65997c2227872211f805be80 Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Wed, 19 May 2010 11:33:43 +0200 Subject: MX3X: Add Keypad device definition for MX3X arch This patch adds also the pin definition helpers in iomux-mx3.h Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c index 81a1dba..db7acd6 100644 --- a/arch/arm/mach-mx3/devices.c +++ b/arch/arm/mach-mx3/devices.c @@ -607,6 +607,25 @@ struct platform_device imx_rtc_device0 = { .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()) { diff --git a/arch/arm/mach-mx3/devices.h b/arch/arm/mach-mx3/devices.h index b1687ad7..2c3c864 100644 --- a/arch/arm/mach-mx3/devices.h +++ b/arch/arm/mach-mx3/devices.h @@ -28,3 +28,4 @@ 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; diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index e51465d..cbaed29 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -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, -- cgit v0.10.2 From 54c1f6367c2836a85e821a010085ed04ab2235bc Mon Sep 17 00:00:00 2001 From: Alberto Panizzo Date: Wed, 19 May 2010 11:34:43 +0200 Subject: mx31_3ds: Support the keypad situated in the personality board Signed-off-by: Alberto Panizzo Signed-off-by: Sascha Hauer diff --git a/arch/arm/mach-mx3/mach-mx31_3ds.c b/arch/arm/mach-mx3/mach-mx31_3ds.c index 55d6117..58e5729 100644 --- a/arch/arm/mach-mx3/mach-mx31_3ds.c +++ b/arch/arm/mach-mx3/mach-mx31_3ds.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -82,6 +83,35 @@ static int mx31_3ds_pins[] = { 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 */ @@ -367,6 +397,8 @@ 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); -- cgit v0.10.2