Add i.MX25 support
Sascha Hauer [Thu, 4 Jun 2009 09:32:12 +0000 (11:32 +0200)]
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

19 files changed:
arch/arm/Makefile
arch/arm/mach-mx25/Kconfig [new file with mode: 0644]
arch/arm/mach-mx25/Makefile [new file with mode: 0644]
arch/arm/mach-mx25/Makefile.boot [new file with mode: 0644]
arch/arm/mach-mx25/clock.c [new file with mode: 0644]
arch/arm/mach-mx25/devices.c [new file with mode: 0644]
arch/arm/mach-mx25/devices.h [new file with mode: 0644]
arch/arm/mach-mx25/mm.c [new file with mode: 0644]
arch/arm/plat-mxc/Kconfig
arch/arm/plat-mxc/gpio.c
arch/arm/plat-mxc/include/mach/common.h
arch/arm/plat-mxc/include/mach/debug-macro.S
arch/arm/plat-mxc/include/mach/hardware.h
arch/arm/plat-mxc/include/mach/irqs.h
arch/arm/plat-mxc/include/mach/memory.h
arch/arm/plat-mxc/include/mach/mx25.h [new file with mode: 0644]
arch/arm/plat-mxc/include/mach/mxc.h
arch/arm/plat-mxc/include/mach/timex.h
arch/arm/plat-mxc/include/mach/uncompress.h

index c877d6d..95ba3c5 100644 (file)
@@ -135,6 +135,7 @@ machine-$(CONFIG_ARCH_MSM)          := msm
 machine-$(CONFIG_ARCH_MV78XX0)         := mv78xx0
 machine-$(CONFIG_ARCH_MX1)             := mx1
 machine-$(CONFIG_ARCH_MX2)             := mx2
+machine-$(CONFIG_ARCH_MX25)            := mx25
 machine-$(CONFIG_ARCH_MX3)             := mx3
 machine-$(CONFIG_ARCH_NETX)            := netx
 machine-$(CONFIG_ARCH_NS9XXX)          := ns9xxx
diff --git a/arch/arm/mach-mx25/Kconfig b/arch/arm/mach-mx25/Kconfig
new file mode 100644 (file)
index 0000000..14c918b
--- /dev/null
@@ -0,0 +1,5 @@
+if ARCH_MX25
+
+comment "MX25 platforms:"
+
+endif
diff --git a/arch/arm/mach-mx25/Makefile b/arch/arm/mach-mx25/Makefile
new file mode 100644 (file)
index 0000000..5471086
--- /dev/null
@@ -0,0 +1,2 @@
+obj-y                          := mm.o devices.o
+obj-$(CONFIG_ARCH_MX25)                += clock.o
diff --git a/arch/arm/mach-mx25/Makefile.boot b/arch/arm/mach-mx25/Makefile.boot
new file mode 100644 (file)
index 0000000..e1dd366
--- /dev/null
@@ -0,0 +1,3 @@
+   zreladdr-y  := 0x80008000
+params_phys-y  := 0x80000100
+initrd_phys-y  := 0x80800000
diff --git a/arch/arm/mach-mx25/clock.c b/arch/arm/mach-mx25/clock.c
new file mode 100644 (file)
index 0000000..ef26951
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * Copyright (C) 2009 by Sascha Hauer, Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/mx25.h>
+
+#define CRM_BASE       MX25_IO_ADDRESS(MX25_CRM_BASE_ADDR)
+
+#define CCM_MPCTL      0x00
+#define CCM_UPCTL      0x04
+#define CCM_CCTL       0x08
+#define CCM_CGCR0      0x0C
+#define CCM_CGCR1      0x10
+#define CCM_CGCR2      0x14
+#define CCM_PCDR0      0x18
+#define CCM_PCDR1      0x1C
+#define CCM_PCDR2      0x20
+#define CCM_PCDR3      0x24
+#define CCM_RCSR       0x28
+#define CCM_CRDR       0x2C
+#define CCM_DCVR0      0x30
+#define CCM_DCVR1      0x34
+#define CCM_DCVR2      0x38
+#define CCM_DCVR3      0x3c
+#define CCM_LTR0       0x40
+#define CCM_LTR1       0x44
+#define CCM_LTR2       0x48
+#define CCM_LTR3       0x4c
+
+static unsigned long get_rate_mpll(void)
+{
+       ulong mpctl = __raw_readl(CRM_BASE + CCM_MPCTL);
+
+       return mxc_decode_pll(mpctl, 24000000);
+}
+
+static unsigned long get_rate_upll(void)
+{
+       ulong mpctl = __raw_readl(CRM_BASE + CCM_UPCTL);
+
+       return mxc_decode_pll(mpctl, 24000000);
+}
+
+unsigned long get_rate_arm(struct clk *clk)
+{
+       unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+       unsigned long rate = get_rate_mpll();
+
+       if (cctl & (1 << 14))
+               rate = (rate * 3) >> 1;
+
+       return rate / ((cctl >> 30) + 1);
+}
+
+static unsigned long get_rate_ahb(struct clk *clk)
+{
+       unsigned long cctl = readl(CRM_BASE + CCM_CCTL);
+
+       return get_rate_arm(NULL) / (((cctl >> 28) & 0x3) + 1);
+}
+
+static unsigned long get_rate_ipg(struct clk *clk)
+{
+       return get_rate_ahb(NULL) >> 1;
+}
+
+static unsigned long get_rate_per(int per)
+{
+       unsigned long ofs = (per & 0x3) * 8;
+       unsigned long reg = per & ~0x3;
+       unsigned long val = (readl(CRM_BASE + CCM_PCDR0 + reg) >> ofs) & 0x3f;
+       unsigned long fref;
+
+       if (readl(CRM_BASE + 0x64) & (1 << per))
+               fref = get_rate_upll();
+       else
+               fref = get_rate_ipg(NULL);
+
+       return fref / (val + 1);
+}
+
+static unsigned long get_rate_uart(struct clk *clk)
+{
+       return get_rate_per(15);
+}
+
+static unsigned long get_rate_i2c(struct clk *clk)
+{
+       return get_rate_per(6);
+}
+
+static unsigned long get_rate_nfc(struct clk *clk)
+{
+       return get_rate_per(8);
+}
+
+static unsigned long get_rate_otg(struct clk *clk)
+{
+       return 48000000; /* FIXME */
+}
+
+static int clk_cgcr_enable(struct clk *clk)
+{
+       u32 reg;
+
+       reg = __raw_readl(clk->enable_reg);
+       reg |= 1 << clk->enable_shift;
+       __raw_writel(reg, clk->enable_reg);
+
+       return 0;
+}
+
+static void clk_cgcr_disable(struct clk *clk)
+{
+       u32 reg;
+
+       reg = __raw_readl(clk->enable_reg);
+       reg &= ~(1 << clk->enable_shift);
+       __raw_writel(reg, clk->enable_reg);
+}
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr)          \
+       static struct clk name = {                      \
+               .id             = i,                    \
+               .enable_reg     = CRM_BASE + er,        \
+               .enable_shift   = es,                   \
+               .get_rate       = gr,                   \
+               .set_rate       = sr,                   \
+               .enable         = clk_cgcr_enable,      \
+               .disable        = clk_cgcr_disable,     \
+       }
+
+DEFINE_CLOCK(gpt_clk,    0, CCM_CGCR0,  5, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi1_clk,  0, CCM_CGCR1,  5, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi2_clk,  0, CCM_CGCR1,  6, get_rate_ipg, NULL);
+DEFINE_CLOCK(cspi3_clk,  0, CCM_CGCR1,  7, get_rate_ipg, NULL);
+DEFINE_CLOCK(uart1_clk,  0, CCM_CGCR2, 14, get_rate_uart, NULL);
+DEFINE_CLOCK(uart2_clk,  0, CCM_CGCR2, 15, get_rate_uart, NULL);
+DEFINE_CLOCK(uart3_clk,  0, CCM_CGCR2, 16, get_rate_uart, NULL);
+DEFINE_CLOCK(uart4_clk,  0, CCM_CGCR2, 17, get_rate_uart, NULL);
+DEFINE_CLOCK(uart5_clk,  0, CCM_CGCR2, 18, get_rate_uart, NULL);
+DEFINE_CLOCK(nfc_clk,    0, CCM_CGCR0,  8, get_rate_nfc, NULL);
+DEFINE_CLOCK(usbotg_clk, 0, CCM_CGCR0, 28, get_rate_otg, NULL);
+DEFINE_CLOCK(pwm1_clk,  0, CCM_CGCR1, 31, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm2_clk,  0, CCM_CGCR2,  0, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm3_clk,  0, CCM_CGCR2,  1, get_rate_ipg, NULL);
+DEFINE_CLOCK(pwm4_clk,  0, CCM_CGCR2,  2, get_rate_ipg, NULL);
+DEFINE_CLOCK(kpp_clk,   0, CCM_CGCR1, 28, get_rate_ipg, NULL);
+DEFINE_CLOCK(tsc_clk,   0, CCM_CGCR2, 13, get_rate_ipg, NULL);
+DEFINE_CLOCK(i2c_clk,   0, CCM_CGCR0,  6, get_rate_i2c, NULL);
+
+#define _REGISTER_CLOCK(d, n, c)       \
+       {                               \
+               .dev_id = d,            \
+               .con_id = n,            \
+               .clk = &c,              \
+       },
+
+static struct clk_lookup lookups[] = {
+       _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk)
+       _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk)
+       _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk)
+       _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk)
+       _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk)
+       _REGISTER_CLOCK("mxc-ehci.0", "usb", usbotg_clk)
+       _REGISTER_CLOCK("mxc-ehci.1", "usb", usbotg_clk)
+       _REGISTER_CLOCK("mxc-ehci.2", "usb", usbotg_clk)
+       _REGISTER_CLOCK("fsl-usb2-udc", "usb", usbotg_clk)
+       _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk)
+       _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk)
+       _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk)
+       _REGISTER_CLOCK("spi_imx.2", NULL, cspi3_clk)
+       _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm1_clk)
+       _REGISTER_CLOCK("mxc_pwm.1", NULL, pwm2_clk)
+       _REGISTER_CLOCK("mxc_pwm.2", NULL, pwm3_clk)
+       _REGISTER_CLOCK("mxc_pwm.3", NULL, pwm4_clk)
+       _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk)
+       _REGISTER_CLOCK("mx25-adc", NULL, tsc_clk)
+       _REGISTER_CLOCK("imx-i2c.0", NULL, i2c_clk)
+       _REGISTER_CLOCK("imx-i2c.1", NULL, i2c_clk)
+       _REGISTER_CLOCK("imx-i2c.2", NULL, i2c_clk)
+};
+
+int __init mx25_clocks_init(unsigned long fref)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(lookups); i++)
+               clkdev_add(&lookups[i]);
+
+       mxc_timer_init(&gpt_clk, MX25_IO_ADDRESS(MX25_GPT1_BASE_ADDR), 54);
+
+       return 0;
+}
diff --git a/arch/arm/mach-mx25/devices.c b/arch/arm/mach-mx25/devices.c
new file mode 100644 (file)
index 0000000..eb12de1
--- /dev/null
@@ -0,0 +1,402 @@
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <mach/mx25.h>
+#include <mach/irqs.h>
+
+static struct resource uart0[] = {
+       {
+               .start = 0x43f90000,
+               .end = 0x43f93fff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 45,
+               .end = 45,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_uart_device0 = {
+       .name = "imx-uart",
+       .id = 0,
+       .resource = uart0,
+       .num_resources = ARRAY_SIZE(uart0),
+};
+
+static struct resource uart1[] = {
+       {
+               .start = 0x43f94000,
+               .end = 0x43f97fff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 32,
+               .end = 32,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_uart_device1 = {
+       .name = "imx-uart",
+       .id = 1,
+       .resource = uart1,
+       .num_resources = ARRAY_SIZE(uart1),
+};
+
+static struct resource uart2[] = {
+       {
+               .start = 0x5000c000,
+               .end = 0x5000ffff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 18,
+               .end = 18,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_uart_device2 = {
+       .name = "imx-uart",
+       .id = 2,
+       .resource = uart2,
+       .num_resources = ARRAY_SIZE(uart2),
+};
+
+static struct resource uart3[] = {
+       {
+               .start = 0x50008000,
+               .end = 0x5000bfff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 5,
+               .end = 5,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_uart_device3 = {
+       .name = "imx-uart",
+       .id = 3,
+       .resource = uart3,
+       .num_resources = ARRAY_SIZE(uart3),
+};
+
+static struct resource uart4[] = {
+       {
+               .start = 0x5002c000,
+               .end = 0x5002ffff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 40,
+               .end = 40,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_uart_device4 = {
+       .name = "imx-uart",
+       .id = 4,
+       .resource = uart4,
+       .num_resources = ARRAY_SIZE(uart4),
+};
+
+#define MX25_OTG_BASE_ADDR 0x53FF4000
+
+static u64 otg_dmamask = DMA_BIT_MASK(32);
+
+static struct resource mxc_otg_resources[] = {
+       {
+               .start = MX25_OTG_BASE_ADDR,
+               .end = MX25_OTG_BASE_ADDR + 0x1ff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 37,
+               .end = 37,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_otg = {
+       .name = "mxc-ehci",
+       .id = 0,
+       .dev = {
+               .coherent_dma_mask = 0xffffffff,
+               .dma_mask = &otg_dmamask,
+       },
+       .resource = mxc_otg_resources,
+       .num_resources = ARRAY_SIZE(mxc_otg_resources),
+};
+
+/* OTG gadget device */
+struct platform_device otg_udc_device = {
+       .name = "fsl-usb2-udc",
+       .id   = -1,
+       .dev  = {
+               .dma_mask          = &otg_dmamask,
+               .coherent_dma_mask = 0xffffffff,
+       },
+       .resource = mxc_otg_resources,
+       .num_resources = ARRAY_SIZE(mxc_otg_resources),
+};
+
+static u64 usbh2_dmamask = DMA_BIT_MASK(32);
+
+static struct resource mxc_usbh2_resources[] = {
+       {
+               .start = MX25_OTG_BASE_ADDR + 0x400,
+               .end = MX25_OTG_BASE_ADDR + 0x5ff,
+               .flags = IORESOURCE_MEM,
+       }, {
+               .start = 35,
+               .end = 35,
+               .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_usbh2 = {
+       .name = "mxc-ehci",
+       .id = 1,
+       .dev = {
+               .coherent_dma_mask = 0xffffffff,
+               .dma_mask = &usbh2_dmamask,
+       },
+       .resource = mxc_usbh2_resources,
+       .num_resources = ARRAY_SIZE(mxc_usbh2_resources),
+};
+
+static struct resource mxc_spi_resources0[] = {
+       {
+              .start = 0x43fa4000,
+              .end = 0x43fa7fff,
+              .flags = IORESOURCE_MEM,
+       }, {
+              .start = 14,
+              .end = 14,
+              .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_spi_device0 = {
+       .name = "spi_imx",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(mxc_spi_resources0),
+       .resource = mxc_spi_resources0,
+};
+
+static struct resource mxc_spi_resources1[] = {
+       {
+              .start = 0x50010000,
+              .end = 0x50013fff,
+              .flags = IORESOURCE_MEM,
+       }, {
+              .start = 13,
+              .end = 13,
+              .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_spi_device1 = {
+       .name = "spi_imx",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(mxc_spi_resources1),
+       .resource = mxc_spi_resources1,
+};
+
+static struct resource mxc_spi_resources2[] = {
+       {
+              .start = 0x50004000,
+              .end = 0x50007fff,
+              .flags = IORESOURCE_MEM,
+       }, {
+              .start = 0,
+              .end = 0,
+              .flags = IORESOURCE_IRQ,
+       },
+};
+
+struct platform_device mxc_spi_device2 = {
+       .name = "spi_imx",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(mxc_spi_resources2),
+       .resource = mxc_spi_resources2,
+};
+
+static struct resource mxc_pwm_resources0[] = {
+       {
+               .start  = 0x53fe0000,
+               .end    = 0x53fe3fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start   = 26,
+               .end     = 26,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_pwm_device0 = {
+       .name = "mxc_pwm",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(mxc_pwm_resources0),
+       .resource = mxc_pwm_resources0,
+};
+
+static struct resource mxc_pwm_resources1[] = {
+       {
+               .start  = 0x53fa0000,
+               .end    = 0x53fa3fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start   = 36,
+               .end     = 36,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_pwm_device1 = {
+       .name = "mxc_pwm",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(mxc_pwm_resources1),
+       .resource = mxc_pwm_resources1,
+};
+
+static struct resource mxc_pwm_resources2[] = {
+       {
+               .start  = 0x53fa8000,
+               .end    = 0x53fabfff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start   = 41,
+               .end     = 41,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_pwm_device2 = {
+       .name = "mxc_pwm",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(mxc_pwm_resources2),
+       .resource = mxc_pwm_resources2,
+};
+
+static struct resource mxc_keypad_resources[] = {
+       {
+               .start  = 0x43fa8000,
+               .end    = 0x43fabfff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start   = 24,
+               .end     = 24,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_keypad_device = {
+       .name = "mxc-keypad",
+       .id = -1,
+       .num_resources = ARRAY_SIZE(mxc_keypad_resources),
+       .resource = mxc_keypad_resources,
+};
+
+static struct resource mxc_pwm_resources3[] = {
+       {
+               .start  = 0x53fc8000,
+               .end    = 0x53fcbfff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start   = 42,
+               .end     = 42,
+               .flags   = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_pwm_device3 = {
+       .name = "mxc_pwm",
+       .id = 3,
+       .num_resources = ARRAY_SIZE(mxc_pwm_resources3),
+       .resource = mxc_pwm_resources3,
+};
+
+static struct resource mxc_i2c_1_resources[] = {
+       {
+               .start  = 0x43f80000,
+               .end    = 0x43f83fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = 3,
+               .end    = 3,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_i2c_device0 = {
+       .name = "imx-i2c",
+       .id = 0,
+       .num_resources = ARRAY_SIZE(mxc_i2c_1_resources),
+       .resource = mxc_i2c_1_resources,
+};
+
+static struct resource mxc_i2c_2_resources[] = {
+       {
+               .start  = 0x43f98000,
+               .end    = 0x43f9bfff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = 4,
+               .end    = 4,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_i2c_device1 = {
+       .name = "imx-i2c",
+       .id = 1,
+       .num_resources = ARRAY_SIZE(mxc_i2c_2_resources),
+       .resource = mxc_i2c_2_resources,
+};
+
+static struct resource mxc_i2c_3_resources[] = {
+       {
+               .start  = 0x43f84000,
+               .end    = 0x43f87fff,
+               .flags  = IORESOURCE_MEM,
+       }, {
+               .start  = 10,
+               .end    = 10,
+               .flags  = IORESOURCE_IRQ,
+       }
+};
+
+struct platform_device mxc_i2c_device2 = {
+       .name = "imx-i2c",
+       .id = 2,
+       .num_resources = ARRAY_SIZE(mxc_i2c_3_resources),
+       .resource = mxc_i2c_3_resources,
+};
+
+static struct mxc_gpio_port imx_gpio_ports[] = {
+       {
+               .chip.label = "gpio-0",
+               .base = (void __iomem *)MX25_GPIO1_BASE_ADDR_VIRT,
+               .irq = 52,
+               .virtual_irq_start = MXC_GPIO_IRQ_START,
+       }, {
+               .chip.label = "gpio-1",
+               .base = (void __iomem *)MX25_GPIO2_BASE_ADDR_VIRT,
+               .irq = 51,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 32,
+       }, {
+               .chip.label = "gpio-2",
+               .base = (void __iomem *)MX25_GPIO3_BASE_ADDR_VIRT,
+               .irq = 16,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 64,
+       }, {
+               .chip.label = "gpio-3",
+               .base = (void __iomem *)MX25_GPIO4_BASE_ADDR_VIRT,
+               .irq = 23,
+               .virtual_irq_start = MXC_GPIO_IRQ_START + 96,
+       }
+};
+
+int __init mxc_register_gpios(void)
+{
+       return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+}
+
diff --git a/arch/arm/mach-mx25/devices.h b/arch/arm/mach-mx25/devices.h
new file mode 100644 (file)
index 0000000..fe6bf88
--- /dev/null
@@ -0,0 +1,19 @@
+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_uart_device3;
+extern struct platform_device mxc_uart_device4;
+extern struct platform_device mxc_otg;
+extern struct platform_device otg_udc_device;
+extern struct platform_device mxc_usbh2;
+extern struct platform_device mxc_spi_device0;
+extern struct platform_device mxc_spi_device1;
+extern struct platform_device mxc_spi_device2;
+extern struct platform_device mxc_pwm_device0;
+extern struct platform_device mxc_pwm_device1;
+extern struct platform_device mxc_pwm_device2;
+extern struct platform_device mxc_pwm_device3;
+extern struct platform_device mxc_keypad_device;
+extern struct platform_device mxc_i2c_device0;
+extern struct platform_device mxc_i2c_device1;
+extern struct platform_device mxc_i2c_device2;
diff --git a/arch/arm/mach-mx25/mm.c b/arch/arm/mach-mx25/mm.c
new file mode 100644 (file)
index 0000000..a7e587f
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *  Copyright (C) 1999,2000 Arm Limited
+ *  Copyright (C) 2000 Deep Blue Solutions Ltd
+ *  Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ *  Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *    - add MX31 specific definitions
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <linux/err.h>
+
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/mx25.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * This table defines static virtual address mappings for I/O regions.
+ * These are the mappings common across all MX3 boards.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+       {
+               .virtual        = MX25_AVIC_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(MX25_AVIC_BASE_ADDR),
+               .length         = MX25_AVIC_SIZE,
+               .type           = MT_DEVICE_NONSHARED
+       }, {
+               .virtual        = MX25_AIPS1_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(MX25_AIPS1_BASE_ADDR),
+               .length         = MX25_AIPS1_SIZE,
+               .type           = MT_DEVICE_NONSHARED
+       }, {
+               .virtual        = MX25_AIPS2_BASE_ADDR_VIRT,
+               .pfn            = __phys_to_pfn(MX25_AIPS2_BASE_ADDR),
+               .length         = MX25_AIPS2_SIZE,
+               .type           = MT_DEVICE_NONSHARED
+       },
+};
+
+/*
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory mappings
+ * for the IO modules.
+ */
+void __init mx25_map_io(void)
+{
+       mxc_set_cpu_type(MXC_CPU_MX25);
+       mxc_iomux_v3_init(MX25_IO_ADDRESS(MX25_IOMUXC_BASE_ADDR));
+       mxc_arch_reset_init(MX25_IO_ADDRESS(MX25_WDOG_BASE_ADDR));
+
+       iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mx25_init_irq(void)
+{
+       mxc_init_irq((void __iomem *)MX25_AVIC_BASE_ADDR_VIRT);
+}
+
index 0617c19..e342a2e 100644 (file)
@@ -20,6 +20,13 @@ config ARCH_MX2
        help
          This enables support for systems based on the Freescale i.MX2 family
 
+config ARCH_MX25
+       bool "MX25-based"
+       select CPU_ARM926T
+       select COMMON_CLKDEV
+       help
+         This enables support for systems based on the Freescale i.MX25 family
+
 config ARCH_MX3
        bool "MX3-based"
        select CPU_V6
@@ -32,6 +39,7 @@ endchoice
 source "arch/arm/mach-mx1/Kconfig"
 source "arch/arm/mach-mx2/Kconfig"
 source "arch/arm/mach-mx3/Kconfig"
+source "arch/arm/mach-mx25/Kconfig"
 
 endmenu
 
index f0315ed..cfc4a8b 100644 (file)
@@ -297,7 +297,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()) {
+               if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25()) {
                        /* setup one handler for each entry */
                        set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
                        set_irq_data(port[i].irq, &port[i]);
index cd8f215..4e7af74 100644 (file)
@@ -16,18 +16,21 @@ struct clk;
 
 extern void mx1_map_io(void);
 extern void mx21_map_io(void);
+extern void mx25_map_io(void);
 extern void mx27_map_io(void);
 extern void mx31_map_io(void);
 extern void mx35_map_io(void);
 extern void mxc_init_irq(void __iomem *);
 extern void mx1_init_irq(void);
 extern void mx21_init_irq(void);
+extern void mx25_init_irq(void);
 extern void mx27_init_irq(void);
 extern void mx31_init_irq(void);
 extern void mx35_init_irq(void);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
 extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
+extern int mx25_clocks_init(unsigned long fref);
 extern int mx27_clocks_init(unsigned long fref);
 extern int mx31_clocks_init(unsigned long fref);
 extern int mx35_clocks_init(void);
index 4f85acd..bf683de 100644 (file)
 #define UART_VADDR     IO_ADDRESS(UART1_BASE_ADDR)
 #endif
 
+#ifdef CONFIG_ARCH_MX25
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#include <mach/mx25.h>
+#define UART_PADDR     UART1_BASE_ADDR
+#define UART_VADDR     MX25_AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+#endif
+
 #ifdef CONFIG_ARCH_MX2
 #ifdef UART_PADDR
 #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
index 42e4ee3..569af32 100644 (file)
 # include <mach/mx1.h>
 #endif
 
+#ifdef CONFIG_ARCH_MX25
+# include <mach/mx25.h>
+#endif
+
 #include <mach/mxc.h>
 
 #endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
index 518a365..f39e016 100644 (file)
@@ -24,6 +24,8 @@
 #define MXC_GPIO_IRQS          (32 * 6)
 #elif defined CONFIG_ARCH_MX3
 #define MXC_GPIO_IRQS          (32 * 3)
+#elif defined CONFIG_ARCH_MX25
+#define MXC_GPIO_IRQS          (32 * 4)
 #endif
 
 /*
index 6065e00..42db739 100644 (file)
@@ -22,6 +22,8 @@
 #endif
 #elif defined CONFIG_ARCH_MX3
 #define PHYS_OFFSET            UL(0x80000000)
+#elif defined CONFIG_ARCH_MX25
+#define PHYS_OFFSET            UL(0x80000000)
 #endif
 
 #if defined(CONFIG_MX1_VIDEO)
diff --git a/arch/arm/plat-mxc/include/mach/mx25.h b/arch/arm/plat-mxc/include/mach/mx25.h
new file mode 100644 (file)
index 0000000..ec64bd9
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef __MACH_MX25_H__
+#define __MACH_MX25_H__
+
+#define MX25_AIPS1_BASE_ADDR           0x43F00000
+#define MX25_AIPS1_BASE_ADDR_VIRT      0xFC000000
+#define MX25_AIPS1_SIZE                        SZ_1M
+#define MX25_AIPS2_BASE_ADDR           0x53F00000
+#define MX25_AIPS2_BASE_ADDR_VIRT      0xFC200000
+#define MX25_AIPS2_SIZE                        SZ_1M
+#define MX25_AVIC_BASE_ADDR            0x68000000
+#define MX25_AVIC_BASE_ADDR_VIRT       0xFC400000
+#define MX25_AVIC_SIZE                 SZ_1M
+
+#define MX25_IOMUXC_BASE_ADDR          (MX25_AIPS1_BASE_ADDR + 0xac000)
+
+#define MX25_CRM_BASE_ADDR             (MX25_AIPS2_BASE_ADDR + 0x80000)
+#define MX25_GPT1_BASE_ADDR            (MX25_AIPS2_BASE_ADDR + 0x90000)
+#define MX25_WDOG_BASE_ADDR            (MX25_AIPS2_BASE_ADDR + 0xdc000)
+
+#define MX25_GPIO1_BASE_ADDR_VIRT      (MX25_AIPS2_BASE_ADDR_VIRT + 0xcc000)
+#define MX25_GPIO2_BASE_ADDR_VIRT      (MX25_AIPS2_BASE_ADDR_VIRT + 0xd0000)
+#define MX25_GPIO3_BASE_ADDR_VIRT      (MX25_AIPS2_BASE_ADDR_VIRT + 0xa4000)
+#define MX25_GPIO4_BASE_ADDR_VIRT      (MX25_AIPS2_BASE_ADDR_VIRT + 0x9c000)
+
+#define MX25_AIPS1_IO_ADDRESS(x)  \
+       (((x) - MX25_AIPS1_BASE_ADDR) + MX25_AIPS1_BASE_ADDR_VIRT)
+#define MX25_AIPS2_IO_ADDRESS(x)  \
+       (((x) - MX25_AIPS2_BASE_ADDR) + MX25_AIPS2_BASE_ADDR_VIRT)
+#define MX25_AVIC_IO_ADDRESS(x)  \
+       (((x) - MX25_AVIC_BASE_ADDR) + MX25_AVIC_BASE_ADDR_VIRT)
+
+#define __in_range(addr, name) ((addr) >= name##_BASE_ADDR && (addr) < name##_BASE_ADDR + name##_SIZE)
+
+#define MX25_IO_ADDRESS(x)                                     \
+       (void __force __iomem *)                                \
+       (__in_range(x, MX25_AIPS1) ? MX25_AIPS1_IO_ADDRESS(x) : \
+       __in_range(x, MX25_AIPS2) ? MX25_AIPS2_IO_ADDRESS(x) :  \
+       __in_range(x, MX25_AVIC) ? MX25_AVIC_IO_ADDRESS(x) :    \
+       0xDEADBEEF)
+
+#define UART1_BASE_ADDR                        0x43f90000
+#define UART2_BASE_ADDR                        0x43f94000
+
+#endif /* __MACH_MX25_H__ */
index 5fa2a07..882b816 100644 (file)
@@ -26,6 +26,7 @@
 
 #define MXC_CPU_MX1            1
 #define MXC_CPU_MX21           21
+#define MXC_CPU_MX25           25
 #define MXC_CPU_MX27           27
 #define MXC_CPU_MX31           31
 #define MXC_CPU_MX35           35
@@ -58,6 +59,18 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx21()         (0)
 #endif
 
+#ifdef CONFIG_ARCH_MX25
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX25
+# endif
+# define cpu_is_mx25()         (mxc_cpu_type == MXC_CPU_MX25)
+#else
+# define cpu_is_mx25()         (0)
+#endif
+
 #ifdef CONFIG_MACH_MX27
 # ifdef mxc_cpu_type
 #  undef mxc_cpu_type
index 07b4a73..0707b7d 100644 (file)
@@ -26,6 +26,8 @@
 #define CLOCK_TICK_RATE                13300000
 #elif defined CONFIG_ARCH_MX3
 #define CLOCK_TICK_RATE                16625000
+#elif defined CONFIG_ARCH_MX25
+#define CLOCK_TICK_RATE                16000000
 #endif
 
 #endif                         /* __ASM_ARCH_MXC_TIMEX_H__ */
index 98c8a60..b6650e7 100644 (file)
@@ -63,6 +63,7 @@ static void putc(int ch)
 #define flush() do { } while (0)
 
 #define MX1_UART1_BASE_ADDR    0x00206000
+#define MX25_UART1_BASE_ADDR   0x43f90000
 #define MX2X_UART1_BASE_ADDR   0x1000a000
 #define MX3X_UART1_BASE_ADDR   0x43F90000