linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv2 00/11] Base support for Freescale i.MX51 SoC platform
@ 2010-02-03  5:16 ` Amit Kucheria
  2010-02-03  5:16   ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Amit Kucheria
  0 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

This series of patches adds basic support for i.MX5 family to the kernel. The
target device is the i.MX51-based Babbage board (v2.5+) since that is the
hardware I have access to.

This is a result of dropping a lot of functionality from the existing
Freescale codebase that is shipping as part of the Ubuntu ARM enablement. A
lot of the code was refactored to use facilities that were already available
upstream in arch/arm/plat-mxc/. The hope is to get this base port into
mainline and then start working on mainlining the drivers.

With regards to the splitting of the patches, I felt that the following
patchset made it easy to review code. But if this is not acceptable and some
of these patches need to be merged into a single patch, I can do that too.

Changelog:

V1: Initial submission of base port
V2: - Split core code enabling i.MX51 and the babbage board
    - Refactor timer code to use version 1 or 2 of timer (patch by Sascha)
    - Fixes from review of V1

Regards,
Amit

Amit Kucheria (9):
  arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  mxc: Fix Drive Strength Field in the IOMUX controller
  mxc: changes to common plat-mxc code to add support for i.MX5
  mxc: Core support for i.MX5 series of processors from Freescale
  mxc: enable support for Freescale i.MX5 series of processors
  mxc: Add support for the Babbage board
  fec: Add LAN8700 phy support
  fec: Add ARCH_MX5 as a dependency
  mxc: Add imx51_defconfig

Rob Herring (1):
  fec: fix uninitialized rx buffer usage

Sascha Hauer (1):
  mxc timer: refactor timer code to use timer versions

 arch/arm/Makefile                            |    1 +
 arch/arm/configs/imx51_defconfig             | 1286 ++++++++++++++++++++++++++
 arch/arm/mach-mx5/Kconfig                    |   17 +
 arch/arm/mach-mx5/Makefile                   |    9 +
 arch/arm/mach-mx5/Makefile.boot              |    3 +
 arch/arm/mach-mx5/board-mx51_babbage.c       |   99 ++
 arch/arm/mach-mx5/clock.c                    |  848 +++++++++++++++++
 arch/arm/mach-mx5/cpu.c                      |   45 +
 arch/arm/mach-mx5/crm_regs.h                 |  583 ++++++++++++
 arch/arm/mach-mx5/devices.c                  |   96 ++
 arch/arm/mach-mx5/devices.h                  |    4 +
 arch/arm/mach-mx5/mm.c                       |   88 ++
 arch/arm/plat-mxc/Kconfig                    |   16 +
 arch/arm/plat-mxc/Makefile                   |    3 +
 arch/arm/plat-mxc/include/mach/common.h      |    6 +
 arch/arm/plat-mxc/include/mach/debug-macro.S |    9 +
 arch/arm/plat-mxc/include/mach/entry-macro.S |   34 +-
 arch/arm/plat-mxc/include/mach/hardware.h    |    4 +
 arch/arm/plat-mxc/include/mach/iomux-mx51.h  |  340 +++++++
 arch/arm/plat-mxc/include/mach/iomux-v3.h    |    8 +-
 arch/arm/plat-mxc/include/mach/irqs.h        |    9 +-
 arch/arm/plat-mxc/include/mach/memory.h      |    3 +
 arch/arm/plat-mxc/include/mach/mx51.h        |  454 +++++++++
 arch/arm/plat-mxc/include/mach/mxc.h         |   13 +
 arch/arm/plat-mxc/include/mach/timex.h       |    2 +
 arch/arm/plat-mxc/time.c                     |   23 +-
 arch/arm/plat-mxc/tzic.c                     |  182 ++++
 drivers/net/Kconfig                          |    3 +-
 drivers/net/fec.c                            |   78 +-
 29 files changed, 4222 insertions(+), 44 deletions(-)
 create mode 100644 arch/arm/configs/imx51_defconfig
 create mode 100644 arch/arm/mach-mx5/Kconfig
 create mode 100644 arch/arm/mach-mx5/Makefile
 create mode 100644 arch/arm/mach-mx5/Makefile.boot
 create mode 100644 arch/arm/mach-mx5/board-mx51_babbage.c
 create mode 100644 arch/arm/mach-mx5/clock.c
 create mode 100644 arch/arm/mach-mx5/cpu.c
 create mode 100644 arch/arm/mach-mx5/crm_regs.h
 create mode 100644 arch/arm/mach-mx5/devices.c
 create mode 100644 arch/arm/mach-mx5/devices.h
 create mode 100644 arch/arm/mach-mx5/mm.c
 create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
 create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h
 create mode 100644 arch/arm/plat-mxc/tzic.c

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03  5:16 ` [PATCHv2 00/11] Base support for Freescale i.MX51 SoC platform Amit Kucheria
@ 2010-02-03  5:16   ` Amit Kucheria
  2010-02-03  5:16     ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Amit Kucheria
  2010-02-03  6:23     ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Eric Miao
  0 siblings, 2 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

Freescale i.MX51 processor uses a new interrupt controller. Add
driver for TrustZone Interrupt Controller

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/plat-mxc/Kconfig  |    8 ++
 arch/arm/plat-mxc/Makefile |    3 +
 arch/arm/plat-mxc/tzic.c   |  182 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 193 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-mxc/tzic.c

diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 8b0a1ee..59558c4 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
 	  requirements for timing.
 	  Say N here, unless you have a specialized requirement.
 
+config MXC_TZIC
+	bool "Enable TrustZone Interrupt Controller"
+	depends on ARCH_MX51
+	help
+	  This will be automatically selected for all processors
+	  containing this interrupt controller.
+	  Say N here only if you are really sure.
+
 config MXC_PWM
 	tristate "Enable PWM driver"
 	depends on ARCH_MXC
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 996cbac..0202ad9 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -5,6 +5,9 @@
 # Common support
 obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
 
+# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
+obj-$(CONFIG_MXC_TZIC) += tzic.o
+
 obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
new file mode 100644
index 0000000..00cb0ad
--- /dev/null
+++ b/arch/arm/plat-mxc/tzic.c
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2004-2009 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
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+
+#include <asm/mach/irq.h>
+
+#include <mach/hardware.h>
+
+/*
+ *****************************************
+ * TZIC Registers                        *
+ *****************************************
+ */
+
+#define TZIC_INTCNTL            0x0000	/* Control register */
+#define TZIC_INTTYPE            0x0004	/* Controller Type register */
+#define TZIC_IMPID              0x0008	/* Distributor Implementer Identification */
+#define TZIC_PRIOMASK           0x000C	/* Priority Mask Reg */
+#define TZIC_SYNCCTRL           0x0010	/* Synchronizer Control register */
+#define TZIC_DSMINT             0x0014	/* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0            0x0080	/* Interrupt Security register 0 */
+#define TZIC_ENSET0             0x0100	/* Enable Set Register 0 */
+#define TZIC_ENCLEAR0           0x0180	/* Enable Clear Register 0 */
+#define TZIC_SRCSET0            0x0200	/* Source Set Register 0 */
+#define TZIC_SRCCLAR0           0x0280	/* Source Clear Register 0 */
+#define TZIC_PRIORITY0          0x0400	/* Priority Register 0 */
+#define TZIC_PND0               0x0D00	/* Pending Register 0 */
+#define TZIC_HIPND0             0x0D80	/* High Priority Pending Register */
+#define TZIC_WAKEUP0            0x0E00	/* Wakeup Config Register */
+#define TZIC_SWINT              0x0F00	/* Software Interrupt Rigger Register */
+#define TZIC_ID0                0x0FD0	/* Indentification Register 0 */
+
+void __iomem *tzic_base;
+
+/*
+ * Disable interrupt number "irq" in the TZIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void tzic_mask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0 + (index << 2));
+}
+
+/*
+ * Enable interrupt number "irq" in the TZIC
+ *
+ * @param  irq          interrupt source number
+ */
+static void tzic_unmask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, tzic_base + TZIC_ENSET0 + (index << 2));
+}
+
+static unsigned int wakeup_intr[4];
+
+/*
+ * Set interrupt number "irq" in the TZIC as a wake-up source.
+ *
+ * @param  irq          interrupt source number
+ * @param  enable       enable as wake-up if equal to non-zero
+ * 			disble as wake-up if equal to zero
+ *
+ * @return       This function returns 0 on success.
+ */
+static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
+{
+	unsigned int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+
+	if (index > 3)
+		return -EINVAL;
+
+	if (enable)
+		wakeup_intr[index] |= (1 << off);
+	else
+		wakeup_intr[index] &= ~(1 << off);
+
+	return 0;
+}
+
+static struct irq_chip mxc_tzic_chip = {
+	.name = "MXC_TZIC",
+	.ack = tzic_mask_irq,
+	.mask = tzic_mask_irq,
+	.unmask = tzic_unmask_irq,
+	.set_wake = tzic_set_wake_irq,
+};
+
+/*
+ * This function initializes the TZIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init tzic_init_irq(void __iomem *irqbase)
+{
+	int i;
+
+	tzic_base = irqbase;
+	/* put the TZIC into the reset value with
+	 * all interrupts disabled
+	 */
+	i = __raw_readl(tzic_base + TZIC_INTCNTL);
+
+	__raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
+	i = __raw_readl(tzic_base + TZIC_INTCNTL);
+	__raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
+	i = __raw_readl(tzic_base + TZIC_PRIOMASK);
+	__raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
+	i = __raw_readl(tzic_base + TZIC_SYNCCTRL);
+
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0 + i * 4);
+
+	/* disable all interrupts */
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0 + i * 4);
+
+	/* all IRQ no FIQ Warning :: No selection */
+
+	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxc_tzic_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	printk(KERN_INFO "TrustZone Interrupt Controller (TZIC) initialized\n");
+}
+
+/*
+ * enable wakeup interrupt
+ *
+ * @param is_idle		1 if called in idle loop (ENSET register);
+ *				0 to be used when called from low power entry
+ * @return			0 if successful; non-zero otherwise
+ *
+ */
+int tzic_enable_wake(int is_idle)
+{
+	unsigned int i, v;
+
+	__raw_writel(1, tzic_base + TZIC_DSMINT);
+	if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
+		return -EAGAIN;
+
+	if (likely(is_idle)) {
+		for (i = 0; i < 4; i++) {
+			v = __raw_readl(tzic_base + TZIC_ENSET0 + i * 4);
+			__raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
+		}
+	} else {
+		for (i = 0; i < 4; i++) {
+			v = wakeup_intr[i];
+			__raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
+		}
+	}
+	return 0;
+}
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions
  2010-02-03  5:16   ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Amit Kucheria
@ 2010-02-03  5:16     ` Amit Kucheria
  2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
  2010-02-03 16:23       ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Grant Likely
  2010-02-03  6:23     ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Eric Miao
  1 sibling, 2 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Sascha Hauer <s.hauer@pengutronix.de>

Refactor the timer code into version 1 and version 2.

Essentially there are 2 versions of the timer hardware. Version 1 is found on
MX1/MXL and MX21. Version 2 is found on MX25, MX27, MX31, MX35, MX37, MX51,
and future parts.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Acked-by: Amit Kucheria <amit.kucheria@canonical.com>
Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/plat-mxc/time.c |   19 +++++++++++--------
 1 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 844567e..7d6499e 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -57,6 +57,9 @@
 #define MX3_TCN			0x24
 #define MX3_TCMP		0x10
 
+#define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx27())
+#define timer_is_v2()	(cpu_is_mx3() || cpu_is_mx25())
+
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
 
@@ -66,7 +69,7 @@ static inline void gpt_irq_disable(void)
 {
 	unsigned int tmp;
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		__raw_writel(0, timer_base + MX3_IR);
 	else {
 		tmp = __raw_readl(timer_base + MXC_TCTL);
@@ -76,7 +79,7 @@ static inline void gpt_irq_disable(void)
 
 static inline void gpt_irq_enable(void)
 {
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		__raw_writel(1<<0, timer_base + MX3_IR);
 	else {
 		__raw_writel(__raw_readl(timer_base + MXC_TCTL) | MX1_2_TCTL_IRQEN,
@@ -90,7 +93,7 @@ static void gpt_irq_acknowledge(void)
 		__raw_writel(0, timer_base + MX1_2_TSTAT);
 	if (cpu_is_mx2())
 		__raw_writel(MX2_TSTAT_CAPT | MX2_TSTAT_COMP, timer_base + MX1_2_TSTAT);
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		__raw_writel(MX3_TSTAT_OF1, timer_base + MX3_TSTAT);
 }
 
@@ -117,7 +120,7 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		clocksource_mxc.read = mx3_get_cycles;
 
 	clocksource_mxc.mult = clocksource_hz2mult(c,
@@ -180,7 +183,7 @@ static void mxc_set_mode(enum clock_event_mode mode,
 
 	if (mode != clockevent_mode) {
 		/* Set event time into far-far future */
-		if (cpu_is_mx3() || cpu_is_mx25())
+		if (timer_is_v2())
 			__raw_writel(__raw_readl(timer_base + MX3_TCN) - 3,
 					timer_base + MX3_TCMP);
 		else
@@ -233,7 +236,7 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	struct clock_event_device *evt = &clockevent_mxc;
 	uint32_t tstat;
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		tstat = __raw_readl(timer_base + MX3_TSTAT);
 	else
 		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
@@ -264,7 +267,7 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		clockevent_mxc.set_next_event = mx3_set_next_event;
 
 	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -296,7 +299,7 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 	__raw_writel(0, timer_base + MXC_TCTL);
 	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
 
-	if (cpu_is_mx3() || cpu_is_mx25())
+	if (timer_is_v2())
 		tctl_val = MX3_TCTL_CLK_IPG | MX3_TCTL_FRR | MX3_TCTL_WAITEN | MXC_TCTL_TEN;
 	else
 		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller
  2010-02-03  5:16     ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Amit Kucheria
@ 2010-02-03  5:16       ` Amit Kucheria
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
                           ` (2 more replies)
  2010-02-03 16:23       ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Grant Likely
  1 sibling, 3 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

i.MX51 defines 4 values:

00: Low Drive Strength
01: Medium Drive Strength
10: High Drive Strength
11: Max Drive Strength

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/plat-mxc/include/mach/iomux-v3.h |    8 +++++---
 1 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
index 1deda01..f2f73d3 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
@@ -81,11 +81,13 @@ struct pad_desc {
 
 #define PAD_CTL_ODE			(1 << 3)
 
-#define PAD_CTL_DSE_STANDARD		(0 << 1)
-#define PAD_CTL_DSE_HIGH		(1 << 1)
-#define PAD_CTL_DSE_MAX			(2 << 1)
+#define PAD_CTL_DSE_LOW			(0 << 1)
+#define PAD_CTL_DSE_MED			(1 << 1)
+#define PAD_CTL_DSE_HIGH		(2 << 1)
+#define PAD_CTL_DSE_MAX			(3 << 1)
 
 #define PAD_CTL_SRE_FAST		(1 << 0)
+#define PAD_CTL_SRE_SLOW		(0 << 0)
 
 /*
  * setups a single pad in the iomuxer
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
@ 2010-02-03  5:16         ` Amit Kucheria
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
                             ` (2 more replies)
  2010-02-03  6:29         ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Eric Miao
  2010-02-03 16:27         ` Grant Likely
  2 siblings, 3 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

Changes separted to help in the review process

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/plat-mxc/include/mach/common.h      |    4 +++
 arch/arm/plat-mxc/include/mach/debug-macro.S |    9 +++++++
 arch/arm/plat-mxc/include/mach/entry-macro.S |   34 +++++++++++++++++++++++++-
 arch/arm/plat-mxc/include/mach/hardware.h    |    4 +++
 arch/arm/plat-mxc/include/mach/irqs.h        |    9 ++++++-
 arch/arm/plat-mxc/include/mach/memory.h      |    3 ++
 arch/arm/plat-mxc/include/mach/mxc.h         |   13 ++++++++++
 arch/arm/plat-mxc/include/mach/timex.h       |    2 +
 arch/arm/plat-mxc/time.c                     |    6 ++--
 9 files changed, 79 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 286cb9b..5250a3f 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -20,8 +20,10 @@ 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 mx51_map_io(void);
 extern void mxc91231_map_io(void);
 extern void mxc_init_irq(void __iomem *);
+extern void tzic_init_irq(void __iomem *);
 extern void mx1_init_irq(void);
 extern void mx21_init_irq(void);
 extern void mx25_init_irq(void);
@@ -36,6 +38,8 @@ 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);
+extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
+			unsigned long ckih1, unsigned long ckih2);
 extern int mxc91231_clocks_init(unsigned long fref);
 extern int mxc_register_gpios(void);
 extern int mxc_register_device(struct platform_device *pdev, void *data);
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 15b2b14..9fe7300 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -44,6 +44,15 @@
 #define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
 #endif
 
+#ifdef CONFIG_ARCH_MX5
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#include <mach/mx51.h>
+#define UART_PADDR	UART1_BASE_ADDR
+#define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+#endif
+
 #ifdef CONFIG_ARCH_MXC91231
 #ifdef UART_PADDR
 #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 7cf290e..aeb0869 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -1,6 +1,6 @@
 /*
  *  Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -18,11 +18,16 @@
 	.endm
 
 	.macro  get_irqnr_preamble, base, tmp
+#ifndef CONFIG_MXC_TZIC
 	ldr	\base, =avic_base
 	ldr	\base, [\base]
 #ifdef CONFIG_MXC_IRQ_PRIOR
 	ldr	r4, [\base, #AVIC_NIMASK]
 #endif
+#elif defined CONFIG_MXC_TZIC
+	ldr	\base, =tzic_base
+	ldr	\base, [\base]
+#endif /* CONFIG_MXC_TZIC */
 	.endm
 
 	.macro  arch_ret_to_user, tmp1, tmp2
@@ -32,6 +37,7 @@
 	@ and returns its number in irqnr
 	@ and returns if an interrupt occured in irqstat
 	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifndef CONFIG_MXC_TZIC
 	@ Load offset & priority of the highest priority
 	@ interrupt pending from AVIC_NIVECSR
 	ldr	\irqstat, [\base, #0x40]
@@ -45,6 +51,32 @@
 	strne	\tmp, [\base, #AVIC_NIMASK]
 	streq	r4, [\base, #AVIC_NIMASK]
 #endif
+#elif defined CONFIG_MXC_TZIC
+	@ Load offset & priority of the highest priority
+	@ interrupt pending.
+	@ 0xD80 is HIPND0 register
+	mov     \irqnr, #0
+	mov     \irqstat, #0x0D80
+1000:
+	ldr     \tmp,   [\irqstat, \base]
+	cmp     \tmp, #0
+	bne     1001f
+	addeq   \irqnr, \irqnr, #32
+	addeq   \irqstat, \irqstat, #4
+	cmp     \irqnr, #128
+	blo     1000b
+	b       2001f
+1001:	mov     \irqstat, #1
+1002:	tst     \tmp, \irqstat
+	bne     2002f
+	movs    \tmp, \tmp, lsr #1
+	addne   \irqnr, \irqnr, #1
+	bne     1002b
+2001:
+	mov  \irqnr, #0
+2002:
+	movs \irqnr, \irqnr
+#endif
 	.endm
 
 	@ irq priority table (not used)
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 78db754..55ebe88 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -22,6 +22,10 @@
 
 #include <asm/sizes.h>
 
+#ifdef CONFIG_ARCH_MX5
+#include <mach/mx51.h>
+#endif
+
 #ifdef CONFIG_ARCH_MX3
 #include <mach/mx3x.h>
 #include <mach/mx31.h>
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index ead9d59..24c066e 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -12,9 +12,13 @@
 #define __ASM_ARCH_MXC_IRQS_H__
 
 /*
- * So far all i.MX SoCs have 64 internal interrupts
+ * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
  */
+#ifdef CONFIG_MXC_TZIC
+#define MXC_INTERNAL_IRQS	128
+#else
 #define MXC_INTERNAL_IRQS	64
+#endif
 
 #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
 
@@ -26,6 +30,8 @@
 #define MXC_GPIO_IRQS		(32 * 3)
 #elif defined CONFIG_ARCH_MX25
 #define MXC_GPIO_IRQS		(32 * 4)
+#elif defined CONFIG_ARCH_MX5
+#define MXC_GPIO_IRQS		(32 * 4)
 #elif defined CONFIG_ARCH_MXC91231
 #define MXC_GPIO_IRQS		(32 * 4)
 #endif
@@ -46,6 +52,7 @@
 #else
 #define MX3_IPU_IRQS 0
 #endif
+/* REVISIT: Add IPU irqs on IMX51 */
 
 #define NR_IRQS			(MXC_IPU_IRQ_START + MX3_IPU_IRQS)
 
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index d3afafd..e46626e 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -27,6 +27,9 @@
 #elif defined CONFIG_ARCH_MXC91231
 #define PHYS_OFFSET		UL(0x90000000)
 #endif
+#ifdef CONFIG_ARCH_MX5
+#define PHYS_OFFSET             UL(0x90000000)
+#endif
 
 #if defined(CONFIG_MX1_VIDEO)
 /*
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 5199053..555e5f8 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -30,6 +30,7 @@
 #define MXC_CPU_MX27		27
 #define MXC_CPU_MX31		31
 #define MXC_CPU_MX35		35
+#define MXC_CPU_MX51		51
 #define MXC_CPU_MXC91231	91231
 
 #ifndef __ASSEMBLY__
@@ -108,6 +109,18 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx35()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_MX5
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX51
+# endif
+# define cpu_is_mx51()		(mxc_cpu_type == MXC_CPU_MX51)
+#else
+# define cpu_is_mx51()		(0)
+#endif
+
 #ifdef CONFIG_ARCH_MXC91231
 # ifdef mxc_cpu_type
 #  undef mxc_cpu_type
diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
index 527a6c2..024416e 100644
--- a/arch/arm/plat-mxc/include/mach/timex.h
+++ b/arch/arm/plat-mxc/include/mach/timex.h
@@ -28,6 +28,8 @@
 #define CLOCK_TICK_RATE		16625000
 #elif defined CONFIG_ARCH_MX25
 #define CLOCK_TICK_RATE		16000000
+#elif defined CONFIG_ARCH_MX5
+#define CLOCK_TICK_RATE		8000000
 #elif defined CONFIG_ARCH_MXC91231
 #define CLOCK_TICK_RATE		13000000
 #endif
diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index 7d6499e..2ba8b29 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -32,7 +32,7 @@
 
 /* defines common for all i.MX */
 #define MXC_TCTL		0x00
-#define MXC_TCTL_TEN		(1 << 0)
+#define MXC_TCTL_TEN		(1 << 0) /* Enable module */
 #define MXC_TPRER		0x04
 
 /* MX1, MX21, MX27 */
@@ -48,7 +48,7 @@
 #define MX2_TSTAT_COMP		(1 << 0)
 
 /* MX31, MX35, MX25, MXC91231 */
-#define MX3_TCTL_WAITEN		(1 << 3)
+#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
@@ -58,7 +58,7 @@
 #define MX3_TCMP		0x10
 
 #define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx27())
-#define timer_is_v2()	(cpu_is_mx3() || cpu_is_mx25())
+#define timer_is_v2()	(cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51())
 
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
@ 2010-02-03  5:16           ` Amit Kucheria
  2010-02-03  5:16             ` [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors Amit Kucheria
                               ` (4 more replies)
  2010-02-03  6:43           ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Eric Miao
  2010-02-03 16:35           ` Grant Likely
  2 siblings, 5 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Amit Kucheria <amit.kucheria@verdurent.com>

Add basic clock support, cpu identification, I/O mapping and serial port.

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/mach-mx5/clock.c                    |  848 ++++++++++++++++++++++++++
 arch/arm/mach-mx5/cpu.c                      |   45 ++
 arch/arm/mach-mx5/crm_regs.h                 |  583 ++++++++++++++++++
 arch/arm/mach-mx5/devices.c                  |   96 +++
 arch/arm/mach-mx5/devices.h                  |    4 +
 arch/arm/mach-mx5/mm.c                       |   88 +++
 arch/arm/plat-mxc/include/mach/common.h      |    1 +
 arch/arm/plat-mxc/include/mach/debug-macro.S |    4 +-
 arch/arm/plat-mxc/include/mach/iomux-mx51.h  |  340 +++++++++++
 arch/arm/plat-mxc/include/mach/mx51.h        |  454 ++++++++++++++
 10 files changed, 2461 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/mach-mx5/clock.c
 create mode 100644 arch/arm/mach-mx5/cpu.c
 create mode 100644 arch/arm/mach-mx5/crm_regs.h
 create mode 100644 arch/arm/mach-mx5/devices.c
 create mode 100644 arch/arm/mach-mx5/devices.h
 create mode 100644 arch/arm/mach-mx5/mm.c
 create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
 create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h

diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
new file mode 100644
index 0000000..595f966
--- /dev/null
+++ b/arch/arm/mach-mx5/clock.c
@@ -0,0 +1,848 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "crm_regs.h"
+
+static void __iomem *pll_base[] = {
+	MX51_DPLL1_BASE,
+	MX51_DPLL2_BASE,
+	MX51_DPLL3_BASE,
+};
+
+/* External clock values passed-in by the board code */
+static unsigned long external_high_reference, external_low_reference;
+static unsigned long oscillator_reference, ckih2_reference;
+
+static struct clk osc_clk;
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk periph_apm_clk;
+static struct clk ahb_clk;
+static struct clk ipg_clk;
+
+#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
+
+static int _clk_ccgr_enable(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+
+	return 0;
+}
+
+static void _clk_ccgr_disable(struct clk *clk)
+{
+	u32 reg;
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
+	__raw_writel(reg, clk->enable_reg);
+
+}
+
+static void _clk_ccgr_disable_inwait(struct clk *clk)
+{
+	u32 reg;
+
+	reg = __raw_readl(clk->enable_reg);
+	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
+	reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
+	__raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+			   struct clk *m1, struct clk *m2, struct clk *m3)
+{
+	if (parent == m0)
+		return 0;
+	else if (parent == m1)
+		return 1;
+	else if (parent == m2)
+		return 2;
+	else if (parent == m3)
+		return 3;
+	else
+		BUG();
+
+	return -EINVAL;
+}
+
+static inline void __iomem *_get_pll_base(struct clk *pll)
+{
+	if (pll == &pll1_main_clk)
+		return pll_base[0];
+	else if (pll == &pll2_sw_clk)
+		return pll_base[1];
+	else if (pll == &pll3_sw_clk)
+		return pll_base[2];
+	else
+		BUG();
+
+	return NULL;
+}
+
+static unsigned long clk_pll_get_rate(struct clk *clk)
+{
+	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+	void __iomem *pllbase;
+	s64 temp;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pllbase = _get_pll_base(clk);
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+	if (pll_hfsm == 0) {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+	} else {
+		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+	mfi = (mfi <= 5) ? 5 : mfi;
+	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+	/* Sign extend to 32-bits */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xFC000000;
+		mfn_abs = -mfn;
+	}
+
+	ref_clk = 2 * parent_rate;
+	if (dbl != 0)
+		ref_clk *= 2;
+
+	ref_clk /= (pdf + 1);
+	temp = (u64) ref_clk * mfn_abs;
+	do_div(temp, mfd + 1);
+	if (mfn < 0)
+		temp = -temp;
+	temp = (ref_clk * mfi) + temp;
+
+	return temp;
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg;
+	void __iomem *pllbase;
+
+	long mfi, pdf, mfn, mfd = 999999;
+	s64 temp64;
+	unsigned long quad_parent_rate;
+	unsigned long pll_hfsm, dp_ctl;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	pllbase = _get_pll_base(clk);
+
+	quad_parent_rate = 4 * parent_rate;
+	pdf = mfi = -1;
+	while (++pdf < 16 && mfi < 5)
+		mfi = rate * (pdf+1) / quad_parent_rate;
+	if (mfi > 15)
+		return -1;
+	pdf--;
+
+	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
+	do_div(temp64, quad_parent_rate/1000000);
+	mfn = (long)temp64;
+
+	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+	/* use dpdck0_2 */
+	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
+	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+	if (pll_hfsm == 0) {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
+	} else {
+		reg = mfi << 4 | pdf;
+		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
+		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
+		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
+	}
+
+	return 0;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+	u32 reg;
+	void __iomem *pllbase;
+	int i = 0;
+
+	pllbase = _get_pll_base(clk);
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+	/* Wait for lock */
+	while ((!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF))
+		&& i < MAX_DPLL_WAIT_TRIES) {
+		i++;
+		udelay(1);
+	}
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		printk(KERN_ERR "MX5: pll locking failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+	u32 reg;
+	void __iomem *pllbase;
+
+	pllbase = _get_pll_base(clk);
+	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	/* When switching from pll_main_clk to a bypass clock, first select a
+	   multiplexed clock in 'step_sel', then shift the glitchless mux
+	   'pll1_sw_clk_sel'.
+	   When switching back, do it in reverse order
+	*/
+	if (parent == &pll1_main_clk) {
+		/* Switch to pll1_main_clk */
+		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+		__raw_writel(reg, MXC_CCM_CCSR);
+		/* step_clk mux switched to lp_apm, to save power. */
+		reg = __raw_readl(MXC_CCM_CCSR);
+		reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+			(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+				MXC_CCM_CCSR_STEP_SEL_OFFSET);
+	} else {
+		if (parent == &lp_apm_clk) {
+			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+				(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
+					MXC_CCM_CCSR_STEP_SEL_OFFSET);
+		} else  if (parent == &pll2_sw_clk) {
+			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+				(MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED <<
+					MXC_CCM_CCSR_STEP_SEL_OFFSET);
+		} else  if (parent == &pll3_sw_clk) {
+			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+				(MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
+					MXC_CCM_CCSR_STEP_SEL_OFFSET);
+		} else
+			return -EINVAL;
+
+		__raw_writel(reg, MXC_CCM_CCSR);
+		/* Switch to step_clk */
+		reg = __raw_readl(MXC_CCM_CCSR);
+		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+	}
+	__raw_writel(reg, MXC_CCM_CCSR);
+	return 0;
+}
+
+static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = 1;
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	if (clk->parent == &pll2_sw_clk) {
+		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+	} else if (clk->parent == &pll3_sw_clk) {
+		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+	}
+	return parent_rate / div;
+}
+
+static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CCSR);
+
+	if (parent == &pll2_sw_clk)
+		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+	else
+		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
+
+	__raw_writel(reg, MXC_CCM_CCSR);
+	return 0;
+}
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	if (parent == &osc_clk)
+		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CCSR);
+
+	return 0;
+}
+
+static unsigned long clk_arm_get_rate(struct clk *clk)
+{
+	u32 cacrr, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+	cacrr = __raw_readl(MXC_CCM_CACRR);
+	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+
+	return parent_rate / div;
+}
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg, mux;
+	int i = 0;
+
+	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+	__raw_writel(reg, MXC_CCM_CBCMR);
+
+	/* Wait for lock */
+	while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)
+		&& i < MAX_DPLL_WAIT_TRIES) {
+		i++;
+		udelay(1);
+	}
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		printk(KERN_ERR "MX5: Set parent for periph_apm clock failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned long clk_main_bus_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent);
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+
+	if (parent == &pll2_sw_clk)
+		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+	else if (parent == &periph_apm_clk)
+		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+	else
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CBCDR);
+
+	return 0;
+}
+
+static struct clk main_bus_clk = {
+	.parent = &pll2_sw_clk,
+	.set_parent = _clk_main_bus_set_parent,
+	.get_rate = clk_main_bus_get_rate,
+};
+
+static unsigned long clk_ahb_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+	       MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+	return parent_rate / div;
+}
+
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+	int i = 0;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+	if (div > 8 || div < 1 || ((parent_rate / div) != rate))
+		return -EINVAL;
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
+	reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
+	__raw_writel(reg, MXC_CCM_CBCDR);
+
+	/* Wait for lock */
+	while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY)
+		&& i < MAX_DPLL_WAIT_TRIES) {
+		i++;
+		udelay(1);
+	}
+
+	if (i == MAX_DPLL_WAIT_TRIES) {
+		printk(KERN_ERR "MX5: clk_ahb_set_rate failed\n");
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+						unsigned long rate)
+{
+	u32 div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	div = parent_rate / rate;
+	if (div > 8)
+		div = 8;
+	else if (div == 0)
+		div++;
+	return parent_rate / div;
+}
+
+
+static int _clk_max_enable(struct clk *clk)
+{
+	u32 reg;
+
+	_clk_ccgr_enable(clk);
+
+	/* Handshake with MAX when LPM is entered. */
+	reg = __raw_readl(MXC_CCM_CLPCR);
+	reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+	__raw_writel(reg, MXC_CCM_CLPCR);
+
+	return 0;
+}
+
+static void _clk_max_disable(struct clk *clk)
+{
+	u32 reg;
+
+	_clk_ccgr_disable_inwait(clk);
+
+	/* No Handshake with MAX when LPM is entered as its disabled. */
+	reg = __raw_readl(MXC_CCM_CLPCR);
+	reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+	__raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static unsigned long clk_ipg_get_rate(struct clk *clk)
+{
+	u32 reg, div;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+	       MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+	return parent_rate / div;
+}
+
+static unsigned long clk_ipg_per_get_rate(struct clk *clk)
+{
+	u32 reg, prediv1, prediv2, podf;
+	unsigned long parent_rate;
+
+	parent_rate = clk_get_rate(clk->parent);
+
+	if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+		/* the main_bus_clk is the one before the DVFS engine */
+		reg = __raw_readl(MXC_CCM_CBCDR);
+		prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+			   MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+		prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+			   MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+		podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+			MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+		return parent_rate / (prediv1 * prediv2 * podf);
+	} else if (clk->parent == &ipg_clk) {
+		return parent_rate;
+	} else {
+		BUG();
+	}
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+	u32 reg;
+
+	reg = __raw_readl(MXC_CCM_CBCMR);
+
+	reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+	reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+
+	if (parent == &ipg_clk)
+		reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+	else if (parent == &lp_apm_clk)
+		reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+	else if (parent != &main_bus_clk)
+		return -EINVAL;
+
+	__raw_writel(reg, MXC_CCM_CBCMR);
+
+	return 0;
+}
+
+static unsigned long clk_uart_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_UART_CLK_PRED_MASK) >>
+		  MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+	podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+		MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+	return parent_rate / (prediv * podf);
+}
+
+static int _clk_uart_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_UART_CLK_SEL_MASK;
+	reg |= mux << MXC_CCM_CSCMR1_UART_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;
+}
+
+static unsigned long get_low_reference_clock_rate(struct clk *clk)
+{
+	return external_low_reference;
+}
+
+static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
+{
+	return oscillator_reference;
+}
+
+static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
+{
+	return ckih2_reference;
+}
+
+/* External high frequency clock */
+static struct clk ckih_clk = {
+	.get_rate = get_high_reference_clock_rate,
+};
+
+static struct clk ckih2_clk = {
+	.get_rate = get_ckih2_reference_clock_rate,
+};
+
+static struct clk osc_clk = {
+	.get_rate = get_oscillator_reference_clock_rate,
+};
+
+/* External low frequency (32kHz) clock */
+static struct clk ckil_clk = {
+	.get_rate = get_low_reference_clock_rate,
+};
+
+static struct clk pll1_main_clk = {
+	.parent = &osc_clk,
+	.get_rate = clk_pll_get_rate,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* Clock tree block diagram (WIP):
+ * 	CCM: Clock Controller Module
+ *
+ * PLL output -> |
+ *               | CCM Switcher -> CCM_CLK_ROOT_GEN ->
+ * PLL bypass -> |
+ *
+ */
+
+/* PLL1 SW supplies to ARM core */
+static struct clk pll1_sw_clk = {
+	.parent = &pll1_main_clk,
+	.set_parent = _clk_pll1_sw_set_parent,
+	.get_rate = clk_pll1_sw_get_rate,
+};
+
+/* PLL2 SW supplies to AXI/AHB/IP buses */
+static struct clk pll2_sw_clk = {
+	.parent = &osc_clk,
+	.get_rate = clk_pll_get_rate,
+	.set_rate = _clk_pll_set_rate,
+	.set_parent = _clk_pll2_sw_set_parent,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
+static struct clk pll3_sw_clk = {
+	.parent = &osc_clk,
+	.set_rate = _clk_pll_set_rate,
+	.get_rate = clk_pll_get_rate,
+	.enable = _clk_pll_enable,
+	.disable = _clk_pll_disable,
+};
+
+/* Low-power Audio Playback Mode clock */
+static struct clk lp_apm_clk = {
+	.parent = &osc_clk,
+	.set_parent = _clk_lp_apm_set_parent,
+};
+
+static struct clk periph_apm_clk = {
+	.parent = &pll1_sw_clk,
+	.set_parent = _clk_periph_apm_set_parent,
+};
+
+static struct clk cpu_clk = {
+	.parent = &pll1_sw_clk,
+	.get_rate = clk_arm_get_rate,
+};
+
+static struct clk ahb_clk = {
+	.parent = &main_bus_clk,
+	.get_rate = clk_ahb_get_rate,
+	.set_rate = _clk_ahb_set_rate,
+	.round_rate = _clk_ahb_round_rate,
+};
+
+/* Main IP interface clock for access to registers */
+static struct clk ipg_clk = {
+	.parent = &ahb_clk,
+	.get_rate = clk_ipg_get_rate,
+};
+
+static struct clk ipg_perclk = {
+	.parent = &lp_apm_clk,
+	.get_rate = clk_ipg_per_get_rate,
+	.set_parent = _clk_ipg_per_set_parent,
+};
+
+static struct clk uart_root_clk = {
+	.parent = &pll2_sw_clk,
+	.get_rate = clk_uart_get_rate,
+	.set_parent = _clk_uart_set_parent,
+};
+
+static struct clk ahb_max_clk = {
+	.parent = &ahb_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
+	.enable = _clk_max_enable,
+	.disable = _clk_max_disable,
+};
+
+static struct clk aips_tz1_clk = {
+	.parent = &ahb_clk,
+	.secondary = &ahb_max_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+	.parent = &ahb_clk,
+	.secondary = &ahb_max_clk,
+	.enable_reg = MXC_CCM_CCGR0,
+	.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
+	.enable = _clk_ccgr_enable,
+	.disable = _clk_ccgr_disable_inwait,
+};
+
+static struct clk gpt_32k_clk = {
+	.id = 0,
+	.parent = &ckil_clk,
+};
+
+#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s)	\
+	static struct clk name = {			\
+		.id		= i,			\
+		.enable_reg	= er,			\
+		.enable_shift	= es,			\
+		.get_rate	= gr,			\
+		.set_rate	= sr,			\
+		.enable		= _clk_ccgr_enable,	\
+		.disable	= _clk_ccgr_disable,	\
+		.parent		= p,			\
+		.secondary	= s,			\
+	}
+
+/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
+   get_rate, set_rate, parent, secondary); */
+
+/* Shared peripheral bus arbiter */
+DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+/* UART */
+DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
+	NULL,  NULL, &uart_root_clk, NULL);
+DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
+	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
+	NULL,  NULL, &ipg_clk, &aips_tz1_clk);
+DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
+	NULL,  NULL, &ipg_clk, &spba_clk);
+
+/* GPT */
+DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
+	NULL,  NULL, &ipg_perclk, NULL);
+DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+/* FEC */
+DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
+	NULL,  NULL, &ipg_clk, NULL);
+
+#define _REGISTER_CLOCK(d, n, c) \
+       { \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c,   \
+       },
+
+static struct clk_lookup lookups[] __initdata = {
+	_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(NULL, "gpt", gpt_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+};
+
+static void clk_tree_init(void)
+{
+	u32 reg;
+
+	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+	/*
+	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+	 * 8MHz, its derived from lp_apm.
+	 * FIXME: Verify if true for all boards
+	 */
+	reg = __raw_readl(MXC_CCM_CBCDR);
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+	__raw_writel(reg, MXC_CCM_CBCDR);
+
+	/* set parent for pll1, pll2 and pll3 */
+	pll1_main_clk.parent = &osc_clk;
+	pll2_sw_clk.parent = &osc_clk;
+	pll3_sw_clk.parent = &osc_clk;
+
+	/* set ipg_perclk parent */
+	ipg_perclk.parent = &lp_apm_clk;
+	reg = __raw_readl(MXC_CCM_CBCMR);
+	if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
+		ipg_perclk.parent = &ipg_clk;
+	} else {
+		if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
+			ipg_perclk.parent = &main_bus_clk;
+	}
+}
+
+int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
+			unsigned long ckih1, unsigned long ckih2)
+{
+	int i;
+
+	external_low_reference = ckil;
+	external_high_reference = ckih1;
+	ckih2_reference = ckih2;
+	oscillator_reference = osc;
+
+	for (i = 0; i < ARRAY_SIZE(lookups); i++)
+		clkdev_add(&lookups[i]);
+
+	clk_tree_init();
+
+	clk_enable(&cpu_clk);
+	clk_enable(&main_bus_clk);
+
+	/* System timer */
+	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
+		MX51_MXC_INT_GPT);
+	return 0;
+}
diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
new file mode 100644
index 0000000..93f1d5a
--- /dev/null
+++ b/arch/arm/mach-mx5/cpu.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008-2009 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
+ * Version 2 or later@the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * This file contains the CPU initialization code.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+static int __init post_cpu_init(void)
+{
+	unsigned int reg;
+	void __iomem *base;
+
+	if (cpu_is_mx51()) {
+		base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
+		__raw_writel(0x0, base + 0x40);
+		__raw_writel(0x0, base + 0x44);
+		__raw_writel(0x0, base + 0x48);
+		__raw_writel(0x0, base + 0x4C);
+		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+		__raw_writel(reg, base + 0x50);
+
+		base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
+		__raw_writel(0x0, base + 0x40);
+		__raw_writel(0x0, base + 0x44);
+		__raw_writel(0x0, base + 0x48);
+		__raw_writel(0x0, base + 0x4C);
+		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+		__raw_writel(reg, base + 0x50);
+	}
+	return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
new file mode 100644
index 0000000..c776b9a
--- /dev/null
+++ b/arch/arm/mach-mx5/crm_regs.h
@@ -0,0 +1,583 @@
+/*
+ * Copyright 2008-2009 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
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+#define MX51_CCM_BASE		MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
+#define MX51_DPLL1_BASE		MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
+#define MX51_DPLL2_BASE		MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)
+#define MX51_DPLL3_BASE		MX51_IO_ADDRESS(MX51_PLL3_BASE_ADDR)
+#define MX51_CORTEXA8_BASE	MX51_IO_ADDRESS(MX51_ARM_BASE_ADDR)
+#define MX51_GPC_BASE		MX51_IO_ADDRESS(MX51_GPC_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL			0x00
+#define MXC_PLL_DP_CONFIG		0x04
+#define MXC_PLL_DP_OP			0x08
+#define MXC_PLL_DP_MFD			0x0C
+#define MXC_PLL_DP_MFN			0x10
+#define MXC_PLL_DP_MFNMINUS		0x14
+#define MXC_PLL_DP_MFNPLUS		0x18
+#define MXC_PLL_DP_HFS_OP		0x1C
+#define MXC_PLL_DP_HFS_MFD		0x20
+#define MXC_PLL_DP_HFS_MFN		0x24
+#define MXC_PLL_DP_MFN_TOGC		0x28
+#define MXC_PLL_DP_DESTAT		0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL		0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN	0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET	12
+#define MXC_PLL_DP_CTL_ADE		0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV	0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK	(3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET	8
+#define MXC_PLL_DP_CTL_HFSM		0x80
+#define MXC_PLL_DP_CTL_PRE		0x40
+#define MXC_PLL_DP_CTL_UPEN		0x20
+#define MXC_PLL_DP_CTL_RST		0x10
+#define MXC_PLL_DP_CTL_RCP		0x8
+#define MXC_PLL_DP_CTL_PLM		0x4
+#define MXC_PLL_DP_CTL_BRM0		0x2
+#define MXC_PLL_DP_CTL_LRF		0x1
+
+#define MXC_PLL_DP_CONFIG_BIST		0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE	0x4
+#define MXC_PLL_DP_CONFIG_AREN		0x2
+#define MXC_PLL_DP_CONFIG_LDREQ		0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET	4
+#define MXC_PLL_DP_OP_MFI_MASK		(0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET	0
+#define MXC_PLL_DP_OP_PDF_MASK		0xF
+
+#define MXC_PLL_DP_MFD_OFFSET		0
+#define MXC_PLL_DP_MFD_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET		0x0
+#define MXC_PLL_DP_MFN_MASK		0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS	(1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN	(1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET	0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK	0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL	(1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN		0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR		(MX51_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR		(MX51_CCM_BASE + 0x04)
+#define MXC_CCM_CSR		(MX51_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR		(MX51_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR		(MX51_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR		(MX51_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR		(MX51_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1		(MX51_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2		(MX51_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1		(MX51_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR		(MX51_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR		(MX51_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR		(MX51_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCDR		(MX51_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2		(MX51_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3		(MX51_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4		(MX51_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR		(MX51_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR		(MX51_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR		(MX51_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR		(MX51_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR		(MX51_CCM_BASE + 0x54)
+#define MXC_CCM_CISR		(MX51_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR		(MX51_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR		(MX51_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR		(MX51_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0		(MX51_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1		(MX51_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2		(MX51_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3		(MX51_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4		(MX51_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5		(MX51_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6		(MX51_CCM_BASE + 0x80)
+#define MXC_CCM_CMEOR		(MX51_CCM_BASE + 0x84)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN		(1 << 12)
+#define MXC_CCM_CCR_FPM_MULT_MASK	(1 << 11)
+#define MXC_CCM_CCR_CAMP2_EN		(1 << 10)
+#define MXC_CCM_CCR_CAMP1_EN		(1 << 9)
+#define MXC_CCM_CCR_FPM_EN		(1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET	(0)
+#define MXC_CCM_CCR_OSCNT_MASK	(0xFF)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_HSC_HS_MASK	(0x1 << 18)
+#define MXC_CCM_CCDR_IPU_HS_MASK	(0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK	(0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY	(1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE	(1 << 4)
+#define MXC_CCM_CSR_CAMP2_READY	(1 << 3)
+#define MXC_CCM_CSR_CAMP1_READY	(1 << 2)
+#define MXC_CCM_CSR_FPM_READY	(1 << 1)
+#define MXC_CCM_CSR_REF_EN_B	(1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_LP_APM_SEL		(0x1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET	(7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK	(0x3 << 7)
+#define MXC_CCM_CCSR_STEP_SEL_LP_APM	   0
+#define MXC_CCM_CCSR_STEP_SEL_PLL1_BYPASS  1 /* Only when JTAG connected? */
+#define MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED 2
+#define MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED 3
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET	(5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK	(0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET	(3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK	(0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL	(1 << 2) /* 0: pll1_main_clk,
+						    1: step_clk */
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL	(1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL	(1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET	(0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK	(0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_EMI_CLK_SEL		(0x1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL		(0x1 << 25)
+#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET		(30)
+#define MXC_CCM_CBCDR_DDR_HF_SEL		(0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET		(27)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK		(0x7 << 27)
+#define MXC_CCM_CBCDR_EMI_PODF_OFFSET		(22)
+#define MXC_CCM_CBCDR_EMI_PODF_MASK		(0x7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET		(19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK		(0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET		(16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK		(0x7 << 16)
+#define MXC_CCM_CBCDR_NFC_PODF_OFFSET		(13)
+#define MXC_CCM_CBCDR_NFC_PODF_MASK		(0x7 << 13)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET		(10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK		(0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET		(8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK		(0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET	(6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK		(0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET	(3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK		(0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET	(0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET	(14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK	(0x3 << 14)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET	(12)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK	(0x3 << 12)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET	(10)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK		(0x3 << 10)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET	(8)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK	(0x3 << 8)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET	(6)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK	(0x3 << 6)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET	(4)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK		(0x3 << 4)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET	(14)
+#define MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK	(0x3 << 14)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL	(0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL	(0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET		(30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK		(0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET		(28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK		(0x3 << 28)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET		(26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL			(0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET		(24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK		(0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET		(22)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK		(0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET	(20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK	(0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL			(0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL			(0x1 << 18)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET	(16)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK	(0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET		(14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK		(0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET		(12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK		(0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL			(0x1 << 11)
+#define MXC_CCM_CSCMR1_VPU_RCLK_SEL			(0x1 << 10)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET		(8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK		(0x3 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL			(0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL			(0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET		(4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK		(0x3 << 4)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET		(2)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK		(0x3 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL		(0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL		(0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET(n)		(26+n*3)
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK(n)		(0x7 << (26+n*3))
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET		(24)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK		(0x3 << 24)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET		(22)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK		(0x3 << 22)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET		(20)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK			(0x3 << 20)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET		(18)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK		(0x3 << 18)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET		(16)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK		(0x3 << 16)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET		(14)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK		(0x3 << 14)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET		(12)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK		(0x3 << 12)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET		(10)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK			(0x3 << 10)
+#define MXC_CCM_CSCMR2_SLIMBUS_COM			(0x1 << 9)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET		(6)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK		(0x7 << 6)
+#define MXC_CCM_CSCMR2_SPDIF1_COM			(1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM			(1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET		(2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK		(0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET		(0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK		(0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET	(22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK	(0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET	(19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK	(0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET	(16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK	(0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET		(14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK		(0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET	(11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK	(0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET		(8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK		(0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET		(6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK		(0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET		(3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK		(0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET		(22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK		(0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET		(16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK		(0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK		(0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET		(22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK		(0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET		(16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK		(0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET		(28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK			(0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET		(25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK		(0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET		(19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK		(0x3F << 19)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK			(0x7 << 6)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET		(3)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK			(0x7 << 3)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET		(0)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK			(0x7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET		(12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK		(0x7 << 12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET		(6)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK		(0x3F << 6)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET		(3)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK		(0x7 << 3)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK		(0x7)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET		(25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK		(0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET		(19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK		(0x3F << 19)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET		(16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET		(9)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET		(6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET		(0)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET	(16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK		(0x7 << 16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET	(9)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK		(0x3F << 9)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET	(6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK		(0x7 << 6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET	(0)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK		(0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY			(1 << 16)
+#define MXC_CCM_CDHIPR_DDR_HF_CLK_SEL_BUSY		(1 << 8)
+#define MXC_CCM_CDHIPR_DDR_PODF_BUSY			(1 << 7)
+#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY			(1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY		(1 << 5)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY	(1 << 4)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY			(1 << 3)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY			(1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY			(1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY			(1 << 0)
+
+/* Define the bits in register CDCR */
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER		(0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET	(0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK		(0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS		(0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS		(0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS		(0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS	(0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS		(0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS		(0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS	(0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS	(0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN		(0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET		(9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK		(0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY			(0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC		(0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS			(0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM	(0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET	(3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK		(0x3 << 3)
+#define MXC_CCM_CLPCR_LPM_OFFSET		(0)
+#define MXC_CCM_CLPCR_LPM_MASK			(0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED			(0x1 << 25)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED	(0x1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED			(0x1 << 20)
+#define MXC_CCM_CISR_EMI_PODF_LOADED			(0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED			(0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED			(0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED			(0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY				(0x1 << 6)
+#define MXC_CCM_CISR_CKIH2_READY			(0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY				(0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY				(0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3				(0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2				(0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1				(0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED		(0x1 << 25)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED	(0x1 << 21)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED		(0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED		(0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED		(0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED		(0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED		(0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY			(0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY			(0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY			(0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3			(0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2			(0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1			(0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET			(0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET			(21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK			(0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET			(16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK			(0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN				(0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET			(4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK			(0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET			(0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK			(0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE		(0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL				(0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET		(0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK		(0x7)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGRx_CG_MASK				0x3
+#define MXC_CCM_CCGRx_MOD_OFF				0x0
+#define MXC_CCM_CCGRx_MOD_ON				0x3
+#define MXC_CCM_CCGRx_MOD_IDLE				0x1
+
+#define MXC_CCM_CCGRx_CG15_MASK				(0x3 << 30)
+#define MXC_CCM_CCGRx_CG14_MASK				(0x3 << 28)
+#define MXC_CCM_CCGRx_CG13_MASK				(0x3 << 26)
+#define MXC_CCM_CCGRx_CG12_MASK				(0x3 << 24)
+#define MXC_CCM_CCGRx_CG11_MASK				(0x3 << 22)
+#define MXC_CCM_CCGRx_CG10_MASK				(0x3 << 20)
+#define MXC_CCM_CCGRx_CG9_MASK				(0x3 << 18)
+#define MXC_CCM_CCGRx_CG8_MASK				(0x3 << 16)
+#define MXC_CCM_CCGRx_CG5_MASK				(0x3 << 10)
+#define MXC_CCM_CCGRx_CG4_MASK				(0x3 << 8)
+#define MXC_CCM_CCGRx_CG3_MASK				(0x3 << 6)
+#define MXC_CCM_CCGRx_CG2_MASK				(0x3 << 4)
+#define MXC_CCM_CCGRx_CG1_MASK				(0x3 << 2)
+#define MXC_CCM_CCGRx_CG0_MASK				(0x3 << 0)
+
+#define MXC_CCM_CCGRx_CG15_OFFSET			30
+#define MXC_CCM_CCGRx_CG14_OFFSET			28
+#define MXC_CCM_CCGRx_CG13_OFFSET			26
+#define MXC_CCM_CCGRx_CG12_OFFSET			24
+#define MXC_CCM_CCGRx_CG11_OFFSET			22
+#define MXC_CCM_CCGRx_CG10_OFFSET			20
+#define MXC_CCM_CCGRx_CG9_OFFSET			18
+#define MXC_CCM_CCGRx_CG8_OFFSET			16
+#define MXC_CCM_CCGRx_CG7_OFFSET			14
+#define MXC_CCM_CCGRx_CG6_OFFSET			12
+#define MXC_CCM_CCGRx_CG5_OFFSET			10
+#define MXC_CCM_CCGRx_CG4_OFFSET			8
+#define MXC_CCM_CCGRx_CG3_OFFSET			6
+#define MXC_CCM_CCGRx_CG2_OFFSET			4
+#define MXC_CCM_CCGRx_CG1_OFFSET			2
+#define MXC_CCM_CCGRx_CG0_OFFSET			0
+
+#define MXC_DPTC_LP_BASE	(MX51_GPC_BASE + 0x80)
+#define MXC_DPTC_GP_BASE	(MX51_GPC_BASE + 0x100)
+#define MXC_DVFS_CORE_BASE	(MX51_GPC_BASE + 0x180)
+#define MXC_DPTC_PER_BASE	(MX51_GPC_BASE + 0x1C0)
+#define MXC_PGC_IPU_BASE	(MX51_GPC_BASE + 0x220)
+#define MXC_PGC_VPU_BASE	(MX51_GPC_BASE + 0x240)
+#define MXC_PGC_GPU_BASE	(MX51_GPC_BASE + 0x260)
+#define MXC_SRPG_NEON_BASE	(MX51_GPC_BASE + 0x280)
+#define MXC_SRPG_ARM_BASE	(MX51_GPC_BASE + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE	(MX51_GPC_BASE + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE	(MX51_GPC_BASE + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE	(MX51_GPC_BASE + 0x2E0)
+#define MXC_SRPG_EMI_BASE	(MX51_GPC_BASE + 0x300)
+
+/* CORTEXA8 platform */
+#define MXC_CORTEXA8_PLAT_PVID		(MX51_CORTEXA8_BASE + 0x0)
+#define MXC_CORTEXA8_PLAT_GPC		(MX51_CORTEXA8_BASE + 0x4)
+#define MXC_CORTEXA8_PLAT_PIC		(MX51_CORTEXA8_BASE + 0x8)
+#define MXC_CORTEXA8_PLAT_LPC		(MX51_CORTEXA8_BASE + 0xC)
+#define MXC_CORTEXA8_PLAT_NEON_LPC	(MX51_CORTEXA8_BASE + 0x10)
+#define MXC_CORTEXA8_PLAT_ICGC		(MX51_CORTEXA8_BASE + 0x14)
+#define MXC_CORTEXA8_PLAT_AMC		(MX51_CORTEXA8_BASE + 0x18)
+#define MXC_CORTEXA8_PLAT_NMC		(MX51_CORTEXA8_BASE + 0x20)
+#define MXC_CORTEXA8_PLAT_NMS		(MX51_CORTEXA8_BASE + 0x24)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS		(MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN		(MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1		(MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0		(MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0		(MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1		(MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT		(MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC		(MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR		(MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0		(MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1		(MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0		(MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1		(MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 		(MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 		(MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 		(MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 		(MXC_DVFS_CORE_BASE + 0x40)
+
+/* GPC */
+#define MXC_GPC_CNTR		(MX51_GPC_BASE + 0x0)
+#define MXC_GPC_PGR		(MX51_GPC_BASE + 0x4)
+#define MXC_GPC_VCR		(MX51_GPC_BASE + 0x8)
+#define MXC_GPC_ALL_PU		(MX51_GPC_BASE + 0xC)
+#define MXC_GPC_NEON		(MX51_GPC_BASE + 0x10)
+#define MXC_GPC_PGR_ARMPG_OFFSET	8
+#define MXC_GPC_PGR_ARMPG_MASK		(3 << 8)
+
+/* PGC */
+#define MXC_PGC_IPU_PGCR	(MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR	(MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR	(MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR	(MXC_PGC_VPU_BASE + 0xC)
+#define MXC_PGC_GPU_PGCR	(MXC_PGC_GPU_BASE + 0x0)
+#define MXC_PGC_GPU_PGSR	(MXC_PGC_GPU_BASE + 0xC)
+
+#define MXC_PGCR_PCR		1
+#define MXC_SRPGCR_PCR		1
+#define MXC_EMPGCR_PCR		1
+#define MXC_PGSR_PSR		1
+
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM	(1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM	(1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR	(MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR	(MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR	(MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR	(MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR	(MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR	(MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR	(MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR	(MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR	(MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR	(MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR	(MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR	(MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR		(MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR		(MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR		(MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR	(MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR	(MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR	(MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
new file mode 100644
index 0000000..55eb089
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+
+static struct resource uart0[] = {
+	{
+		.start = MX51_UART1_BASE_ADDR,
+		.end = MX51_UART1_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART1,
+		.end = MX51_MXC_INT_UART1,
+		.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 = MX51_UART2_BASE_ADDR,
+		.end = MX51_UART2_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART2,
+		.end = MX51_MXC_INT_UART2,
+		.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 = MX51_UART3_BASE_ADDR,
+		.end = MX51_UART3_BASE_ADDR + 0x0B5,
+		.flags = IORESOURCE_MEM,
+	}, {
+		.start = MX51_MXC_INT_UART3,
+		.end = MX51_MXC_INT_UART3,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_uart_device2 = {
+	.name = "imx-uart",
+	.id = 2,
+	.resource = uart2,
+	.num_resources = ARRAY_SIZE(uart2),
+};
+
+static struct resource mxc_fec_resources[] = {
+	{
+		.start	= MX51_MXC_FEC_BASE_ADDR,
+		.end	= MX51_MXC_FEC_BASE_ADDR + 0xfff,
+		.flags	= IORESOURCE_MEM,
+	}, {
+		.start	= MX51_MXC_INT_FEC,
+		.end	= MX51_MXC_INT_FEC,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+struct platform_device mxc_fec_device = {
+	.name = "fec",
+	.id = 0,
+	.num_resources = ARRAY_SIZE(mxc_fec_resources),
+	.resource = mxc_fec_resources,
+};
+
+/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
+int __init mxc_register_gpios(void)
+{
+	return 0;
+}
diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
new file mode 100644
index 0000000..f339ab8
--- /dev/null
+++ b/arch/arm/mach-mx5/devices.h
@@ -0,0 +1,4 @@
+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;
diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
new file mode 100644
index 0000000..d66c31a
--- /dev/null
+++ b/arch/arm/mach-mx5/mm.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008-2009 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
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * Create static mapping between physical to virtual memory.
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-v3.h>
+
+/*
+ * Define the MX51 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+	{
+	 .virtual = MX51_IRAM_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
+	 .length = MX51_IRAM_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_DEBUG_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
+	 .length = MX51_DEBUG_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_TZIC_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
+	 .length = MX51_TZIC_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
+	 .length = MX51_AIPS1_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_SPBA0_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
+	 .length = MX51_SPBA0_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_AIPS2_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
+	 .length = MX51_AIPS2_SIZE,
+	 .type = MT_DEVICE},
+	{
+	 .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
+	 .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
+	 .length = MX51_NFC_AXI_SIZE,
+	 .type = MT_DEVICE},
+};
+
+/*
+ * 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 mx51_map_io(void)
+{
+	u32 tzic_addr;
+
+	if (mx51_revision() < MX51_CHIP_REV_2_0)
+		tzic_addr = 0x8FFFC000;
+	else
+		tzic_addr = 0xE0003000;
+	mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
+
+	mxc_set_cpu_type(MXC_CPU_MX51);
+	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
+	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
+	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
+
+void __init mx51_init_irq(void)
+{
+	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
+}
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 5250a3f..0a25576 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -30,6 +30,7 @@ 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 mx51_init_irq(void);
 extern void mxc91231_init_irq(void);
 extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
 extern int mx1_clocks_init(unsigned long fref);
diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
index 9fe7300..9d41bfd 100644
--- a/arch/arm/plat-mxc/include/mach/debug-macro.S
+++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
@@ -49,8 +49,8 @@
 #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
 #endif
 #include <mach/mx51.h>
-#define UART_PADDR	UART1_BASE_ADDR
-#define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+#define UART_PADDR	MX51_UART1_BASE_ADDR
+#define UART_VADDR	MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
 #endif
 
 #ifdef CONFIG_ARCH_MXC91231
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
new file mode 100644
index 0000000..14df0f5
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
@@ -0,0 +1,340 @@
+/*
+ * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com> 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
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __MACH_IOMUX_MX51_H__
+#define __MACH_IOMUX_MX51_H__
+
+#include <mach/iomux-v3.h>
+
+/*
+ * various IOMUX alternate output functions (1-7)
+ */
+typedef enum iomux_config {
+	IOMUX_CONFIG_ALT0,
+	IOMUX_CONFIG_ALT1,
+	IOMUX_CONFIG_ALT2,
+	IOMUX_CONFIG_ALT3,
+	IOMUX_CONFIG_ALT4,
+	IOMUX_CONFIG_ALT5,
+	IOMUX_CONFIG_ALT6,
+	IOMUX_CONFIG_ALT7,
+	IOMUX_CONFIG_GPIO,	/* added to help user use GPIO mode */
+	IOMUX_CONFIG_SION = 0x1 << 4,	/* LOOPBACK:MUX SION bit */
+} iomux_pin_cfg_t;
+
+/* Pad control groupings */
+#define MX51_UART1_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
+				PAD_CTL_DSE_HIGH)
+#define MX51_UART2_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
+				PAD_CTL_SRE_FAST)
+#define MX51_UART3_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
+				PAD_CTL_SRE_FAST)
+
+/*
+ * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named
+ * GPIO_<unit>_<num> see also iomux-v3.h
+ */
+
+/* REVISIT: This was converted using scripts from existing Freescale code to
+ * this form used upstream. Need to verify the name format.
+ */
+
+/*						PAD      MUX   ALT INPSE PATH PADCTRL */
+
+
+/* UART1 */
+#define MX51_BABBAGE_PAD_UART1_RXD__UART1_RXD	\
+	IOMUX_PAD(0x618, 0x228,	IOMUX_CONFIG_ALT0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_BABBAGE_PAD_UART1_TXD__UART1_TXD	\
+	IOMUX_PAD(0x61C, 0x22C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
+#define MX51_BABBAGE_PAD_UART1_RTS__UART1_RTS	\
+	IOMUX_PAD(0x620, 0x230, IOMUX_CONFIG_ALT0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
+#define MX51_BABBAGE_PAD_UART1_CTS__UART1_CTS	\
+	IOMUX_PAD(0x624, 0x234, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL)
+
+/* UART2 */
+#define MX51_BABBAGE_PAD_UART2_RXD__UART2_RXD	IOMUX_PAD(0x628, 0x238, IOMUX_CONFIG_ALT0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
+#define MX51_BABBAGE_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x62C, 0x23C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART2_PAD_CTRL)
+
+/* UART3 */
+#define MX51_BABBAGE_PAD_EIM_D25__UART3_RXD	IOMUX_PAD(0x414, 0x080, IOMUX_CONFIG_ALT3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
+#define MX51_BABBAGE_PAD_EIM_D26__UART3_TXD	IOMUX_PAD(0x418, 0x084, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_BABBAGE_PAD_EIM_D27__UART3_RTS	IOMUX_PAD(0x41c, 0x088, IOMUX_CONFIG_ALT3, 0x9f0, 0, MX51_UART3_PAD_CTRL)
+#define MX51_BABBAGE_PAD_EIM_D24__UART3_CTS	IOMUX_PAD(0x410, 0x07c, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
+
+#define MX51_BABBAGE_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))
+
+/* EIM */
+#define MX51_PAD_EIM_DA0__EIM_DA0	IOMUX_PAD(0x7a8, 0x01c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA1__EIM_DA1	IOMUX_PAD(0x7a8, 0x020, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA2__EIM_DA2	IOMUX_PAD(0x7a8, 0x024, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA3__EIM_DA3	IOMUX_PAD(0x7a8, 0x028, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA4__EIM_DA4	IOMUX_PAD(0x7ac, 0x02c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA5__EIM_DA5	IOMUX_PAD(0x7ac, 0x030, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA6__EIM_DA6	IOMUX_PAD(0x7ac, 0x034, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA7__EIM_DA7	IOMUX_PAD(0x7ac, 0x038, 0, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_EIM_DA8__EIM_DA8	IOMUX_PAD(0x7b0, 0x03c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA9__EIM_DA9	IOMUX_PAD(0x7b0, 0x040, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA10__EIM_DA10	IOMUX_PAD(0x7b0, 0x044, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA11__EIM_DA11	IOMUX_PAD(0x7b0, 0x048, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA12__EIM_DA12	IOMUX_PAD(0x7bc, 0x04c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA13__EIM_DA13	IOMUX_PAD(0x7bc, 0x050, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA14__EIM_DA14	IOMUX_PAD(0x7bc, 0x054, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_DA15__EIM_DA15	IOMUX_PAD(0x7bc, 0x058, 0, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_0__EIM_D16	IOMUX_PAD(0x3f0, 0x05c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_1__EIM_D17	IOMUX_PAD(0x3f4, 0x060, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_2__EIM_D18	IOMUX_PAD(0x3f8, 0x064, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_3__EIM_D19	IOMUX_PAD(0x3fc, 0x068, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_4__EIM_D20	IOMUX_PAD(0x400, 0x06c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_5__EIM_D21	IOMUX_PAD(0x404, 0x070, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_6__EIM_D22	IOMUX_PAD(0x408, 0x074, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_7__EIM_D23	IOMUX_PAD(0x40c, 0x078, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_8__EIM_D24	IOMUX_PAD(0x410, 0x07c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D25__EIM_D25	IOMUX_PAD(0x414, 0x080, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D26__EIM_D26	IOMUX_PAD(0x418, 0x084, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_9__EIM_D27	IOMUX_PAD(0x41c, 0x088, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D28__EIM_D28	IOMUX_PAD(0x420, 0x08c, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D29__EIM_D29	IOMUX_PAD(0x424, 0x090, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D30__EIM_D30	IOMUX_PAD(0x428, 0x094, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_D31__EIM_D31	IOMUX_PAD(0x42c, 0x09c, 0, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_10__EIM_A16	IOMUX_PAD(0x430, 0x09c, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_11__EIM_A17	IOMUX_PAD(0x434, 0x0a0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_12__EIM_A18	IOMUX_PAD(0x438, 0x0a4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_13__EIM_A19	IOMUX_PAD(0x43c, 0x0a8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_14__EIM_A20	IOMUX_PAD(0x440, 0x0ac, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_15__EIM_A21	IOMUX_PAD(0x444, 0x0b0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_16__EIM_A22	IOMUX_PAD(0x448, 0x0b4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_17__EIM_A23	IOMUX_PAD(0x44c, 0x0b8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_18__EIM_A24	IOMUX_PAD(0x450, 0x0bc, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_19__EIM_A25	IOMUX_PAD(0x454, 0x0c0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_20__EIM_A26	IOMUX_PAD(0x458, 0x0c4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_21__EIM_A27	IOMUX_PAD(0x45c, 0x0c8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB0__EIM_EB0	IOMUX_PAD(0x460, 0x0cc, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_EIM_EB1__EIM_EB1	IOMUX_PAD(0x464, 0x0d0, 0, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_22__EIM_EB2	IOMUX_PAD(0x468, 0x0d4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_23__EIM_EB3	IOMUX_PAD(0x46c, 0x0d8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_2_24__EIM_OE	IOMUX_PAD(0x470, 0x0dc, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_25__EIM_CS0	IOMUX_PAD(0x474, 0x0e0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_26__EIM_CS1	IOMUX_PAD(0x478, 0x0e4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_27__EIM_CS2	IOMUX_PAD(0x47c, 0x0e8, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_28__EIM_CS3	IOMUX_PAD(0x480, 0x0ec, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_29__EIM_CS4	IOMUX_PAD(0x484, 0x0f0, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_30__EIM_CS5	IOMUX_PAD(0x488, 0x0f4, 1, 0x0,   0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_2_31__EIM_DTACK	IOMUX_PAD(0x48c, 0x0f8, 1, 0x0,   0, NO_PAD_CTRL)
+
+#define MX51_PAD_GPIO_3_1__EIM_LBA	IOMUX_PAD(0x494, 0xFC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_2__EIM_CRE	IOMUX_PAD(0x4A0, 0x100, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DRAM_CS1__DRAM_CS1	IOMUX_PAD(0x4D0, 0x104, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_3__NANDF_WE_B	IOMUX_PAD(0x4E4, 0x108, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_4__NANDF_RE_B	IOMUX_PAD(0x4E8, 0x10C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_5__NANDF_ALE	IOMUX_PAD(0x4EC, 0x110, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_6__NANDF_CLE	IOMUX_PAD(0x4F0, 0x114, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_7__NANDF_WP_B	IOMUX_PAD(0x4F4, 0x118, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_8__NANDF_RB0	IOMUX_PAD(0x4F8, 0x11C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_9__NANDF_RB1	IOMUX_PAD(0x4FC, 0x120, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_10__NANDF_RB2	IOMUX_PAD(0x500, 0x124, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_11__NANDF_RB3	IOMUX_PAD(0x504, 0x128, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_12__GPIO_NAND	IOMUX_PAD(0x514, 0x12C, 3, 0x0, 0, NO_PAD_CTRL)
+/* REVISIT: Not sure of these values
+
+  #define MX51_PAD_GPIO_1___NANDF_RB4	IOMUX_PAD(, , , 0x0, 0, NO_PAD_CTRL)
+  #define MX51_PAD_GPIO_3_13__NANDF_RB5	IOMUX_PAD(0x5D8, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+  #define MX51_PAD_GPIO_3_15__NANDF_RB7	IOMUX_PAD(0x5E0, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+*/
+#define MX51_PAD_GPIO_3_14__NANDF_RB6	IOMUX_PAD(0x5DC, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_16__NANDF_CS0	IOMUX_PAD(0x518, 0x130, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_17__NANDF_CS1	IOMUX_PAD(0x51C, 0x134, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_18__NANDF_CS2	IOMUX_PAD(0x520, 0x138, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_19__NANDF_CS3	IOMUX_PAD(0x524, 0x13C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_20__NANDF_CS4	IOMUX_PAD(0x528, 0x140, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_21__NANDF_CS5	IOMUX_PAD(0x52C, 0x144, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_22__NANDF_CS6	IOMUX_PAD(0x530, 0x148, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_23__NANDF_CS7	IOMUX_PAD(0x534, 0x14C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_24__NANDF_RDY_INT	IOMUX_PAD(0x538, 0x150, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_25__NANDF_D15	IOMUX_PAD(0x53C, 0x154, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_26__NANDF_D14	IOMUX_PAD(0x540, 0x158, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_27__NANDF_D13	IOMUX_PAD(0x544, 0x15C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_28__NANDF_D12	IOMUX_PAD(0x548, 0x160, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_29__NANDF_D11	IOMUX_PAD(0x54C, 0x164, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_30__NANDF_D10	IOMUX_PAD(0x550, 0x168, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_31__NANDF_D9	IOMUX_PAD(0x554, 0x16C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_0__NANDF_D8	IOMUX_PAD(0x558, 0x170, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_1__NANDF_D7	IOMUX_PAD(0x55C, 0x174, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_2__NANDF_D6	IOMUX_PAD(0x560, 0x178, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_3__NANDF_D5	IOMUX_PAD(0x564, 0x17C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_4__NANDF_D4	IOMUX_PAD(0x568, 0x180, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_5__NANDF_D3	IOMUX_PAD(0x56C, 0x184, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_6__NANDF_D2	IOMUX_PAD(0x570, 0x188, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_7__NANDF_D1	IOMUX_PAD(0x574, 0x18C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_8__NANDF_D0	IOMUX_PAD(0x578, 0x190, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_12__CSI1_D8	IOMUX_PAD(0x57C, 0x194, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_13__CSI1_D9	IOMUX_PAD(0x580, 0x198, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D10__CSI1_D10	IOMUX_PAD(0x584, 0x19C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D11__CSI1_D11	IOMUX_PAD(0x588, 0x1A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D12__CSI1_D12	IOMUX_PAD(0x58C, 0x1A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D13__CSI1_D13	IOMUX_PAD(0x590, 0x1A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D14__CSI1_D14	IOMUX_PAD(0x594, 0x1AC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D15__CSI1_D15	IOMUX_PAD(0x598, 0x1B0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D16__CSI1_D16	IOMUX_PAD(0x59C, 0x1B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D17__CSI1_D17	IOMUX_PAD(0x5A0, 0x1B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D18__CSI1_D18	IOMUX_PAD(0x5A4, 0x1BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_D19__CSI1_D19	IOMUX_PAD(0x5A8, 0x1C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_VSYNC__CSI1_VSYNC	IOMUX_PAD(0x5AC, 0x1C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_HSYNC__CSI1_HSYNC	IOMUX_PAD(0x5B0, 0x1C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PIXCLK__CSI1_PIXCLK	IOMUX_PAD(0x5B4, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_MCLK__CSI1_MCLK	IOMUX_PAD(0x5B8, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI1_PKE0__CSI1_PKE0	IOMUX_PAD(0x860, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_9__CSI2_D12	IOMUX_PAD(0x5BC, 0x1CC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_10__CSI2_D13	IOMUX_PAD(0x5C0, 0x1D0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D14	IOMUX_PAD(0x5C4, 0x1D4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D15	IOMUX_PAD(0x5C8, 0x1D8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D16	IOMUX_PAD(0x5CC, 0x1DC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D17	IOMUX_PAD(0x5D0, 0x1E0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_11__CSI2_D18	IOMUX_PAD(0x5D4, 0x1E4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_12__CSI2_D19	IOMUX_PAD(0x5D8, 0x1E8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_13__CSI2_VSYNC	IOMUX_PAD(0x5DC, 0x1EC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_14__CSI2_HSYNC	IOMUX_PAD(0x5E0, 0x1F0, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_15__CSI2_PIXCLK	IOMUX_PAD(0x5E4, 0x1F4, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_CSI2_PKE0__CSI2_PKE0	IOMUX_PAD(0x81C, 0x0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_16__I2C1_CLK	IOMUX_PAD(0x5E8, 0x1F8, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_17__I2C1_DAT	IOMUX_PAD(0x5EC, 0x1FC, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_18__AUD3_BB_TXD	IOMUX_PAD(0x5F0, 0x200, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_19__AUD3_BB_RXD	IOMUX_PAD(0x5F4, 0x204, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_20__AUD3_BB_CK	IOMUX_PAD(0x5F8, 0x208, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_21__AUD3_BB_FS	IOMUX_PAD(0x5FC, 0x20C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_22__CSPI1_MOSI	IOMUX_PAD(0x600, 0x210, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_23__CSPI1_MISO	IOMUX_PAD(0x604, 0x214, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_24__CSPI1_SS0	IOMUX_PAD(0x608, 0x218, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_25__CSPI1_SS1	IOMUX_PAD(0x60C, 0x21C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_26__CSPI1_RDY	IOMUX_PAD(0x610, 0x220, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_27__CSPI1_SCLK	IOMUX_PAD(0x614, 0x224, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_28__UART1_RXD	IOMUX_PAD(0x618, 0x228, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_29__UART1_TXD	IOMUX_PAD(0x61C, 0x22C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_30__UART1_RTS	IOMUX_PAD(0x620, 0x230, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_4_31__UART1_CTS	IOMUX_PAD(0x624, 0x234, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_20__UART2_RXD	IOMUX_PAD(0x628, 0x238, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_21__UART2_TXD	IOMUX_PAD(0x62C, 0x23C, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_22__UART3_RXD	IOMUX_PAD(0x630, 0x240, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_23__UART3_TXD	IOMUX_PAD(0x634, 0x244, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_24__OWIRE_LINE	IOMUX_PAD(0x638, 0x248, 3, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW0__KEY_ROW0	IOMUX_PAD(0x63C, 0x24C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW1__KEY_ROW1	IOMUX_PAD(0x640, 0x250, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW2__KEY_ROW2	IOMUX_PAD(0x644, 0x254, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_ROW3__KEY_ROW3	IOMUX_PAD(0x648, 0x258, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL0__KEY_COL0	IOMUX_PAD(0x64C, 0x25C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL1__KEY_COL1	IOMUX_PAD(0x650, 0x260, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL2__KEY_COL2	IOMUX_PAD(0x654, 0x264, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL3__KEY_COL3	IOMUX_PAD(0x658, 0x268, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_COL4__KEY_COL4	IOMUX_PAD(0x65C, 0x26C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_KEY_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_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)
+#define MX51_PAD_GPIO_3_3__DI1_D0_CS	IOMUX_PAD(0x6B4, 0x2B4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_4__DI1_D1_CS	IOMUX_PAD(0x6B8, 0x2B8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_5__DISPB2_SER_DIN	IOMUX_PAD(0x6BC, 0x2BC, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_6__DISPB2_SER_DIO	IOMUX_PAD(0x6C0, 0x2C0, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_7__DISPB2_SER_CLK	IOMUX_PAD(0x6C4, 0x2C4, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_3_8__DISPB2_SER_RS	IOMUX_PAD(0x6C8, 0x2C8, 4, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT0__DISP1_DAT0	IOMUX_PAD(0x6CC, 0x2CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT1__DISP1_DAT1	IOMUX_PAD(0x6D0, 0x2D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT2__DISP1_DAT2	IOMUX_PAD(0x6D4, 0x2D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT3__DISP1_DAT3	IOMUX_PAD(0x6D8, 0x2D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT4__DISP1_DAT4	IOMUX_PAD(0x6DC, 0x2DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT5__DISP1_DAT5	IOMUX_PAD(0x6E0, 0x2E0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT6__DISP1_DAT6	IOMUX_PAD(0x6E4, 0x2E4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT7__DISP1_DAT7	IOMUX_PAD(0x6E8, 0x2E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT8__DISP1_DAT8	IOMUX_PAD(0x6EC, 0x2EC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT9__DISP1_DAT9	IOMUX_PAD(0x6F0, 0x2F0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT10__DISP1_DAT10	IOMUX_PAD(0x6F4, 0x2F4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT11__DISP1_DAT11	IOMUX_PAD(0x6F8, 0x2F8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT12__DISP1_DAT12	IOMUX_PAD(0x6FC, 0x2FC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT13__DISP1_DAT13	IOMUX_PAD(0x700, 0x300, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT14__DISP1_DAT14	IOMUX_PAD(0x704, 0x304, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT15__DISP1_DAT15	IOMUX_PAD(0x708, 0x308, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT16__DISP1_DAT16	IOMUX_PAD(0x70C, 0x30C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT17__DISP1_DAT17	IOMUX_PAD(0x710, 0x310, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT18__DISP1_DAT18	IOMUX_PAD(0x714, 0x314, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT19__DISP1_DAT19	IOMUX_PAD(0x718, 0x318, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT20__DISP1_DAT20	IOMUX_PAD(0x71C, 0x31C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT21__DISP1_DAT21	IOMUX_PAD(0x720, 0x320, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT22__DISP1_DAT22	IOMUX_PAD(0x724, 0x324, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP1_DAT23__DISP1_DAT23	IOMUX_PAD(0x728, 0x328, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN3__DI1_PIN3	IOMUX_PAD(0x72C, 0x32C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI1_PIN2__DI1_PIN2	IOMUX_PAD(0x734, 0x330, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP1__DI_GP1	IOMUX_PAD(0x73C, 0x334, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP2__DI_GP2	IOMUX_PAD(0x740, 0x338, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP3__DI_GP3	IOMUX_PAD(0x744, 0x33C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN4__DI2_PIN4	IOMUX_PAD(0x748, 0x340, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN2__DI2_PIN2	IOMUX_PAD(0x74C, 0x344, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_PIN3__DI2_PIN3	IOMUX_PAD(0x750, 0x348, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI2_DISP_CLK__DI2_DISP_CLK	IOMUX_PAD(0x754, 0x34C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DI_GP4__DI_GP4	IOMUX_PAD(0x758, 0x350, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT0__DISP2_DAT0	IOMUX_PAD(0x75C, 0x354, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT1__DISP2_DAT1	IOMUX_PAD(0x760, 0x358, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT2__DISP2_DAT2	IOMUX_PAD(0x764, 0x35C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT3__DISP2_DAT3	IOMUX_PAD(0x768, 0x360, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT4__DISP2_DAT4	IOMUX_PAD(0x76C, 0x364, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT5__DISP2_DAT5	IOMUX_PAD(0x770, 0x368, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_19__DISP2_DAT6	IOMUX_PAD(0x774, 0x36C, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_29__DISP2_DAT7	IOMUX_PAD(0x778, 0x370, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_30__DISP2_DAT8	IOMUX_PAD(0x77C, 0x374, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_31__DISP2_DAT9	IOMUX_PAD(0x780, 0x378, 5, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT10__DISP2_DAT10	IOMUX_PAD(0x784, 0x37C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT11__DISP2_DAT11	IOMUX_PAD(0x788, 0x380, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT12__DISP2_DAT12	IOMUX_PAD(0x78C, 0x384, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT13__DISP2_DAT13	IOMUX_PAD(0x790, 0x388, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT14__DISP2_DAT14	IOMUX_PAD(0x794, 0x38C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_DISP2_DAT15__DISP2_DAT15	IOMUX_PAD(0x798, 0x390, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CMD__SD1_CMD	IOMUX_PAD(0x79C, 0x394, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_CLK__SD1_CLK	IOMUX_PAD(0x7A0, 0x398, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA0__SD1_DATA0	IOMUX_PAD(0x7A4, 0x39C, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA1__SD1_DATA1	IOMUX_PAD(0x7A8, 0x3A0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA2__SD1_DATA2	IOMUX_PAD(0x7AC, 0x3A4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD1_DATA3__SD1_DATA3	IOMUX_PAD(0x7B0, 0x3A8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_0__GPIO1_0	IOMUX_PAD(0x7B4, 0x3AC, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_1__GPIO1_1	IOMUX_PAD(0x7B8, 0x3B0, 1, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CMD__SD2_CMD	IOMUX_PAD(0x7BC, 0x3B4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_CLK__SD2_CLK	IOMUX_PAD(0x7C0, 0x3B8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA0__SD2_DATA0	IOMUX_PAD(0x7C4, 0x3BC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA1__SD2_DATA1	IOMUX_PAD(0x7C8, 0x3C0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA2__SD2_DATA2	IOMUX_PAD(0x7CC, 0x3C4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_SD2_DATA3__SD2_DATA3	IOMUX_PAD(0x7D0, 0x3C8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_2__GPIO1_2	IOMUX_PAD(0x7D4, 0x3CC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_3__GPIO1_3	IOMUX_PAD(0x7D8, 0x3D0, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_PMIC_INT_REQ__PMIC_INT_REQ	IOMUX_PAD(0x7FC, 0x3D4, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_4__GPIO1_4	IOMUX_PAD(0x804, 0x3D8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_5__GPIO1_5	IOMUX_PAD(0x808, 0x3DC, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_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_8__GPIO1_8	IOMUX_PAD(0x814, 0x3E8, 0, 0x0, 0, NO_PAD_CTRL)
+#define MX51_PAD_GPIO_1_9__GPIO1_9	IOMUX_PAD(0x818, 0x3EC, 0, 0x0, 0, NO_PAD_CTRL)
+
+#endif /* __MACH_IOMUX_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
new file mode 100644
index 0000000..771532b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -0,0 +1,454 @@
+#ifndef __ASM_ARCH_MXC_MX51_H__
+#define __ASM_ARCH_MXC_MX51_H__
+
+/*
+ * MX51 memory map:
+ *
+ *
+ * Virt		Phys		Size	What
+ * ---------------------------------------------------------------------------
+ * FA3E0000	1FFE0000	128K	IRAM (SCCv2 RAM)
+ *         	30000000	256M	GPU
+ *         	40000000	512M	IPU
+ * FA200000	60000000	1M	DEBUG
+ * FB100000	70000000	1M	SPBA 0
+ * FB000000	73F00000	1M	AIPS 1
+ * FB200000	83F00000	1M	AIPS 2
+ * FA100000	8FFFC000	16K	TZIC (interrupt controller)
+ *         	90000000	256M	CSD0 SDRAM/DDR
+ *         	A0000000	256M	CSD1 SDRAM/DDR
+ *         	B0000000	128M	CS0 Flash
+ *         	B8000000	128M	CS1 Flash
+ *         	C0000000	128M	CS2 Flash
+ *         	C8000000	64M	CS3 Flash
+ *         	CC000000	32M	CS4 SRAM
+ *         	CE000000	32M	CS5 SRAM
+ * F9000000	CFFF0000	64K	NFC (NAND Flash AXI)
+ *
+ */
+
+/*
+ * IRAM
+ */
+#define MX51_IRAM_BASE_ADDR		0x1FFE0000	/* internal ram */
+#define MX51_IRAM_BASE_ADDR_VIRT	0xFA3E0000
+#define MX51_IRAM_PARTITIONS		16
+#define MX51_IRAM_PARTITIONS_TO1	12
+#define MX51_IRAM_SIZE		(MX51_IRAM_PARTITIONS * SZ_8K)	/* 128KB */
+
+/*
+ * NFC
+ */
+#define MX51_NFC_AXI_BASE_ADDR		0xCFFF0000	/* NAND flash AXI */
+#define MX51_NFC_AXI_BASE_ADDR_VIRT	0xF9000000
+#define MX51_NFC_AXI_SIZE		SZ_64K
+
+/*
+ * Graphics Memory of GPU
+ */
+#define MX51_GPU_BASE_ADDR		0x20000000
+#define MX51_GPU2D_BASE_ADDR		0xD0000000
+
+#define MX51_TZIC_BASE_ADDR		0x8FFFC000
+#define MX51_TZIC_BASE_ADDR_VIRT	0xFA100000
+#define MX51_TZIC_SIZE			SZ_16K
+
+#define MX51_DEBUG_BASE_ADDR		0x60000000
+#define MX51_DEBUG_BASE_ADDR_VIRT	0xFA200000
+#define MX51_DEBUG_SIZE			SZ_1M
+#define MX51_ETB_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00001000)
+#define MX51_ETM_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00002000)
+#define MX51_TPIU_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00003000)
+#define MX51_CTI0_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00004000)
+#define MX51_CTI1_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00005000)
+#define MX51_CTI2_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00006000)
+#define MX51_CTI3_BASE_ADDR		(MX51_DEBUG_BASE_ADDR + 0x00007000)
+#define MX51_CORTEX_DBG_BASE_ADDR	(MX51_DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define MX51_SPBA0_BASE_ADDR 		0x70000000
+#define MX51_SPBA0_BASE_ADDR_VIRT	0xFB100000
+#define MX51_SPBA0_SIZE			SZ_1M
+
+#define MX51_MMC_SDHC1_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00004000)
+#define MX51_MMC_SDHC2_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00008000)
+#define MX51_UART3_BASE_ADDR 		(MX51_SPBA0_BASE_ADDR + 0x0000C000)
+#define MX51_CSPI1_BASE_ADDR 		(MX51_SPBA0_BASE_ADDR + 0x00010000)
+#define MX51_SSI2_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00014000)
+#define MX51_MMC_SDHC3_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00020000)
+#define MX51_MMC_SDHC4_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00024000)
+#define MX51_SPDIF_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00028000)
+#define MX51_ATA_DMA_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00030000)
+#define MX51_SLIM_DMA_BASE_ADDR		(MX51_SPBA0_BASE_ADDR + 0x00034000)
+#define MX51_HSI2C_DMA_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x00038000)
+#define MX51_SPBA_CTRL_BASE_ADDR	(MX51_SPBA0_BASE_ADDR + 0x0003C000)
+
+/*
+ * defines for SPBA modules
+ */
+#define MX51_SPBA_SDHC1	0x04
+#define MX51_SPBA_SDHC2	0x08
+#define MX51_SPBA_UART3	0x0C
+#define MX51_SPBA_CSPI1	0x10
+#define MX51_SPBA_SSI2	0x14
+#define MX51_SPBA_SDHC3	0x20
+#define MX51_SPBA_SDHC4	0x24
+#define MX51_SPBA_SPDIF	0x28
+#define MX51_SPBA_ATA	0x30
+#define MX51_SPBA_SLIM	0x34
+#define MX51_SPBA_HSI2C	0x38
+#define MX51_SPBA_CTRL	0x3C
+
+/*
+ * AIPS 1
+ */
+#define MX51_AIPS1_BASE_ADDR 	0x73F00000
+#define MX51_AIPS1_BASE_ADDR_VIRT	0xFB000000
+#define MX51_AIPS1_SIZE		SZ_1M
+
+#define MX51_OTG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00080000)
+#define MX51_GPIO1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00084000)
+#define MX51_GPIO2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00088000)
+#define MX51_GPIO3_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0008C000)
+#define MX51_GPIO4_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00090000)
+#define MX51_KPP_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00094000)
+#define MX51_WDOG_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x00098000)
+#define MX51_WDOG2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x0009C000)
+#define MX51_GPT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A0000)
+#define MX51_SRTC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A4000)
+#define MX51_IOMUXC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000A8000)
+#define MX51_EPIT1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000AC000)
+#define MX51_EPIT2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B0000)
+#define MX51_PWM1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B4000)
+#define MX51_PWM2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000B8000)
+#define MX51_UART1_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000BC000)
+#define MX51_UART2_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000C0000)
+#define MX51_SRC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D0000)
+#define MX51_CCM_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D4000)
+#define MX51_GPC_BASE_ADDR	(MX51_AIPS1_BASE_ADDR + 0x000D8000)
+
+/*
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MX51_MXC_DMA_CHANNEL_IRAM	30
+#define MX51_MXC_DMA_CHANNEL_SPDIF_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_UART3_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC1	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MMC2	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_SSI2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX	(MX51_MXC_DMA_CHANNEL_IRAM + 1)
+#else				/*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_SSI2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#endif				/*CONFIG_SDMA_IRAM */
+#define MX51_MXC_DMA_CHANNEL_CSPI1_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI1_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI2_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_CSPI3_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_RX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_ATA_TX	MXC_DMA_DYNAMIC_CHANNEL
+#define MX51_MXC_DMA_CHANNEL_MEMORY	MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define MX51_AIPS2_BASE_ADDR		0x83F00000
+#define MX51_AIPS2_BASE_ADDR_VIRT	0xFB200000
+#define MX51_AIPS2_SIZE			SZ_1M
+
+#define MX51_PLL1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00080000)
+#define MX51_PLL2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00084000)
+#define MX51_PLL3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00088000)
+#define MX51_AHBMAX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00094000)
+#define MX51_IIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x00098000)
+#define MX51_CSU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x0009C000)
+#define MX51_ARM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A0000)
+#define MX51_OWIRE_BASE_ADDR 	(MX51_AIPS2_BASE_ADDR + 0x000A4000)
+#define MX51_FIRI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000A8000)
+#define MX51_CSPI2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000AC000)
+#define MX51_SDMA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B0000)
+#define MX51_SCC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B4000)
+#define MX51_ROMCP_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000B8000)
+#define MX51_RTIC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000BC000)
+#define MX51_CSPI3_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C0000)
+#define MX51_I2C2_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C4000)
+#define MX51_I2C1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000C8000)
+#define MX51_SSI1_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000CC000)
+#define MX51_AUDMUX_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D0000)
+#define MX51_M4IF_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D8000)
+#define MX51_ESDCTL_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000D9000)
+#define MX51_WEIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DA000)
+#define MX51_NFC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DB000)
+#define MX51_EMI_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DBF00)
+#define MX51_MIPI_HSC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000DC000)
+#define MX51_ATA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E0000)
+#define MX51_SIM_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E4000)
+#define MX51_SSI3BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000E8000)
+#define MX51_MXC_FEC_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000EC000)
+#define MX51_TVE_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F0000)
+#define MX51_VPU_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F4000)
+#define MX51_SAHARA_BASE_ADDR	(MX51_AIPS2_BASE_ADDR + 0x000F8000)
+
+/*
+ * Memory regions and CS
+ */
+#define MX51_GPU_CTRL_BASE_ADDR		0x30000000
+#define MX51_IPU_CTRL_BASE_ADDR		0x40000000
+#define MX51_CSD0_BASE_ADDR		0x90000000
+#define MX51_CSD1_BASE_ADDR		0xA0000000
+#define MX51_CS0_BASE_ADDR		0xB0000000
+#define MX51_CS1_BASE_ADDR		0xB8000000
+#define MX51_CS2_BASE_ADDR		0xC0000000
+#define MX51_CS3_BASE_ADDR		0xC8000000
+#define MX51_CS4_BASE_ADDR		0xCC000000
+#define MX51_CS5_BASE_ADDR		0xCE000000
+
+/* Does given address belongs to the specified memory region? */
+#define ADDRESS_IN_REGION(addr, start, size)			\
+	(((addr) >= (start)) && ((addr) < (start)+(size)))
+
+/* Does given address belongs to the specified named `module'? */
+#define MX51_IS_MODULE(addr, module)			       \
+	ADDRESS_IN_REGION(addr, MX51_ ## module ## _BASE_ADDR, \
+				MX51_ ## module ## _SIZE)
+/*
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+
+#define MX51_IO_ADDRESS(x)					\
+	(void __iomem *)					\
+	(MX51_IS_MODULE(x, IRAM) ? MX51_IRAM_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, TZIC) ? MX51_TZIC_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, DEBUG) ? MX51_DEBUG_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, SPBA0) ? MX51_SPBA0_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, AIPS1) ? MX51_AIPS1_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, AIPS2) ? MX51_AIPS2_IO_ADDRESS(x) :	\
+	MX51_IS_MODULE(x, NFC_AXI) ? MX51_NFC_AXI_IO_ADDRESS(x) : \
+	0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define MX51_IRAM_IO_ADDRESS(x)  \
+	(((x) - MX51_IRAM_BASE_ADDR) + MX51_IRAM_BASE_ADDR_VIRT)
+
+#define MX51_TZIC_IO_ADDRESS(x)  \
+	(((x) - MX51_TZIC_BASE_ADDR) + MX51_TZIC_BASE_ADDR_VIRT)
+
+#define MX51_DEBUG_IO_ADDRESS(x)  \
+	(((x) - MX51_DEBUG_BASE_ADDR) + MX51_DEBUG_BASE_ADDR_VIRT)
+
+#define MX51_SPBA0_IO_ADDRESS(x)  \
+	(((x) - MX51_SPBA0_BASE_ADDR) + MX51_SPBA0_BASE_ADDR_VIRT)
+
+#define MX51_AIPS1_IO_ADDRESS(x)  \
+	(((x) - MX51_AIPS1_BASE_ADDR) + MX51_AIPS1_BASE_ADDR_VIRT)
+
+#define MX51_AIPS2_IO_ADDRESS(x)  \
+	(((x) - MX51_AIPS2_BASE_ADDR) + MX51_AIPS2_BASE_ADDR_VIRT)
+
+#define MX51_NFC_AXI_IO_ADDRESS(x) \
+	(((x) - MX51_NFC_AXI_BASE_ADDR) + MX51_NFC_AXI_BASE_ADDR_VIRT)
+
+#define MX51_IS_MEM_DEVICE_NONSHARED(x)		0
+
+/*
+ * DMA request assignments
+ */
+#define MX51_DMA_REQ_SSI3_TX1	47
+#define MX51_DMA_REQ_SSI3_RX1	46
+#define MX51_DMA_REQ_SPDIF	45
+#define MX51_DMA_REQ_UART3_TX	44
+#define MX51_DMA_REQ_UART3_RX	43
+#define MX51_DMA_REQ_SLIM_B_TX	42
+#define MX51_DMA_REQ_SDHC4	41
+#define MX51_DMA_REQ_SDHC3	40
+#define MX51_DMA_REQ_CSPI_TX	39
+#define MX51_DMA_REQ_CSPI_RX	38
+#define MX51_DMA_REQ_SSI3_TX2	37
+#define MX51_DMA_REQ_IPU	36
+#define MX51_DMA_REQ_SSI3_RX2	35
+#define MX51_DMA_REQ_EPIT2	34
+#define MX51_DMA_REQ_CTI2_1	33
+#define MX51_DMA_REQ_EMI_WR	32
+#define MX51_DMA_REQ_CTI2_0	31
+#define MX51_DMA_REQ_EMI_RD	30
+#define MX51_DMA_REQ_SSI1_TX1	29
+#define MX51_DMA_REQ_SSI1_RX1	28
+#define MX51_DMA_REQ_SSI1_TX2	27
+#define MX51_DMA_REQ_SSI1_RX2	26
+#define MX51_DMA_REQ_SSI2_TX1	25
+#define MX51_DMA_REQ_SSI2_RX1	24
+#define MX51_DMA_REQ_SSI2_TX2	23
+#define MX51_DMA_REQ_SSI2_RX2	22
+#define MX51_DMA_REQ_SDHC2	21
+#define MX51_DMA_REQ_SDHC1	20
+#define MX51_DMA_REQ_UART1_TX	19
+#define MX51_DMA_REQ_UART1_RX	18
+#define MX51_DMA_REQ_UART2_TX	17
+#define MX51_DMA_REQ_UART2_RX	16
+#define MX51_DMA_REQ_GPU	15
+#define MX51_DMA_REQ_EXTREQ1	14
+#define MX51_DMA_REQ_FIRI_TX	13
+#define MX51_DMA_REQ_FIRI_RX	12
+#define MX51_DMA_REQ_HS_I2C_RX	11
+#define MX51_DMA_REQ_HS_I2C_TX	10
+#define MX51_DMA_REQ_CSPI2_TX	9
+#define MX51_DMA_REQ_CSPI2_RX	8
+#define MX51_DMA_REQ_CSPI1_TX	7
+#define MX51_DMA_REQ_CSPI1_RX	6
+#define MX51_DMA_REQ_SLIM_B	5
+#define MX51_DMA_REQ_ATA_TX_END	4
+#define MX51_DMA_REQ_ATA_TX	3
+#define MX51_DMA_REQ_ATA_RX	2
+#define MX51_DMA_REQ_GPC	1
+#define MX51_DMA_REQ_VPU	0
+
+/*
+ * Interrupt numbers
+ */
+#define MX51_MXC_INT_BASE	0
+#define MX51_MXC_INT_RESV0	0
+#define MX51_MXC_INT_MMC_SDHC1	1
+#define MX51_MXC_INT_MMC_SDHC2	2
+#define MX51_MXC_INT_MMC_SDHC3	3
+#define MX51_MXC_INT_MMC_SDHC4	4
+#define MX51_MXC_INT_RESV5	5
+#define MX51_MXC_INT_SDMA	6
+#define MX51_MXC_INT_IOMUX	7
+#define MX51_MXC_INT_NFC	8
+#define MX51_MXC_INT_VPU	9
+#define MX51_MXC_INT_IPU_ERR	10
+#define MX51_MXC_INT_IPU_SYN	11
+#define MX51_MXC_INT_GPU	12
+#define MX51_MXC_INT_RESV13	13
+#define MX51_MXC_INT_USB_H1	14
+#define MX51_MXC_INT_EMI	15
+#define MX51_MXC_INT_USB_H2	16
+#define MX51_MXC_INT_USB_H3	17
+#define MX51_MXC_INT_USB_OTG	18
+#define MX51_MXC_INT_SAHARA_H0	19
+#define MX51_MXC_INT_SAHARA_H1	20
+#define MX51_MXC_INT_SCC_SMN	21
+#define MX51_MXC_INT_SCC_STZ	22
+#define MX51_MXC_INT_SCC_SCM	23
+#define MX51_MXC_INT_SRTC_NTZ	24
+#define MX51_MXC_INT_SRTC_TZ	25
+#define MX51_MXC_INT_RTIC	26
+#define MX51_MXC_INT_CSU	27
+#define MX51_MXC_INT_SLIM_B	28
+#define MX51_MXC_INT_SSI1	29
+#define MX51_MXC_INT_SSI2	30
+#define MX51_MXC_INT_UART1	31
+#define MX51_MXC_INT_UART2	32
+#define MX51_MXC_INT_UART3	33
+#define MX51_MXC_INT_RESV34	34
+#define MX51_MXC_INT_RESV35	35
+#define MX51_MXC_INT_CSPI1	36
+#define MX51_MXC_INT_CSPI2	37
+#define MX51_MXC_INT_CSPI	38
+#define MX51_MXC_INT_GPT	39
+#define MX51_MXC_INT_EPIT1	40
+#define MX51_MXC_INT_EPIT2	41
+#define MX51_MXC_INT_GPIO1_INT7	42
+#define MX51_MXC_INT_GPIO1_INT6	43
+#define MX51_MXC_INT_GPIO1_INT5	44
+#define MX51_MXC_INT_GPIO1_INT4	45
+#define MX51_MXC_INT_GPIO1_INT3	46
+#define MX51_MXC_INT_GPIO1_INT2	47
+#define MX51_MXC_INT_GPIO1_INT1	48
+#define MX51_MXC_INT_GPIO1_INT0	49
+#define MX51_MXC_INT_GPIO1_LOW	50
+#define MX51_MXC_INT_GPIO1_HIGH	51
+#define MX51_MXC_INT_GPIO2_LOW	52
+#define MX51_MXC_INT_GPIO2_HIGH	53
+#define MX51_MXC_INT_GPIO3_LOW	54
+#define MX51_MXC_INT_GPIO3_HIGH	55
+#define MX51_MXC_INT_GPIO4_LOW	56
+#define MX51_MXC_INT_GPIO4_HIGH	57
+#define MX51_MXC_INT_WDOG1	58
+#define MX51_MXC_INT_WDOG2	59
+#define MX51_MXC_INT_KPP	60
+#define MX51_MXC_INT_PWM1	61
+#define MX51_MXC_INT_I2C1	62
+#define MX51_MXC_INT_I2C2	63
+#define MX51_MXC_INT_HS_I2C	64
+#define MX51_MXC_INT_RESV65	65
+#define MX51_MXC_INT_RESV66	66
+#define MX51_MXC_INT_SIM_IPB	67
+#define MX51_MXC_INT_SIM_DAT	68
+#define MX51_MXC_INT_IIM	69
+#define MX51_MXC_INT_ATA	70
+#define MX51_MXC_INT_CCM1	71
+#define MX51_MXC_INT_CCM2	72
+#define MX51_MXC_INT_GPC1	73
+#define MX51_MXC_INT_GPC2	74
+#define MX51_MXC_INT_SRC	75
+#define MX51_MXC_INT_NM		76
+#define MX51_MXC_INT_PMU	77
+#define MX51_MXC_INT_CTI_IRQ	78
+#define MX51_MXC_INT_CTI1_TG0	79
+#define MX51_MXC_INT_CTI1_TG1	80
+#define MX51_MXC_INT_MCG_ERR	81
+#define MX51_MXC_INT_MCG_TMR	82
+#define MX51_MXC_INT_MCG_FUNC	83
+#define MX51_MXC_INT_GPU2_IRQ	84
+#define MX51_MXC_INT_GPU2_BUSY	85
+#define MX51_MXC_INT_RESV86	86
+#define MX51_MXC_INT_FEC	87
+#define MX51_MXC_INT_OWIRE	88
+#define MX51_MXC_INT_CTI1_TG2	89
+#define MX51_MXC_INT_SJC	90
+#define MX51_MXC_INT_SPDIF	91
+#define MX51_MXC_INT_TVE	92
+#define MX51_MXC_INT_FIRI	93
+#define MX51_MXC_INT_PWM2	94
+#define MX51_MXC_INT_SLIM_EXP	95
+#define MX51_MXC_INT_SSI3	96
+#define MX51_MXC_INT_EMI_BOOT	97
+#define MX51_MXC_INT_CTI1_TG3	98
+#define MX51_MXC_INT_SMC_RX	99
+#define MX51_MXC_INT_VPU_IDLE	100
+#define MX51_MXC_INT_EMI_NFC	101
+#define MX51_MXC_INT_GPU_IDLE	102
+
+/* silicon revisions specific to i.MX51 */
+#define MX51_CHIP_REV_1_0	0x10
+#define MX51_CHIP_REV_1_1	0x11
+#define MX51_CHIP_REV_1_2	0x12
+#define MX51_CHIP_REV_1_3	0x13
+#define MX51_CHIP_REV_2_0	0x20
+#define MX51_CHIP_REV_2_1	0x21
+#define MX51_CHIP_REV_2_2	0x22
+#define MX51_CHIP_REV_2_3	0x23
+#define MX51_CHIP_REV_3_0	0x30
+#define MX51_CHIP_REV_3_1	0x31
+#define MX51_CHIP_REV_3_2	0x32
+
+/* Mandatory defines used globally */
+
+#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
+
+extern unsigned int system_rev;
+
+static inline unsigned int mx51_revision(void)
+{
+	return system_rev;
+}
+#endif
+
+#endif	/*  __ASM_ARCH_MXC_MX51_H__ */
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
@ 2010-02-03  5:16             ` Amit Kucheria
  2010-02-03  5:16               ` [PATCHv2 07/11] mxc: Add support for the Babbage board Amit Kucheria
  2010-02-03  7:03             ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Eric Miao
                               ` (3 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

Kconfig and Makefiles to enable Freescale i.MX51 processor. Separated to help
ease the review process.

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/Makefile               |    1 +
 arch/arm/mach-mx5/Kconfig       |   11 +++++++++++
 arch/arm/mach-mx5/Makefile      |    7 +++++++
 arch/arm/mach-mx5/Makefile.boot |    3 +++
 arch/arm/plat-mxc/Kconfig       |    8 ++++++++
 5 files changed, 30 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mx5/Kconfig
 create mode 100644 arch/arm/mach-mx5/Makefile
 create mode 100644 arch/arm/mach-mx5/Makefile.boot

diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9e75825..52232d2 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -146,6 +146,7 @@ machine-$(CONFIG_ARCH_MX1)		:= mx1
 machine-$(CONFIG_ARCH_MX2)		:= mx2
 machine-$(CONFIG_ARCH_MX25)		:= mx25
 machine-$(CONFIG_ARCH_MX3)		:= mx3
+machine-$(CONFIG_ARCH_MX5)		:= mx5
 machine-$(CONFIG_ARCH_MXC91231)		:= mxc91231
 machine-$(CONFIG_ARCH_NETX)		:= netx
 machine-$(CONFIG_ARCH_NOMADIK)		:= nomadik
diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
new file mode 100644
index 0000000..ccd96fd
--- /dev/null
+++ b/arch/arm/mach-mx5/Kconfig
@@ -0,0 +1,11 @@
+if ARCH_MX5
+
+config ARCH_MX51
+	bool
+	default y
+	select MXC_TZIC
+	select ARCH_MXC_IOMUX_V3
+
+comment "MX5 platforms:"
+
+endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
new file mode 100644
index 0000000..d74ce4f
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile
@@ -0,0 +1,7 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+obj-y   := cpu.o mm.o clock.o devices.o
+
diff --git a/arch/arm/mach-mx5/Makefile.boot b/arch/arm/mach-mx5/Makefile.boot
new file mode 100644
index 0000000..9939a19
--- /dev/null
+++ b/arch/arm/mach-mx5/Makefile.boot
@@ -0,0 +1,3 @@
+   zreladdr-y	:= 0x90008000
+params_phys-y	:= 0x90000100
+initrd_phys-y	:= 0x90800000
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 59558c4..cea51a0 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -41,6 +41,13 @@ config ARCH_MXC91231
 	help
 	  This enables support for systems based on the Freescale MXC91231 family
 
+config ARCH_MX5
+	bool "MX5-based"
+	select CPU_V7
+	select COMMON_CLKDEV
+	help
+	  This enables support for systems based on the Freescale i.MX51 family
+
 endchoice
 
 source "arch/arm/mach-mx1/Kconfig"
@@ -48,6 +55,7 @@ source "arch/arm/mach-mx2/Kconfig"
 source "arch/arm/mach-mx3/Kconfig"
 source "arch/arm/mach-mx25/Kconfig"
 source "arch/arm/mach-mxc91231/Kconfig"
+source "arch/arm/mach-mx5/Kconfig"
 
 endmenu
 
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 07/11] mxc: Add support for the Babbage board
  2010-02-03  5:16             ` [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors Amit Kucheria
@ 2010-02-03  5:16               ` Amit Kucheria
  2010-02-03  5:16                 ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Amit Kucheria
  2010-02-03 11:10                 ` [PATCHv2 07/11] mxc: Add support for the Babbage board Sascha Hauer
  0 siblings, 2 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

Babbage is a reference board from Freescale for their i.MX51 SoC.

Boot tested on a Babbage2.5 board

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/mach-mx5/Kconfig               |    6 ++
 arch/arm/mach-mx5/Makefile              |    2 +
 arch/arm/mach-mx5/board-mx51_babbage.c  |   99 +++++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/common.h |    1 +
 4 files changed, 108 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-mx5/board-mx51_babbage.c

diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
index ccd96fd..80a749c 100644
--- a/arch/arm/mach-mx5/Kconfig
+++ b/arch/arm/mach-mx5/Kconfig
@@ -8,4 +8,10 @@ config ARCH_MX51
 
 comment "MX5 platforms:"
 
+config MACH_MX51_BABBAGE
+	bool "Support MX51 BABBAGE platforms"
+	help
+	  Include support for MX51 Babbage platform. This includes specific
+	  configurations for the board and its peripherals.
+
 endif
diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
index d74ce4f..e4cf91f 100644
--- a/arch/arm/mach-mx5/Makefile
+++ b/arch/arm/mach-mx5/Makefile
@@ -5,3 +5,5 @@
 # Object file lists.
 obj-y   := cpu.o mm.o clock.o devices.o
 
+obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
+
diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c
new file mode 100644
index 0000000..6cd0e14
--- /dev/null
+++ b/arch/arm/mach-mx5/board-mx51_babbage.c
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/imx-uart.h>
+#include <mach/iomux-mx51.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include "crm_regs.h"
+#include "devices.h"
+
+static struct platform_device *devices[] __initdata = {
+	&mxc_fec_device,
+};
+
+static struct pad_desc mx51babbage_pads[] = {
+	/* UART1 */
+	MX51_BABBAGE_PAD_UART1_RXD__UART1_RXD,
+	MX51_BABBAGE_PAD_UART1_TXD__UART1_TXD,
+	MX51_BABBAGE_PAD_UART1_RTS__UART1_RTS,
+	MX51_BABBAGE_PAD_UART1_CTS__UART1_CTS,
+
+	/* UART2 */
+	MX51_BABBAGE_PAD_UART2_RXD__UART2_RXD,
+	MX51_BABBAGE_PAD_UART2_TXD__UART2_TXD,
+
+	/* UART3 */
+	MX51_BABBAGE_PAD_EIM_D25__UART3_RXD,
+	MX51_BABBAGE_PAD_EIM_D26__UART3_TXD,
+	MX51_BABBAGE_PAD_EIM_D27__UART3_RTS,
+	MX51_BABBAGE_PAD_EIM_D24__UART3_CTS,
+};
+
+/* Serial ports */
+#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
+static struct imxuart_platform_data uart_pdata = {
+	.flags = IMXUART_HAVE_RTSCTS,
+};
+
+static inline void mxc_init_imx_uart(void)
+{
+	mxc_register_device(&mxc_uart_device0, &uart_pdata);
+	mxc_register_device(&mxc_uart_device1, &uart_pdata);
+	mxc_register_device(&mxc_uart_device2, &uart_pdata);
+}
+#else /* !SERIAL_IMX */
+static inline void mxc_init_imx_uart(void)
+{
+}
+#endif /* SERIAL_IMX */
+
+/*
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+	mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
+					ARRAY_SIZE(mx51babbage_pads));
+	mxc_init_imx_uart();
+	platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+
+static void __init mx51_babbage_timer_init(void)
+{
+	mx51_clocks_init(32768, 24000000, 22579200, 24576000);
+}
+
+static struct sys_timer mxc_timer = {
+	.init	= mx51_babbage_timer_init,
+};
+
+MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
+	/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
+	.phys_io = MX51_AIPS1_BASE_ADDR,
+	.io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+	.boot_params = PHYS_OFFSET + 0x100,
+	.map_io = mx51_map_io,
+	.init_irq = mx51_init_irq,
+	.init_machine = mxc_board_init,
+	.timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 0a25576..33d4496 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -21,6 +21,7 @@ extern void mx27_map_io(void);
 extern void mx31_map_io(void);
 extern void mx35_map_io(void);
 extern void mx51_map_io(void);
+extern void mx51_babbage_io_init(void);
 extern void mxc91231_map_io(void);
 extern void mxc_init_irq(void __iomem *);
 extern void tzic_init_irq(void __iomem *);
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 08/11] fec: fix uninitialized rx buffer usage
  2010-02-03  5:16               ` [PATCHv2 07/11] mxc: Add support for the Babbage board Amit Kucheria
@ 2010-02-03  5:16                 ` Amit Kucheria
  2010-02-03  5:16                   ` [PATCHv2 09/11] fec: Add LAN8700 phy support Amit Kucheria
  2010-02-03 16:46                   ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Grant Likely
  2010-02-03 11:10                 ` [PATCHv2 07/11] mxc: Add support for the Babbage board Sascha Hauer
  1 sibling, 2 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rob Herring <r.herring@freescale.com>

The fec driver was enabling receive buffer descriptor without allocating
the buffers. Make sure the buffer descriptors are initialized to not
start receiving packets.

Open also calls fec_restart after the rx buffers are allocated. With the code
in fec_restart, it zeroes out the buffer descriptors that have just been
setup.

Signed-off-by: Rob Herring <r.herring@freescale.com>
Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev at vger.kernel.org
---
 drivers/net/fec.c |   57 +++++++++++++++++++++++++++--------------------------
 1 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 16a1d58..9a8743d 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1658,6 +1658,7 @@ static int fec_enet_init(struct net_device *dev, int index)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
 	struct bufdesc *cbd_base;
+	struct bufdesc *bdp;
 	int i;
 
 	/* Allocate memory for buffer descriptors. */
@@ -1710,6 +1711,34 @@ static int fec_enet_init(struct net_device *dev, int index)
 	/* Set MII speed to 2.5 MHz */
 	fep->phy_speed = ((((clk_get_rate(fep->clk) / 2 + 4999999)
 					/ 2500000) / 2) & 0x3F) << 1;
+
+	/* Initialize the receive buffer descriptors. */
+	bdp = fep->rx_bd_base;
+	for (i = 0; i < RX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page. */
+		bdp->cbd_sc = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap */
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
+	/* ...and the same for transmit */
+	bdp = fep->tx_bd_base;
+	for (i = 0; i < TX_RING_SIZE; i++) {
+
+		/* Initialize the BD for every fragment in the page. */
+		bdp->cbd_sc = 0;
+		bdp->cbd_bufaddr = 0;
+		bdp++;
+	}
+
+	/* Set the last buffer to wrap */
+	bdp--;
+	bdp->cbd_sc |= BD_SC_WRAP;
+
 	fec_restart(dev, 0);
 
 	/* Queue up command to detect the PHY and initialize the
@@ -1730,7 +1759,6 @@ static void
 fec_restart(struct net_device *dev, int duplex)
 {
 	struct fec_enet_private *fep = netdev_priv(dev);
-	struct bufdesc *bdp;
 	int i;
 
 	/* Whack a reset.  We should wait for this. */
@@ -1768,33 +1796,6 @@ fec_restart(struct net_device *dev, int duplex)
 		}
 	}
 
-	/* Initialize the receive buffer descriptors. */
-	bdp = fep->rx_bd_base;
-	for (i = 0; i < RX_RING_SIZE; i++) {
-
-		/* Initialize the BD for every fragment in the page. */
-		bdp->cbd_sc = BD_ENET_RX_EMPTY;
-		bdp++;
-	}
-
-	/* Set the last buffer to wrap */
-	bdp--;
-	bdp->cbd_sc |= BD_SC_WRAP;
-
-	/* ...and the same for transmit */
-	bdp = fep->tx_bd_base;
-	for (i = 0; i < TX_RING_SIZE; i++) {
-
-		/* Initialize the BD for every fragment in the page. */
-		bdp->cbd_sc = 0;
-		bdp->cbd_bufaddr = 0;
-		bdp++;
-	}
-
-	/* Set the last buffer to wrap */
-	bdp--;
-	bdp->cbd_sc |= BD_SC_WRAP;
-
 	/* Enable MII mode */
 	if (duplex) {
 		/* MII enable / FD enable */
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 09/11] fec: Add LAN8700 phy support
  2010-02-03  5:16                 ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Amit Kucheria
@ 2010-02-03  5:16                   ` Amit Kucheria
  2010-02-03  5:16                     ` [PATCHv2 10/11] fec: Add ARCH_MX5 as a dependency Amit Kucheria
  2010-02-03 16:46                   ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Grant Likely
  1 sibling, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

The i.MX51 babbage board has a FEC ethernet controller with this phy.

In the long term we should resurrect the phylib patches for fec.

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev at vger.kernel.org
---
 drivers/net/fec.c |   21 +++++++++++++++++++++
 1 files changed, 21 insertions(+), 0 deletions(-)

diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 9a8743d..5d0d332 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1128,6 +1128,26 @@ static phy_info_t phy_info_dp83848= {
 	},
 };
 
+static phy_info_t phy_info_lan8700 = {
+	0x0007C0C,
+	"LAN8700",
+	(const phy_cmd_t []) { /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* startup */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* act_int */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* shutdown */
+		{ mk_mii_end, }
+	},
+};
 /* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
@@ -1137,6 +1157,7 @@ static phy_info_t const * const phy_info[] = {
 	&phy_info_am79c874,
 	&phy_info_ks8721bl,
 	&phy_info_dp83848,
+	&phy_info_lan8700,
 	NULL
 };
 
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 10/11] fec: Add ARCH_MX5 as a dependency
  2010-02-03  5:16                   ` [PATCHv2 09/11] fec: Add LAN8700 phy support Amit Kucheria
@ 2010-02-03  5:16                     ` Amit Kucheria
  2010-02-03  5:16                       ` [PATCHv2 11/11] mxc: Add imx51_defconfig Amit Kucheria
  0 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

i.MX51 babbage board has a FEC ethernet controller

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: netdev at vger.kernel.org
---
 drivers/net/Kconfig |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dd9a09c..515658e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1883,7 +1883,8 @@ config 68360_ENET
 
 config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
-	depends on M523x || M527x || M5272 || M528x || M520x || M532x || MACH_MX27 || ARCH_MX35 || ARCH_MX25
+	depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
+		MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
 	help
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  controller on some Motorola ColdFire and Freescale i.MX processors.
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 11/11] mxc: Add imx51_defconfig
  2010-02-03  5:16                     ` [PATCHv2 10/11] fec: Add ARCH_MX5 as a dependency Amit Kucheria
@ 2010-02-03  5:16                       ` Amit Kucheria
  2010-02-05  6:48                         ` Sascha Hauer
  0 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03  5:16 UTC (permalink / raw)
  To: linux-arm-kernel

This config is used to test the base support for i.MX51 processors on the
Babbage board

Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
---
 arch/arm/configs/imx51_defconfig | 1286 ++++++++++++++++++++++++++++++++++++++
 1 files changed, 1286 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/configs/imx51_defconfig

diff --git a/arch/arm/configs/imx51_defconfig b/arch/arm/configs/imx51_defconfig
new file mode 100644
index 0000000..c88e952
--- /dev/null
+++ b/arch/arm/configs/imx51_defconfig
@@ -0,0 +1,1286 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.33-rc6
+# Tue Feb  2 15:20:48 2010
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+CONFIG_GENERIC_GPIO=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_HAVE_LATENCYTOP_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_HAVE_KERNEL_GZIP=y
+CONFIG_HAVE_KERNEL_LZO=y
+CONFIG_KERNEL_GZIP=y
+# CONFIG_KERNEL_BZIP2 is not set
+# CONFIG_KERNEL_LZMA is not set
+# CONFIG_KERNEL_LZO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+
+#
+# RCU Subsystem
+#
+CONFIG_TREE_RCU=y
+# CONFIG_TREE_PREEMPT_RCU is not set
+# CONFIG_TINY_RCU is not set
+# CONFIG_RCU_TRACE is not set
+CONFIG_RCU_FANOUT=32
+# CONFIG_RCU_FANOUT_EXACT is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=18
+# CONFIG_GROUP_SCHED is not set
+# CONFIG_CGROUPS is not set
+# CONFIG_SYSFS_DEPRECATED_V2 is not set
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_HAVE_CLK=y
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_GCOV_KERNEL is not set
+# CONFIG_SLOW_WORK is not set
+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLOCK=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+CONFIG_FREEZER=y
+
+#
+# System Type
+#
+CONFIG_MMU=y
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_GEMINI is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_STMP3XXX is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_NOMADIK is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_DOVE is not set
+# CONFIG_ARCH_KIRKWOOD is not set
+# CONFIG_ARCH_LOKI is not set
+# CONFIG_ARCH_MV78XX0 is not set
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_MMP is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+# CONFIG_ARCH_W90X900 is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_MSM is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_S3C64XX is not set
+# CONFIG_ARCH_S5PC1XX is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_U300 is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_BCMRING is not set
+# CONFIG_ARCH_U8500 is not set
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX1 is not set
+# CONFIG_ARCH_MX2 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MXC91231 is not set
+CONFIG_ARCH_MX5=y
+CONFIG_ARCH_MX51=y
+
+#
+# MX5 platforms:
+#
+CONFIG_MACH_MX51_BABBAGE=y
+# CONFIG_MXC_IRQ_PRIOR is not set
+CONFIG_MXC_TZIC=y
+# CONFIG_MXC_PWM is not set
+CONFIG_ARCH_MXC_IOMUX_V3=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_V7=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+CONFIG_ARM_L1_CACHE_SHIFT=5
+# CONFIG_ARM_ERRATA_430973 is not set
+# CONFIG_ARM_ERRATA_458693 is not set
+# CONFIG_ARM_ERRATA_460075 is not set
+CONFIG_COMMON_CLKDEV=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_VMSPLIT_3G=y
+# CONFIG_VMSPLIT_2G is not set
+# CONFIG_VMSPLIT_1G is not set
+CONFIG_PAGE_OFFSET=0xC0000000
+# CONFIG_PREEMPT_NONE is not set
+CONFIG_PREEMPT_VOLUNTARY=y
+# CONFIG_PREEMPT is not set
+CONFIG_HZ=100
+# CONFIG_THUMB2_KERNEL is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
+# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+# CONFIG_HIGHMEM is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_PHYS_ADDR_T_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_KSM is not set
+CONFIG_DEFAULT_MMAP_MIN_ADDR=32768
+CONFIG_ALIGNMENT_TRAP=y
+# CONFIG_UACCESS_WITH_MEMCPY is not set
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0
+CONFIG_ZBOOT_ROM_BSS=0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/nfs nfsroot=192.168.0.101:/shared/nfs ip=dhcp"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Power Management
+#
+# CONFIG_CPU_IDLE is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+CONFIG_HAVE_AOUT=y
+# CONFIG_BINFMT_AOUT is not set
+CONFIG_BINFMT_MISC=m
+
+#
+# Power management options
+#
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_VERBOSE is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+# CONFIG_PM_RUNTIME is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+# CONFIG_IP_MULTICAST is not set
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_IP_PNP_BOOTP is not set
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_WIRELESS is not set
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_STANDALONE is not set
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_DRBD is not set
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=65536
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_MG_DISK is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_SCSI_PROC_FS is not set
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+CONFIG_SCSI_MULTI_LUN=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+# CONFIG_SCSI_LOWLEVEL is not set
+# CONFIG_SCSI_DH is not set
+# CONFIG_SCSI_OSD_INITIATOR is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+CONFIG_ATA_VERBOSE_ERROR=y
+CONFIG_SATA_PMP=y
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+CONFIG_PHYLIB=y
+
+#
+# MII PHY device drivers
+#
+CONFIG_MARVELL_PHY=y
+CONFIG_DAVICOM_PHY=y
+CONFIG_QSEMI_PHY=y
+CONFIG_LXT_PHY=y
+CONFIG_CICADA_PHY=y
+CONFIG_VITESSE_PHY=y
+CONFIG_SMSC_PHY=y
+CONFIG_BROADCOM_PHY=y
+CONFIG_ICPLUS_PHY=y
+CONFIG_REALTEK_PHY=y
+CONFIG_NATIONAL_PHY=y
+CONFIG_STE10XP=y
+CONFIG_LSI_ET1011C_PHY=y
+CONFIG_FIXED_PHY=y
+CONFIG_MDIO_BITBANG=y
+CONFIG_MDIO_GPIO=y
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=m
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ETHOC is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_DNET is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+# CONFIG_KS8842 is not set
+# CONFIG_KS8851_MLL is not set
+CONFIG_FEC=y
+# CONFIG_FEC2 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_WLAN is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+CONFIG_INPUT_FF_MEMLESS=m
+# CONFIG_INPUT_POLLDEV is not set
+# CONFIG_INPUT_SPARSEKMAP is not set
+
+#
+# Userland interfaces
+#
+CONFIG_INPUT_MOUSEDEV=y
+# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ADP5588 is not set
+CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_QT2160 is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_GPIO is not set
+# CONFIG_KEYBOARD_MATRIX is not set
+# CONFIG_KEYBOARD_LM8323 is not set
+# CONFIG_KEYBOARD_MAX7359 is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_OPENCORES is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+CONFIG_INPUT_MOUSE=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ALPS=y
+CONFIG_MOUSE_PS2_LOGIPS2PP=y
+CONFIG_MOUSE_PS2_SYNAPTICS=y
+CONFIG_MOUSE_PS2_TRACKPOINT=y
+CONFIG_MOUSE_PS2_ELANTECH=y
+# CONFIG_MOUSE_PS2_SENTELIC is not set
+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
+# CONFIG_MOUSE_SERIAL is not set
+# CONFIG_MOUSE_VSXXXAA is not set
+# CONFIG_MOUSE_GPIO is not set
+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+CONFIG_SERIO=y
+CONFIG_SERIO_SERPORT=m
+CONFIG_SERIO_LIBPS2=y
+# CONFIG_SERIO_RAW is not set
+# CONFIG_SERIO_ALTERA_PS2 is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+CONFIG_VT_HW_CONSOLE_BINDING=y
+# CONFIG_DEVKMEM is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=m
+# CONFIG_I2C_HELPER_AUTO is not set
+
+#
+# I2C Algorithms
+#
+CONFIG_I2C_ALGOBIT=m
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+
+#
+# I2C Hardware Bus support
+#
+
+#
+# I2C system bus drivers (mostly embedded / system-on-chip)
+#
+# CONFIG_I2C_DESIGNWARE is not set
+# CONFIG_I2C_GPIO is not set
+# CONFIG_I2C_IMX is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_SIMTEC is not set
+
+#
+# External I2C/SMBus adapter drivers
+#
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_TAOS_EVM is not set
+
+#
+# Other I2C/SMBus bus drivers
+#
+# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_STUB is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+CONFIG_ARCH_REQUIRE_GPIOLIB=y
+CONFIG_GPIOLIB=y
+# CONFIG_DEBUG_GPIO is not set
+CONFIG_GPIO_SYSFS=y
+
+#
+# Memory mapped GPIO expanders:
+#
+
+#
+# I2C GPIO expanders:
+#
+# CONFIG_GPIO_MAX732X is not set
+# CONFIG_GPIO_PCA953X is not set
+# CONFIG_GPIO_PCF857X is not set
+# CONFIG_GPIO_ADP5588 is not set
+
+#
+# PCI GPIO expanders:
+#
+
+#
+# SPI GPIO expanders:
+#
+
+#
+# AC97 GPIO expanders:
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_EGPIO is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_TPS65010 is not set
+# CONFIG_TWL4030_CORE is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_MFD_T7L66XB is not set
+# CONFIG_MFD_TC6387XB is not set
+# CONFIG_MFD_TC6393XB is not set
+# CONFIG_PMIC_DA903X is not set
+# CONFIG_PMIC_ADP5520 is not set
+# CONFIG_MFD_WM8400 is not set
+# CONFIG_MFD_WM831X is not set
+# CONFIG_MFD_WM8350_I2C is not set
+# CONFIG_MFD_PCF50633 is not set
+# CONFIG_AB3100_CORE is not set
+# CONFIG_MFD_88PM8607 is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+# CONFIG_SOUND is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD/SDIO Card Drivers
+#
+CONFIG_MMC_BLOCK=m
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD/SDIO Host Controller Drivers
+#
+CONFIG_MMC_SDHCI=m
+# CONFIG_MMC_SDHCI_PLTFM is not set
+# CONFIG_MMC_AT91 is not set
+# CONFIG_MMC_ATMELMCI is not set
+# CONFIG_MMC_MXC is not set
+# CONFIG_MEMSTICK is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=m
+
+#
+# LED drivers
+#
+# CONFIG_LEDS_PCA9532 is not set
+# CONFIG_LEDS_GPIO is not set
+# CONFIG_LEDS_LP3944 is not set
+# CONFIG_LEDS_PCA955X is not set
+# CONFIG_LEDS_BD2802 is not set
+# CONFIG_LEDS_LT3593 is not set
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_BQ32K is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+# CONFIG_RTC_DRV_RX8581 is not set
+# CONFIG_RTC_DRV_RX8025 is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_MSM6242 is not set
+# CONFIG_RTC_MXC is not set
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_RP5C01 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+
+#
+# TI VLYNQ
+#
+# CONFIG_STAGING is not set
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+# CONFIG_EXT2_FS_XIP is not set
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_DEFAULTS_TO_ORDERED=y
+CONFIG_EXT3_FS_XATTR=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_XATTR=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+# CONFIG_EXT4_DEBUG is not set
+CONFIG_JBD=y
+# CONFIG_JBD_DEBUG is not set
+CONFIG_JBD2=y
+# CONFIG_JBD2_DEBUG is not set
+CONFIG_FS_MBCACHE=y
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+CONFIG_FS_POSIX_ACL=y
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+# CONFIG_QFMT_V1 is not set
+# CONFIG_QFMT_V2 is not set
+CONFIG_QUOTACTL=y
+CONFIG_AUTOFS_FS=y
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+# CONFIG_CUSE is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_UDF_NLS=y
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+# CONFIG_TMPFS is not set
+# CONFIG_HUGETLB_PAGE is not set
+CONFIG_CONFIGFS_FS=m
+CONFIG_MISC_FILESYSTEMS=y
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_ECRYPT_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_SQUASHFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+# CONFIG_NFS_V4_1 is not set
+CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_ACL_SUPPORT=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+CONFIG_SUNRPC_GSS=y
+CONFIG_RPCSEC_GSS_KRB5=y
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=y
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+# CONFIG_DETECT_SOFTLOCKUP is not set
+# CONFIG_DETECT_HUNG_TASK is not set
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_KMEMLEAK is not set
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+# CONFIG_DEBUG_SPINLOCK is not set
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_DEBUG_INFO is not set
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_DEBUG_NOTIFIERS is not set
+# CONFIG_DEBUG_CREDENTIALS is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
+# CONFIG_FAULT_INJECTION is not set
+# CONFIG_LATENCYTOP is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_PAGE_POISONING is not set
+CONFIG_HAVE_FUNCTION_TRACER=y
+CONFIG_TRACING_SUPPORT=y
+# CONFIG_FTRACE is not set
+# CONFIG_DYNAMIC_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+# CONFIG_ARM_UNWIND is not set
+# CONFIG_DEBUG_USER is not set
+# CONFIG_DEBUG_ERRORS is not set
+# CONFIG_DEBUG_STACK_USAGE is not set
+CONFIG_DEBUG_LL=y
+CONFIG_EARLY_PRINTK=y
+# CONFIG_DEBUG_ICEDCC is not set
+# CONFIG_OC_ETM is not set
+
+#
+# Security options
+#
+CONFIG_KEYS=y
+# CONFIG_KEYS_DEBUG_PROC_KEYS is not set
+# CONFIG_SECURITY is not set
+CONFIG_SECURITYFS=y
+# CONFIG_DEFAULT_SECURITY_SELINUX is not set
+# CONFIG_DEFAULT_SECURITY_SMACK is not set
+# CONFIG_DEFAULT_SECURITY_TOMOYO is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
+CONFIG_CRYPTO_AEAD2=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
+CONFIG_CRYPTO_PCOMP=y
+CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=y
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+CONFIG_CRYPTO_CRC32C=m
+# CONFIG_CRYPTO_GHASH is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ZLIB is not set
+CONFIG_CRYPTO_LZO=y
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_RATIONAL=y
+CONFIG_GENERIC_FIND_LAST_BIT=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC16=y
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC_ITU_T=m
+CONFIG_CRC32=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
-- 
1.6.3.3

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03  5:16   ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Amit Kucheria
  2010-02-03  5:16     ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Amit Kucheria
@ 2010-02-03  6:23     ` Eric Miao
  2010-02-03  9:45       ` Sascha Hauer
  2010-02-03 13:24       ` Amit Kucheria
  1 sibling, 2 replies; 40+ messages in thread
From: Eric Miao @ 2010-02-03  6:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Amit,

Just some nit-picking review comments, see below:

On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> Freescale i.MX51 processor uses a new interrupt controller. Add
> driver for TrustZone Interrupt Controller
>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/plat-mxc/Kconfig ?| ? ?8 ++
> ?arch/arm/plat-mxc/Makefile | ? ?3 +
> ?arch/arm/plat-mxc/tzic.c ? | ?182 ++++++++++++++++++++++++++++++++++++++++++++
> ?3 files changed, 193 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/plat-mxc/tzic.c
>
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index 8b0a1ee..59558c4 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
> ? ? ? ? ?requirements for timing.
> ? ? ? ? ?Say N here, unless you have a specialized requirement.
>
> +config MXC_TZIC
> + ? ? ? bool "Enable TrustZone Interrupt Controller"
> + ? ? ? depends on ARCH_MX51

This is the first patch of the base port, yet I cannot find any reference to
this ARCH_MX51, did you miss something?

> + ? ? ? help
> + ? ? ? ? This will be automatically selected for all processors
> + ? ? ? ? containing this interrupt controller.
> + ? ? ? ? Say N here only if you are really sure.
> +
> ?config MXC_PWM
> ? ? ? ?tristate "Enable PWM driver"
> ? ? ? ?depends on ARCH_MXC
> diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> index 996cbac..0202ad9 100644
> --- a/arch/arm/plat-mxc/Makefile
> +++ b/arch/arm/plat-mxc/Makefile
> @@ -5,6 +5,9 @@
> ?# Common support
> ?obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
>
> +# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
> +obj-$(CONFIG_MXC_TZIC) += tzic.o
> +
> ?obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
> ?obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
> ?obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> new file mode 100644
> index 0000000..00cb0ad
> --- /dev/null
> +++ b/arch/arm/plat-mxc/tzic.c
> @@ -0,0 +1,182 @@
> +/*
> + * Copyright 2004-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/io.h>
> +
> +#include <asm/mach/irq.h>
> +
> +#include <mach/hardware.h>
> +
> +/*
> + *****************************************
> + * TZIC Registers ? ? ? ? ? ? ? ? ? ? ? ?*
> + *****************************************
> + */
> +
> +#define TZIC_INTCNTL ? ? ? ? ? ?0x0000 /* Control register */
> +#define TZIC_INTTYPE ? ? ? ? ? ?0x0004 /* Controller Type register */
> +#define TZIC_IMPID ? ? ? ? ? ? ?0x0008 /* Distributor Implementer Identification */
> +#define TZIC_PRIOMASK ? ? ? ? ? 0x000C /* Priority Mask Reg */
> +#define TZIC_SYNCCTRL ? ? ? ? ? 0x0010 /* Synchronizer Control register */
> +#define TZIC_DSMINT ? ? ? ? ? ? 0x0014 /* DSM interrupt Holdoffregister */
> +#define TZIC_INTSEC0 ? ? ? ? ? ?0x0080 /* Interrupt Security register 0 */
> +#define TZIC_ENSET0 ? ? ? ? ? ? 0x0100 /* Enable Set Register 0 */
> +#define TZIC_ENCLEAR0 ? ? ? ? ? 0x0180 /* Enable Clear Register 0 */
> +#define TZIC_SRCSET0 ? ? ? ? ? ?0x0200 /* Source Set Register 0 */
> +#define TZIC_SRCCLAR0 ? ? ? ? ? 0x0280 /* Source Clear Register 0 */
> +#define TZIC_PRIORITY0 ? ? ? ? ?0x0400 /* Priority Register 0 */
> +#define TZIC_PND0 ? ? ? ? ? ? ? 0x0D00 /* Pending Register 0 */
> +#define TZIC_HIPND0 ? ? ? ? ? ? 0x0D80 /* High Priority Pending Register */
> +#define TZIC_WAKEUP0 ? ? ? ? ? ?0x0E00 /* Wakeup Config Register */
> +#define TZIC_SWINT ? ? ? ? ? ? ?0x0F00 /* Software Interrupt Rigger Register */
> +#define TZIC_ID0 ? ? ? ? ? ? ? ?0x0FD0 /* Indentification Register 0 */
> +
> +void __iomem *tzic_base;

This can just be made to 'static' if it's not used elsewhere, and I'm
wondering if it's neater to define them as:

#define TZIC_INTCNTL		(tzic_base + 0x0000)

so to make the code below short and handy.

> +
> +/*
> + * Disable interrupt number "irq" in the TZIC

I don't think this follows kernel API doc exactly, you may want to have a
look into Documentation/kernel-doc-nano-HOWTO.txt.

> + *
> + * @param ?irq ? ? ? ? ?interrupt source number
> + */
> +static void tzic_mask_irq(unsigned int irq)
> +{
> + ? ? ? int index, off;
> +
> + ? ? ? index = irq >> 5;
> + ? ? ? off = irq & 0x1F;
> + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0 + (index << 2));

I'll normally define TZIC_ENCLEAR0 then as:

#define TZIC_ENCLEAR(i)		(0x0180 + ((i) << 2))

so the above can be written as:

	__raw_writel(1 << off, tzic_base + TZIC_ENCLEAR(index));

or by including tzic_base into TZIC_*, simply as:

	__raw_writel(1 << off, TZIC_ENCLEAR(index));

> +}
> +
> +/*
> + * Enable interrupt number "irq" in the TZIC
> + *
> + * @param ?irq ? ? ? ? ?interrupt source number
> + */
> +static void tzic_unmask_irq(unsigned int irq)
> +{
> + ? ? ? int index, off;
> +
> + ? ? ? index = irq >> 5;
> + ? ? ? off = irq & 0x1F;
> + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENSET0 + (index << 2));
> +}
> +
> +static unsigned int wakeup_intr[4];
> +
> +/*
> + * Set interrupt number "irq" in the TZIC as a wake-up source.
> + *
> + * @param ?irq ? ? ? ? ?interrupt source number
> + * @param ?enable ? ? ? enable as wake-up if equal to non-zero
> + * ? ? ? ? ? ? ? ? ? ? disble as wake-up if equal to zero
> + *
> + * @return ? ? ? This function returns 0 on success.
> + */
> +static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
> +{
> + ? ? ? unsigned int index, off;
> +
> + ? ? ? index = irq >> 5;
> + ? ? ? off = irq & 0x1F;
> +
> + ? ? ? if (index > 3)
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? if (enable)
> + ? ? ? ? ? ? ? wakeup_intr[index] |= (1 << off);
> + ? ? ? else
> + ? ? ? ? ? ? ? wakeup_intr[index] &= ~(1 << off);
> +
> + ? ? ? return 0;
> +}
> +
> +static struct irq_chip mxc_tzic_chip = {
> + ? ? ? .name = "MXC_TZIC",
> + ? ? ? .ack = tzic_mask_irq,
> + ? ? ? .mask = tzic_mask_irq,
> + ? ? ? .unmask = tzic_unmask_irq,
> + ? ? ? .set_wake = tzic_set_wake_irq,
> +};
> +
> +/*
> + * This function initializes the TZIC hardware and disables all the
> + * interrupts. It registers the interrupt enable and disable functions
> + * to the kernel for each interrupt source.
> + */
> +void __init tzic_init_irq(void __iomem *irqbase)
> +{
> + ? ? ? int i;
> +
> + ? ? ? tzic_base = irqbase;
> + ? ? ? /* put the TZIC into the reset value with
> + ? ? ? ?* all interrupts disabled
> + ? ? ? ?*/
> + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);

Mixing the use of 'i' as both a signed counter and register value might
not be a good idea, provided it's not guaranteed from theory that 'i' as
an integer could not be sufficient to hold the value returned from
__raw_readl()

> +
> + ? ? ? __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
> + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);
> + ? ? ? __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
> + ? ? ? i = __raw_readl(tzic_base + TZIC_PRIOMASK);
> + ? ? ? __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
> + ? ? ? i = __raw_readl(tzic_base + TZIC_SYNCCTRL);

Are these read-back really necessary? We can start without them and add them
later if they do cause issues.

> +
> + ? ? ? for (i = 0; i < 4; i++)
> + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0 + i * 4);
> +
> + ? ? ? /* disable all interrupts */
> + ? ? ? for (i = 0; i < 4; i++)
> + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0 + i * 4);
> +
> + ? ? ? /* all IRQ no FIQ Warning :: No selection */
> +
> + ? ? ? for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
> + ? ? ? ? ? ? ? set_irq_chip(i, &mxc_tzic_chip);
> + ? ? ? ? ? ? ? set_irq_handler(i, handle_level_irq);
> + ? ? ? ? ? ? ? set_irq_flags(i, IRQF_VALID);
> + ? ? ? }
> +
> + ? ? ? printk(KERN_INFO "TrustZone Interrupt Controller (TZIC) initialized\n");

You may want to use pr_info() for short.

> +}
> +
> +/*
> + * enable wakeup interrupt
> + *
> + * @param is_idle ? ? ? ? ? ? ?1 if called in idle loop (ENSET register);
> + * ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 to be used when called from low power entry
> + * @return ? ? ? ? ? ? ? ? ? ? 0 if successful; non-zero otherwise
> + *
> + */
> +int tzic_enable_wake(int is_idle)
> +{
> + ? ? ? unsigned int i, v;
> +
> + ? ? ? __raw_writel(1, tzic_base + TZIC_DSMINT);
> + ? ? ? if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
> + ? ? ? ? ? ? ? return -EAGAIN;

Looks like an unnecessary read-back provided the silicon is sane enough.

> +
> + ? ? ? if (likely(is_idle)) {
> + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> + ? ? ? ? ? ? ? ? ? ? ? v = __raw_readl(tzic_base + TZIC_ENSET0 + i * 4);
> + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
> + ? ? ? ? ? ? ? }
> + ? ? ? } else {
> + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> + ? ? ? ? ? ? ? ? ? ? ? v = wakeup_intr[i];
> + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
> + ? ? ? ? ? ? ? }
> + ? ? ? }

Or could be simplified to:

	for (i = 0; i < 4; i++) {
		v = is_idle ? __raw_readl(TZIC_ENSET(i)) : wakeup_intr[i];
		__raw_writel(v, TZIC_WAKEUP(i));
	}

but just nit-picking comments, so it's up to you.

> + ? ? ? return 0;
> +}

Mmmm.... this being called elsewhere, I'm thinking about making this a
sys_device and having this called within sysdev_class.suspend() to make
this file rather self-contained.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller
  2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
@ 2010-02-03  6:29         ` Eric Miao
  2010-02-03  9:40           ` Sascha Hauer
  2010-02-03 16:27         ` Grant Likely
  2 siblings, 1 reply; 40+ messages in thread
From: Eric Miao @ 2010-02-03  6:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> i.MX51 defines 4 values:
>
> 00: Low Drive Strength
> 01: Medium Drive Strength
> 10: High Drive Strength
> 11: Max Drive Strength
>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/plat-mxc/include/mach/iomux-v3.h | ? ?8 +++++---
> ?1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> index 1deda01..f2f73d3 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> @@ -81,11 +81,13 @@ struct pad_desc {
>
> ?#define PAD_CTL_ODE ? ? ? ? ? ? ? ? ? ?(1 << 3)
>
> -#define PAD_CTL_DSE_STANDARD ? ? ? ? ? (0 << 1)
> -#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (1 << 1)
> -#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(2 << 1)
> +#define PAD_CTL_DSE_LOW ? ? ? ? ? ? ? ? ? ? ? ?(0 << 1)
> +#define PAD_CTL_DSE_MED ? ? ? ? ? ? ? ? ? ? ? ?(1 << 1)
> +#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (2 << 1)
> +#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(3 << 1)
>

I'm seeing some changes in recent kernel with introduction of PAD_CTL_DRV_*,
which also affects mx3, think it's a tough problem to keep backward
compatibility
now, one way out is to introduce maybe PAD_CTL_DRV_EXTREME specifically
for imx51.

> ?#define PAD_CTL_SRE_FAST ? ? ? ? ? ? ? (1 << 0)
> +#define PAD_CTL_SRE_SLOW ? ? ? ? ? ? ? (0 << 0)
>
> ?/*
> ?* setups a single pad in the iomuxer
> --
> 1.6.3.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
@ 2010-02-03  6:43           ` Eric Miao
  2010-02-03  9:49             ` Sascha Hauer
  2010-02-03 16:35           ` Grant Likely
  2 siblings, 1 reply; 40+ messages in thread
From: Eric Miao @ 2010-02-03  6:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> Changes separted to help in the review process
>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/plat-mxc/include/mach/common.h ? ? ?| ? ?4 +++
> ?arch/arm/plat-mxc/include/mach/debug-macro.S | ? ?9 +++++++
> ?arch/arm/plat-mxc/include/mach/entry-macro.S | ? 34 +++++++++++++++++++++++++-
> ?arch/arm/plat-mxc/include/mach/hardware.h ? ?| ? ?4 +++
> ?arch/arm/plat-mxc/include/mach/irqs.h ? ? ? ?| ? ?9 ++++++-
> ?arch/arm/plat-mxc/include/mach/memory.h ? ? ?| ? ?3 ++
> ?arch/arm/plat-mxc/include/mach/mxc.h ? ? ? ? | ? 13 ++++++++++
> ?arch/arm/plat-mxc/include/mach/timex.h ? ? ? | ? ?2 +
> ?arch/arm/plat-mxc/time.c ? ? ? ? ? ? ? ? ? ? | ? ?6 ++--
> ?9 files changed, 79 insertions(+), 5 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 286cb9b..5250a3f 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -20,8 +20,10 @@ 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 mx51_map_io(void);
> ?extern void mxc91231_map_io(void);
> ?extern void mxc_init_irq(void __iomem *);
> +extern void tzic_init_irq(void __iomem *);
> ?extern void mx1_init_irq(void);
> ?extern void mx21_init_irq(void);
> ?extern void mx25_init_irq(void);
> @@ -36,6 +38,8 @@ 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);
> +extern int mx51_clocks_init(unsigned long ckil, unsigned long osc,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned long ckih1, unsigned long ckih2);
> ?extern int mxc91231_clocks_init(unsigned long fref);
> ?extern int mxc_register_gpios(void);
> ?extern int mxc_register_device(struct platform_device *pdev, void *data);
> diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> index 15b2b14..9fe7300 100644
> --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> @@ -44,6 +44,15 @@
> ?#define UART_VADDR ? ? AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
> ?#endif
>
> +#ifdef CONFIG_ARCH_MX5
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#include <mach/mx51.h>
> +#define UART_PADDR ? ? UART1_BASE_ADDR
> +#define UART_VADDR ? ? AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
> +#endif
> +
> ?#ifdef CONFIG_ARCH_MXC91231
> ?#ifdef UART_PADDR
> ?#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index 7cf290e..aeb0869 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -1,6 +1,6 @@
> ?/*
> ?* ?Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
> - * ?Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * ?Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> ?*/
>
> ?/*
> @@ -18,11 +18,16 @@
> ? ? ? ?.endm
>
> ? ? ? ?.macro ?get_irqnr_preamble, base, tmp
> +#ifndef CONFIG_MXC_TZIC
> ? ? ? ?ldr ? ? \base, =avic_base
> ? ? ? ?ldr ? ? \base, [\base]
> ?#ifdef CONFIG_MXC_IRQ_PRIOR
> ? ? ? ?ldr ? ? r4, [\base, #AVIC_NIMASK]
> ?#endif
> +#elif defined CONFIG_MXC_TZIC
> + ? ? ? ldr ? ? \base, =tzic_base
> + ? ? ? ldr ? ? \base, [\base]
> +#endif /* CONFIG_MXC_TZIC */

Mmm.... this should be something that we really need to get rid of, it just
makes a single kernel for both TZIC and AVIC together impossible, if that's
so designed by HW, I'm thinking about keeping this into plat-mxc/ is a good
way to go ...

Sascha, you have any better idea? Provided the other file debug-macro.S in
the same directory already seems to break the support for multiple arches?

> ? ? ? ?.endm
>
> ? ? ? ?.macro ?arch_ret_to_user, tmp1, tmp2
> @@ -32,6 +37,7 @@
> ? ? ? ?@ and returns its number in irqnr
> ? ? ? ?@ and returns if an interrupt occured in irqstat
> ? ? ? ?.macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
> +#ifndef CONFIG_MXC_TZIC
> ? ? ? ?@ Load offset & priority of the highest priority
> ? ? ? ?@ interrupt pending from AVIC_NIVECSR
> ? ? ? ?ldr ? ? \irqstat, [\base, #0x40]
> @@ -45,6 +51,32 @@
> ? ? ? ?strne ? \tmp, [\base, #AVIC_NIMASK]
> ? ? ? ?streq ? r4, [\base, #AVIC_NIMASK]
> ?#endif
> +#elif defined CONFIG_MXC_TZIC
> + ? ? ? @ Load offset & priority of the highest priority
> + ? ? ? @ interrupt pending.
> + ? ? ? @ 0xD80 is HIPND0 register
> + ? ? ? mov ? ? \irqnr, #0
> + ? ? ? mov ? ? \irqstat, #0x0D80
> +1000:
> + ? ? ? ldr ? ? \tmp, ? [\irqstat, \base]
> + ? ? ? cmp ? ? \tmp, #0
> + ? ? ? bne ? ? 1001f
> + ? ? ? addeq ? \irqnr, \irqnr, #32
> + ? ? ? addeq ? \irqstat, \irqstat, #4
> + ? ? ? cmp ? ? \irqnr, #128
> + ? ? ? blo ? ? 1000b
> + ? ? ? b ? ? ? 2001f
> +1001: ?mov ? ? \irqstat, #1
> +1002: ?tst ? ? \tmp, \irqstat
> + ? ? ? bne ? ? 2002f
> + ? ? ? movs ? ?\tmp, \tmp, lsr #1
> + ? ? ? addne ? \irqnr, \irqnr, #1
> + ? ? ? bne ? ? 1002b
> +2001:
> + ? ? ? mov ?\irqnr, #0
> +2002:
> + ? ? ? movs \irqnr, \irqnr
> +#endif
> ? ? ? ?.endm
>
> ? ? ? ?@ irq priority table (not used)
> diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> index 78db754..55ebe88 100644
> --- a/arch/arm/plat-mxc/include/mach/hardware.h
> +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> @@ -22,6 +22,10 @@
>
> ?#include <asm/sizes.h>
>
> +#ifdef CONFIG_ARCH_MX5
> +#include <mach/mx51.h>
> +#endif
> +
> ?#ifdef CONFIG_ARCH_MX3
> ?#include <mach/mx3x.h>
> ?#include <mach/mx31.h>
> diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> index ead9d59..24c066e 100644
> --- a/arch/arm/plat-mxc/include/mach/irqs.h
> +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> @@ -12,9 +12,13 @@
> ?#define __ASM_ARCH_MXC_IRQS_H__
>
> ?/*
> - * So far all i.MX SoCs have 64 internal interrupts
> + * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> ?*/
> +#ifdef CONFIG_MXC_TZIC
> +#define MXC_INTERNAL_IRQS ? ? ?128
> +#else
> ?#define MXC_INTERNAL_IRQS ? ? ?64
> +#endif
>
> ?#define MXC_GPIO_IRQ_START ? ? MXC_INTERNAL_IRQS
>
> @@ -26,6 +30,8 @@
> ?#define MXC_GPIO_IRQS ? ? ? ? ?(32 * 3)
> ?#elif defined CONFIG_ARCH_MX25
> ?#define MXC_GPIO_IRQS ? ? ? ? ?(32 * 4)
> +#elif defined CONFIG_ARCH_MX5
> +#define MXC_GPIO_IRQS ? ? ? ? ?(32 * 4)
> ?#elif defined CONFIG_ARCH_MXC91231
> ?#define MXC_GPIO_IRQS ? ? ? ? ?(32 * 4)
> ?#endif
> @@ -46,6 +52,7 @@
> ?#else
> ?#define MX3_IPU_IRQS 0
> ?#endif
> +/* REVISIT: Add IPU irqs on IMX51 */
>
> ?#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ? ?(MXC_IPU_IRQ_START + MX3_IPU_IRQS)
>
> diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> index d3afafd..e46626e 100644
> --- a/arch/arm/plat-mxc/include/mach/memory.h
> +++ b/arch/arm/plat-mxc/include/mach/memory.h
> @@ -27,6 +27,9 @@
> ?#elif defined CONFIG_ARCH_MXC91231
> ?#define PHYS_OFFSET ? ? ? ? ? ?UL(0x90000000)
> ?#endif
> +#ifdef CONFIG_ARCH_MX5
> +#define PHYS_OFFSET ? ? ? ? ? ? UL(0x90000000)
> +#endif
>
> ?#if defined(CONFIG_MX1_VIDEO)
> ?/*
> diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> index 5199053..555e5f8 100644
> --- a/arch/arm/plat-mxc/include/mach/mxc.h
> +++ b/arch/arm/plat-mxc/include/mach/mxc.h
> @@ -30,6 +30,7 @@
> ?#define MXC_CPU_MX27 ? ? ? ? ? 27
> ?#define MXC_CPU_MX31 ? ? ? ? ? 31
> ?#define MXC_CPU_MX35 ? ? ? ? ? 35
> +#define MXC_CPU_MX51 ? ? ? ? ? 51
> ?#define MXC_CPU_MXC91231 ? ? ? 91231
>
> ?#ifndef __ASSEMBLY__
> @@ -108,6 +109,18 @@ extern unsigned int __mxc_cpu_type;
> ?# define cpu_is_mx35() ? ? ? ? (0)
> ?#endif
>
> +#ifdef CONFIG_ARCH_MX5
> +# ifdef mxc_cpu_type
> +# ?undef mxc_cpu_type
> +# ?define mxc_cpu_type __mxc_cpu_type
> +# else
> +# ?define mxc_cpu_type MXC_CPU_MX51
> +# endif
> +# define cpu_is_mx51() ? ? ? ? (mxc_cpu_type == MXC_CPU_MX51)
> +#else
> +# define cpu_is_mx51() ? ? ? ? (0)
> +#endif
> +
> ?#ifdef CONFIG_ARCH_MXC91231
> ?# ifdef mxc_cpu_type
> ?# ?undef mxc_cpu_type
> diff --git a/arch/arm/plat-mxc/include/mach/timex.h b/arch/arm/plat-mxc/include/mach/timex.h
> index 527a6c2..024416e 100644
> --- a/arch/arm/plat-mxc/include/mach/timex.h
> +++ b/arch/arm/plat-mxc/include/mach/timex.h
> @@ -28,6 +28,8 @@
> ?#define CLOCK_TICK_RATE ? ? ? ? ? ? ? ?16625000
> ?#elif defined CONFIG_ARCH_MX25
> ?#define CLOCK_TICK_RATE ? ? ? ? ? ? ? ?16000000
> +#elif defined CONFIG_ARCH_MX5
> +#define CLOCK_TICK_RATE ? ? ? ? ? ? ? ?8000000
> ?#elif defined CONFIG_ARCH_MXC91231
> ?#define CLOCK_TICK_RATE ? ? ? ? ? ? ? ?13000000
> ?#endif
> diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
> index 7d6499e..2ba8b29 100644
> --- a/arch/arm/plat-mxc/time.c
> +++ b/arch/arm/plat-mxc/time.c
> @@ -32,7 +32,7 @@
>
> ?/* defines common for all i.MX */
> ?#define MXC_TCTL ? ? ? ? ? ? ? 0x00
> -#define MXC_TCTL_TEN ? ? ? ? ? (1 << 0)
> +#define MXC_TCTL_TEN ? ? ? ? ? (1 << 0) /* Enable module */
> ?#define MXC_TPRER ? ? ? ? ? ? ?0x04
>
> ?/* MX1, MX21, MX27 */
> @@ -48,7 +48,7 @@
> ?#define MX2_TSTAT_COMP ? ? ? ? (1 << 0)
>
> ?/* MX31, MX35, MX25, MXC91231 */
> -#define MX3_TCTL_WAITEN ? ? ? ? ? ? ? ?(1 << 3)
> +#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
> @@ -58,7 +58,7 @@
> ?#define MX3_TCMP ? ? ? ? ? ? ? 0x10
>
> ?#define timer_is_v1() ?(cpu_is_mx1() || cpu_is_mx27())
> -#define timer_is_v2() ?(cpu_is_mx3() || cpu_is_mx25())
> +#define timer_is_v2() ?(cpu_is_mx3() || cpu_is_mx25() || cpu_is_mx51())
>
> ?static struct clock_event_device clockevent_mxc;
> ?static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> --
> 1.6.3.3
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
  2010-02-03  5:16             ` [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors Amit Kucheria
@ 2010-02-03  7:03             ` Eric Miao
  2010-02-03 14:20               ` Amit Kucheria
  2010-02-03  9:24             ` Russell King - ARM Linux
                               ` (2 subsequent siblings)
  4 siblings, 1 reply; 40+ messages in thread
From: Eric Miao @ 2010-02-03  7:03 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> From: Amit Kucheria <amit.kucheria@verdurent.com>
>
> Add basic clock support, cpu identification, I/O mapping and serial port.
>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/mach-mx5/clock.c ? ? ? ? ? ? ? ? ? ?| ?848 ++++++++++++++++++++++++++
> ?arch/arm/mach-mx5/cpu.c ? ? ? ? ? ? ? ? ? ? ?| ? 45 ++
> ?arch/arm/mach-mx5/crm_regs.h ? ? ? ? ? ? ? ? | ?583 ++++++++++++++++++
> ?arch/arm/mach-mx5/devices.c ? ? ? ? ? ? ? ? ?| ? 96 +++
> ?arch/arm/mach-mx5/devices.h ? ? ? ? ? ? ? ? ?| ? ?4 +
> ?arch/arm/mach-mx5/mm.c ? ? ? ? ? ? ? ? ? ? ? | ? 88 +++
> ?arch/arm/plat-mxc/include/mach/common.h ? ? ?| ? ?1 +
> ?arch/arm/plat-mxc/include/mach/debug-macro.S | ? ?4 +-
> ?arch/arm/plat-mxc/include/mach/iomux-mx51.h ?| ?340 +++++++++++
> ?arch/arm/plat-mxc/include/mach/mx51.h ? ? ? ?| ?454 ++++++++++++++
> ?10 files changed, 2461 insertions(+), 2 deletions(-)
> ?create mode 100644 arch/arm/mach-mx5/clock.c
> ?create mode 100644 arch/arm/mach-mx5/cpu.c
> ?create mode 100644 arch/arm/mach-mx5/crm_regs.h
> ?create mode 100644 arch/arm/mach-mx5/devices.c
> ?create mode 100644 arch/arm/mach-mx5/devices.h
> ?create mode 100644 arch/arm/mach-mx5/mm.c
> ?create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
> ?create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h
>
> diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
> new file mode 100644
> index 0000000..595f966
> --- /dev/null
> +++ b/arch/arm/mach-mx5/clock.c
> @@ -0,0 +1,848 @@
> +/*
> + * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +#include <asm/clkdev.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/clock.h>
> +
> +#include "crm_regs.h"
> +
> +static void __iomem *pll_base[] = {
> + ? ? ? MX51_DPLL1_BASE,
> + ? ? ? MX51_DPLL2_BASE,
> + ? ? ? MX51_DPLL3_BASE,
> +};
> +
> +/* External clock values passed-in by the board code */
> +static unsigned long external_high_reference, external_low_reference;
> +static unsigned long oscillator_reference, ckih2_reference;
> +
> +static struct clk osc_clk;
> +static struct clk pll1_main_clk;
> +static struct clk pll1_sw_clk;
> +static struct clk pll2_sw_clk;
> +static struct clk pll3_sw_clk;
> +static struct clk lp_apm_clk;
> +static struct clk periph_apm_clk;
> +static struct clk ahb_clk;
> +static struct clk ipg_clk;
> +
> +#define MAX_DPLL_WAIT_TRIES ? ?1000 /* 1000 * udelay(1) = 1ms */
> +
> +static int _clk_ccgr_enable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(clk->enable_reg);
> + ? ? ? reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
> + ? ? ? __raw_writel(reg, clk->enable_reg);
> +
> + ? ? ? return 0;
> +}
> +
> +static void _clk_ccgr_disable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> + ? ? ? reg = __raw_readl(clk->enable_reg);
> + ? ? ? reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
> + ? ? ? __raw_writel(reg, clk->enable_reg);
> +
> +}
> +
> +static void _clk_ccgr_disable_inwait(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(clk->enable_reg);
> + ? ? ? reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
> + ? ? ? reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
> + ? ? ? __raw_writel(reg, clk->enable_reg);
> +}
> +
> +/*
> + * For the 4-to-1 muxed input clock
> + */
> +static inline u32 _get_mux(struct clk *parent, struct clk *m0,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?struct clk *m1, struct clk *m2, struct clk *m3)
> +{
> + ? ? ? if (parent == m0)
> + ? ? ? ? ? ? ? return 0;
> + ? ? ? else if (parent == m1)
> + ? ? ? ? ? ? ? return 1;
> + ? ? ? else if (parent == m2)
> + ? ? ? ? ? ? ? return 2;
> + ? ? ? else if (parent == m3)
> + ? ? ? ? ? ? ? return 3;
> + ? ? ? else
> + ? ? ? ? ? ? ? BUG();
> +
> + ? ? ? return -EINVAL;
> +}
> +
> +static inline void __iomem *_get_pll_base(struct clk *pll)
> +{
> + ? ? ? if (pll == &pll1_main_clk)
> + ? ? ? ? ? ? ? return pll_base[0];
> + ? ? ? else if (pll == &pll2_sw_clk)
> + ? ? ? ? ? ? ? return pll_base[1];
> + ? ? ? else if (pll == &pll3_sw_clk)
> + ? ? ? ? ? ? ? return pll_base[2];
> + ? ? ? else
> + ? ? ? ? ? ? ? BUG();
> +
> + ? ? ? return NULL;
> +}
> +
> +static unsigned long clk_pll_get_rate(struct clk *clk)
> +{
> + ? ? ? long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
> + ? ? ? unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
> + ? ? ? void __iomem *pllbase;
> + ? ? ? s64 temp;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? pllbase = _get_pll_base(clk);
> +
> + ? ? ? dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> + ? ? ? pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> + ? ? ? dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
> +
> + ? ? ? if (pll_hfsm == 0) {
> + ? ? ? ? ? ? ? dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
> + ? ? ? ? ? ? ? dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
> + ? ? ? ? ? ? ? dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
> + ? ? ? } else {
> + ? ? ? ? ? ? ? dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
> + ? ? ? ? ? ? ? dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
> + ? ? ? ? ? ? ? dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
> + ? ? ? }
> + ? ? ? pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
> + ? ? ? mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
> + ? ? ? mfi = (mfi <= 5) ? 5 : mfi;
> + ? ? ? mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
> + ? ? ? mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
> + ? ? ? /* Sign extend to 32-bits */
> + ? ? ? if (mfn >= 0x04000000) {
> + ? ? ? ? ? ? ? mfn |= 0xFC000000;
> + ? ? ? ? ? ? ? mfn_abs = -mfn;
> + ? ? ? }
> +
> + ? ? ? ref_clk = 2 * parent_rate;
> + ? ? ? if (dbl != 0)
> + ? ? ? ? ? ? ? ref_clk *= 2;
> +
> + ? ? ? ref_clk /= (pdf + 1);
> + ? ? ? temp = (u64) ref_clk * mfn_abs;
> + ? ? ? do_div(temp, mfd + 1);
> + ? ? ? if (mfn < 0)
> + ? ? ? ? ? ? ? temp = -temp;
> + ? ? ? temp = (ref_clk * mfi) + temp;
> +
> + ? ? ? return temp;
> +}
> +
> +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
> +{
> + ? ? ? u32 reg;
> + ? ? ? void __iomem *pllbase;
> +
> + ? ? ? long mfi, pdf, mfn, mfd = 999999;
> + ? ? ? s64 temp64;
> + ? ? ? unsigned long quad_parent_rate;
> + ? ? ? unsigned long pll_hfsm, dp_ctl;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? pllbase = _get_pll_base(clk);
> +
> + ? ? ? quad_parent_rate = 4 * parent_rate;
> + ? ? ? pdf = mfi = -1;
> + ? ? ? while (++pdf < 16 && mfi < 5)
> + ? ? ? ? ? ? ? mfi = rate * (pdf+1) / quad_parent_rate;
> + ? ? ? if (mfi > 15)
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? pdf--;
> +
> + ? ? ? temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
> + ? ? ? do_div(temp64, quad_parent_rate/1000000);
> + ? ? ? mfn = (long)temp64;
> +
> + ? ? ? dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> + ? ? ? /* use dpdck0_2 */
> + ? ? ? __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
> + ? ? ? pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> + ? ? ? if (pll_hfsm == 0) {
> + ? ? ? ? ? ? ? reg = mfi << 4 | pdf;
> + ? ? ? ? ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
> + ? ? ? ? ? ? ? __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
> + ? ? ? ? ? ? ? __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
> + ? ? ? } else {
> + ? ? ? ? ? ? ? reg = mfi << 4 | pdf;
> + ? ? ? ? ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
> + ? ? ? ? ? ? ? __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
> + ? ? ? ? ? ? ? __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static int _clk_pll_enable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> + ? ? ? void __iomem *pllbase;
> + ? ? ? int i = 0;
> +
> + ? ? ? pllbase = _get_pll_base(clk);
> + ? ? ? reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
> + ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> +
> + ? ? ? /* Wait for lock */
> + ? ? ? while ((!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF))
> + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? i++;
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? }


Mmm... this really hurts my eyes:

	
	do {
		v = __raw_readl(pllbase + MXC_PLL_DP_CTL)
		if (v & MXC_PLL_DP_CTL_LRF)
			break;
		
		udelay(1);
	} while (++i < MAX_DPLL_WAIT_TRIES);

> +
> + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: pll locking failed\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static void _clk_pll_disable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> + ? ? ? void __iomem *pllbase;
> +
> + ? ? ? pllbase = _get_pll_base(clk);
> + ? ? ? reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
> + ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> +}
> +
> +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> +
> + ? ? ? /* When switching from pll_main_clk to a bypass clock, first select a
> + ? ? ? ? ?multiplexed clock in 'step_sel', then shift the glitchless mux
> + ? ? ? ? ?'pll1_sw_clk_sel'.
> + ? ? ? ? ?When switching back, do it in reverse order
> + ? ? ? */

comment style ... not sure if this leaks apw's checkscripts, heh :)

> + ? ? ? if (parent == &pll1_main_clk) {
> + ? ? ? ? ? ? ? /* Switch to pll1_main_clk */
> + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> + ? ? ? ? ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> + ? ? ? ? ? ? ? /* step_clk mux switched to lp_apm, to save power. */
> + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> + ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> + ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> + ? ? ? } else {
> + ? ? ? ? ? ? ? if (parent == &lp_apm_clk) {
> + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> + ? ? ? ? ? ? ? } else ?if (parent == &pll2_sw_clk) {
> + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED <<
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> + ? ? ? ? ? ? ? } else ?if (parent == &pll3_sw_clk) {
> + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> + ? ? ? ? ? ? ? } else
> + ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;

Again, hurts my eyes:

		if (...)
			step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
		else if (...)
			step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
		else if (...)
			step = ...

		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
		reg |= step << MXC_CCM_CCSR_STEP_SEL_OFFSET;
		...

> +
> + ? ? ? ? ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> + ? ? ? ? ? ? ? /* Switch to step_clk */
> + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> + ? ? ? ? ? ? ? reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> + ? ? ? }
> + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> + ? ? ? return 0;
> +}
> +
> +static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
> +{
> + ? ? ? u32 reg, div;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? div = 1;
> + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> +
> + ? ? ? if (clk->parent == &pll2_sw_clk) {
> + ? ? ? ? ? ? ? div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
> + ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
> + ? ? ? } else if (clk->parent == &pll3_sw_clk) {
> + ? ? ? ? ? ? ? div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
> + ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
> + ? ? ? }
> + ? ? ? return parent_rate / div;
> +}
> +
> +static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> +
> + ? ? ? if (parent == &pll2_sw_clk)
> + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> + ? ? ? else
> + ? ? ? ? ? ? ? reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> +
> + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> + ? ? ? return 0;
> +}
> +
> +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? if (parent == &osc_clk)
> + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
> + ? ? ? else
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> +
> + ? ? ? return 0;
> +}
> +
> +static unsigned long clk_arm_get_rate(struct clk *clk)
> +{
> + ? ? ? u32 cacrr, div;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> + ? ? ? cacrr = __raw_readl(MXC_CCM_CACRR);
> + ? ? ? div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
> +
> + ? ? ? return parent_rate / div;
> +}
> +
> +static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg, mux;
> + ? ? ? int i = 0;
> +
> + ? ? ? mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
> + ? ? ? reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
> + ? ? ? __raw_writel(reg, MXC_CCM_CBCMR);
> +
> + ? ? ? /* Wait for lock */
> + ? ? ? while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)
> + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? i++;
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? }
> +
> + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: Set parent for periph_apm clock failed\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static unsigned long clk_main_bus_get_rate(struct clk *clk)
> +{
> + ? ? ? return clk_get_rate(clk->parent);
> +}
> +
> +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> +
> + ? ? ? if (parent == &pll2_sw_clk)
> + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> + ? ? ? else if (parent == &periph_apm_clk)
> + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> + ? ? ? else
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> +
> + ? ? ? return 0;
> +}
> +
> +static struct clk main_bus_clk = {
> + ? ? ? .parent = &pll2_sw_clk,
> + ? ? ? .set_parent = _clk_main_bus_set_parent,
> + ? ? ? .get_rate = clk_main_bus_get_rate,
> +};
> +
> +static unsigned long clk_ahb_get_rate(struct clk *clk)
> +{
> + ? ? ? u32 reg, div;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> + ? ? ? div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
> + ? ? ? ? ? ? ?MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
> + ? ? ? return parent_rate / div;
> +}
> +
> +
> +static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
> +{
> + ? ? ? u32 reg, div;
> + ? ? ? unsigned long parent_rate;
> + ? ? ? int i = 0;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? div = parent_rate / rate;
> + ? ? ? if (div > 8 || div < 1 || ((parent_rate / div) != rate))
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> + ? ? ? reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
> + ? ? ? reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
> + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> +
> + ? ? ? /* Wait for lock */
> + ? ? ? while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY)
> + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? i++;
> + ? ? ? ? ? ? ? udelay(1);
> + ? ? ? }

Provided this loop sequence appears so many times here, maybe we can just
invent a static inline function for this, e.g. dpll_wait_flags(register, flags)

> +
> + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: clk_ahb_set_rate failed\n");
> + ? ? ? ? ? ? ? return -EINVAL;
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +static unsigned long _clk_ahb_round_rate(struct clk *clk,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned long rate)
> +{
> + ? ? ? u32 div;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? div = parent_rate / rate;
> + ? ? ? if (div > 8)
> + ? ? ? ? ? ? ? div = 8;
> + ? ? ? else if (div == 0)
> + ? ? ? ? ? ? ? div++;
> + ? ? ? return parent_rate / div;
> +}
> +
> +
> +static int _clk_max_enable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? _clk_ccgr_enable(clk);
> +
> + ? ? ? /* Handshake with MAX when LPM is entered. */
> + ? ? ? reg = __raw_readl(MXC_CCM_CLPCR);
> + ? ? ? reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
> + ? ? ? __raw_writel(reg, MXC_CCM_CLPCR);
> +
> + ? ? ? return 0;
> +}
> +
> +static void _clk_max_disable(struct clk *clk)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? _clk_ccgr_disable_inwait(clk);
> +
> + ? ? ? /* No Handshake with MAX when LPM is entered as its disabled. */
> + ? ? ? reg = __raw_readl(MXC_CCM_CLPCR);
> + ? ? ? reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
> + ? ? ? __raw_writel(reg, MXC_CCM_CLPCR);
> +}
> +
> +static unsigned long clk_ipg_get_rate(struct clk *clk)
> +{
> + ? ? ? u32 reg, div;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> + ? ? ? div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
> + ? ? ? ? ? ? ?MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
> +
> + ? ? ? return parent_rate / div;
> +}
> +
> +static unsigned long clk_ipg_per_get_rate(struct clk *clk)
> +{
> + ? ? ? u32 reg, prediv1, prediv2, podf;
> + ? ? ? unsigned long parent_rate;
> +
> + ? ? ? parent_rate = clk_get_rate(clk->parent);
> +
> + ? ? ? if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
> + ? ? ? ? ? ? ? /* the main_bus_clk is the one before the DVFS engine */
> + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> + ? ? ? ? ? ? ? prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
> + ? ? ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
> + ? ? ? ? ? ? ? prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
> + ? ? ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
> + ? ? ? ? ? ? ? podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
> + ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
> + ? ? ? ? ? ? ? return parent_rate / (prediv1 * prediv2 * podf);
> + ? ? ? } else if (clk->parent == &ipg_clk) {
> + ? ? ? ? ? ? ? return parent_rate;

unnecessary braces

> + ? ? ? } else {
> + ? ? ? ? ? ? ? BUG();

ditto

> + ? ? ? }
> +}
> +
> +static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR);
> +
> + ? ? ? reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
> + ? ? ? reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
> +
> + ? ? ? if (parent == &ipg_clk)
> + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
> + ? ? ? else if (parent == &lp_apm_clk)
> + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
> + ? ? ? else if (parent != &main_bus_clk)
> + ? ? ? ? ? ? ? return -EINVAL;
> +
> + ? ? ? __raw_writel(reg, MXC_CCM_CBCMR);
> +
> + ? ? ? return 0;
> +}
> +
> +static unsigned long clk_uart_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_UART_CLK_PRED_MASK) >>
> + ? ? ? ? ? ? ? ? MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
> + ? ? ? podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
> + ? ? ? ? ? ? ? MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
> +
> + ? ? ? return parent_rate / (prediv * podf);
> +}
> +
> +static int _clk_uart_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_UART_CLK_SEL_MASK;
> + ? ? ? reg |= mux << MXC_CCM_CSCMR1_UART_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;
> +}
> +
> +static unsigned long get_low_reference_clock_rate(struct clk *clk)
> +{
> + ? ? ? return external_low_reference;
> +}
> +
> +static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
> +{
> + ? ? ? return oscillator_reference;
> +}
> +
> +static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
> +{
> + ? ? ? return ckih2_reference;
> +}
> +
> +/* External high frequency clock */
> +static struct clk ckih_clk = {
> + ? ? ? .get_rate = get_high_reference_clock_rate,
> +};
> +
> +static struct clk ckih2_clk = {
> + ? ? ? .get_rate = get_ckih2_reference_clock_rate,
> +};
> +
> +static struct clk osc_clk = {
> + ? ? ? .get_rate = get_oscillator_reference_clock_rate,
> +};
> +
> +/* External low frequency (32kHz) clock */
> +static struct clk ckil_clk = {
> + ? ? ? .get_rate = get_low_reference_clock_rate,
> +};

That's why Jerremy is coming up with a clk_fixed, to address exactly such
awkward situations :)

> +
> +static struct clk pll1_main_clk = {
> + ? ? ? .parent = &osc_clk,
> + ? ? ? .get_rate = clk_pll_get_rate,
> + ? ? ? .enable = _clk_pll_enable,
> + ? ? ? .disable = _clk_pll_disable,
> +};
> +
> +/* Clock tree block diagram (WIP):
> + * ? ? CCM: Clock Controller Module
> + *
> + * PLL output -> |
> + * ? ? ? ? ? ? ? | CCM Switcher -> CCM_CLK_ROOT_GEN ->
> + * PLL bypass -> |
> + *
> + */
> +
> +/* PLL1 SW supplies to ARM core */
> +static struct clk pll1_sw_clk = {
> + ? ? ? .parent = &pll1_main_clk,
> + ? ? ? .set_parent = _clk_pll1_sw_set_parent,
> + ? ? ? .get_rate = clk_pll1_sw_get_rate,
> +};
> +
> +/* PLL2 SW supplies to AXI/AHB/IP buses */
> +static struct clk pll2_sw_clk = {
> + ? ? ? .parent = &osc_clk,
> + ? ? ? .get_rate = clk_pll_get_rate,
> + ? ? ? .set_rate = _clk_pll_set_rate,
> + ? ? ? .set_parent = _clk_pll2_sw_set_parent,
> + ? ? ? .enable = _clk_pll_enable,
> + ? ? ? .disable = _clk_pll_disable,
> +};
> +
> +/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
> +static struct clk pll3_sw_clk = {
> + ? ? ? .parent = &osc_clk,
> + ? ? ? .set_rate = _clk_pll_set_rate,
> + ? ? ? .get_rate = clk_pll_get_rate,
> + ? ? ? .enable = _clk_pll_enable,
> + ? ? ? .disable = _clk_pll_disable,
> +};
> +
> +/* Low-power Audio Playback Mode clock */
> +static struct clk lp_apm_clk = {
> + ? ? ? .parent = &osc_clk,
> + ? ? ? .set_parent = _clk_lp_apm_set_parent,
> +};
> +
> +static struct clk periph_apm_clk = {
> + ? ? ? .parent = &pll1_sw_clk,
> + ? ? ? .set_parent = _clk_periph_apm_set_parent,
> +};
> +
> +static struct clk cpu_clk = {
> + ? ? ? .parent = &pll1_sw_clk,
> + ? ? ? .get_rate = clk_arm_get_rate,
> +};
> +
> +static struct clk ahb_clk = {
> + ? ? ? .parent = &main_bus_clk,
> + ? ? ? .get_rate = clk_ahb_get_rate,
> + ? ? ? .set_rate = _clk_ahb_set_rate,
> + ? ? ? .round_rate = _clk_ahb_round_rate,
> +};
> +
> +/* Main IP interface clock for access to registers */
> +static struct clk ipg_clk = {
> + ? ? ? .parent = &ahb_clk,
> + ? ? ? .get_rate = clk_ipg_get_rate,
> +};
> +
> +static struct clk ipg_perclk = {
> + ? ? ? .parent = &lp_apm_clk,
> + ? ? ? .get_rate = clk_ipg_per_get_rate,
> + ? ? ? .set_parent = _clk_ipg_per_set_parent,
> +};
> +
> +static struct clk uart_root_clk = {
> + ? ? ? .parent = &pll2_sw_clk,
> + ? ? ? .get_rate = clk_uart_get_rate,
> + ? ? ? .set_parent = _clk_uart_set_parent,
> +};
> +
> +static struct clk ahb_max_clk = {
> + ? ? ? .parent = &ahb_clk,
> + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
> + ? ? ? .enable = _clk_max_enable,
> + ? ? ? .disable = _clk_max_disable,
> +};
> +
> +static struct clk aips_tz1_clk = {
> + ? ? ? .parent = &ahb_clk,
> + ? ? ? .secondary = &ahb_max_clk,
> + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
> + ? ? ? .enable = _clk_ccgr_enable,
> + ? ? ? .disable = _clk_ccgr_disable_inwait,
> +};
> +
> +static struct clk aips_tz2_clk = {
> + ? ? ? .parent = &ahb_clk,
> + ? ? ? .secondary = &ahb_max_clk,
> + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
> + ? ? ? .enable = _clk_ccgr_enable,
> + ? ? ? .disable = _clk_ccgr_disable_inwait,
> +};
> +
> +static struct clk gpt_32k_clk = {
> + ? ? ? .id = 0,
> + ? ? ? .parent = &ckil_clk,
> +};
> +
> +#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) ? ?\
> + ? ? ? static struct clk name = { ? ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? .id ? ? ? ? ? ? = i, ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? .enable_reg ? ? = er, ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .enable_shift ? = es, ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .get_rate ? ? ? = gr, ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .set_rate ? ? ? = sr, ? ? ? ? ? ? ? ? ? \
> + ? ? ? ? ? ? ? .enable ? ? ? ? = _clk_ccgr_enable, ? ? \
> + ? ? ? ? ? ? ? .disable ? ? ? ?= _clk_ccgr_disable, ? ?\
> + ? ? ? ? ? ? ? .parent ? ? ? ? = p, ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? ? ? ? ? .secondary ? ? ?= s, ? ? ? ? ? ? ? ? ? ?\
> + ? ? ? }
> +
> +/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
> + ? get_rate, set_rate, parent, secondary); */
> +
> +/* Shared peripheral bus arbiter */
> +DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> +
> +/* UART */
> +DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
> + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> +DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
> + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> +DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
> + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> +DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, &aips_tz1_clk);
> +DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, &aips_tz1_clk);
> +DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, &spba_clk);
> +
> +/* GPT */
> +DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_perclk, NULL);
> +DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> +
> +/* FEC */
> +DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
> + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> +
> +#define _REGISTER_CLOCK(d, n, c) \
> + ? ? ? { \
> + ? ? ? ? ? ? ? .dev_id = d, \
> + ? ? ? ? ? ? ? .con_id = n, \
> + ? ? ? ? ? ? ? .clk = &c, ? \
> + ? ? ? },
> +
> +static struct clk_lookup lookups[] __initdata = {
> + ? ? ? _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(NULL, "gpt", gpt_clk)
> + ? ? ? _REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +};
> +
> +static void clk_tree_init(void)
> +{
> + ? ? ? u32 reg;
> +
> + ? ? ? ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
> +
> + ? ? ? /*
> + ? ? ? ?* Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
> + ? ? ? ?* 8MHz, its derived from lp_apm.
> + ? ? ? ?* FIXME: Verify if true for all boards
> + ? ? ? ?*/
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
> + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
> + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
> + ? ? ? reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
> + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> +
> + ? ? ? /* set parent for pll1, pll2 and pll3 */
> + ? ? ? pll1_main_clk.parent = &osc_clk;
> + ? ? ? pll2_sw_clk.parent = &osc_clk;
> + ? ? ? pll3_sw_clk.parent = &osc_clk;
> +
> + ? ? ? /* set ipg_perclk parent */
> + ? ? ? ipg_perclk.parent = &lp_apm_clk;
> + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR);
> + ? ? ? if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
> + ? ? ? ? ? ? ? ipg_perclk.parent = &ipg_clk;
> + ? ? ? } else {
> + ? ? ? ? ? ? ? if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
> + ? ? ? ? ? ? ? ? ? ? ? ipg_perclk.parent = &main_bus_clk;
> + ? ? ? }
> +}
> +
> +int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> + ? ? ? ? ? ? ? ? ? ? ? unsigned long ckih1, unsigned long ckih2)
> +{
> + ? ? ? int i;
> +
> + ? ? ? external_low_reference = ckil;
> + ? ? ? external_high_reference = ckih1;
> + ? ? ? ckih2_reference = ckih2;
> + ? ? ? oscillator_reference = osc;
> +
> + ? ? ? for (i = 0; i < ARRAY_SIZE(lookups); i++)
> + ? ? ? ? ? ? ? clkdev_add(&lookups[i]);
> +
> + ? ? ? clk_tree_init();
> +
> + ? ? ? clk_enable(&cpu_clk);
> + ? ? ? clk_enable(&main_bus_clk);
> +
> + ? ? ? /* System timer */
> + ? ? ? mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> + ? ? ? ? ? ? ? MX51_MXC_INT_GPT);
> + ? ? ? return 0;
> +}
> diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
> new file mode 100644
> index 0000000..93f1d5a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/cpu.c
> @@ -0,0 +1,45 @@
> +/*
> + * Copyright 2008-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + *
> + * This file contains the CPU initialization code.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <mach/hardware.h>
> +#include <asm/io.h>
> +
> +static int __init post_cpu_init(void)
> +{
> + ? ? ? unsigned int reg;
> + ? ? ? void __iomem *base;
> +
> + ? ? ? if (cpu_is_mx51()) {
> + ? ? ? ? ? ? ? base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x40);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x44);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x48);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x4C);
> + ? ? ? ? ? ? ? reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> + ? ? ? ? ? ? ? __raw_writel(reg, base + 0x50);
> +
> + ? ? ? ? ? ? ? base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x40);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x44);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x48);
> + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x4C);
> + ? ? ? ? ? ? ? reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> + ? ? ? ? ? ? ? __raw_writel(reg, base + 0x50);
> + ? ? ? }
> + ? ? ? return 0;
> +}
> +
> +postcore_initcall(post_cpu_init);
> diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
> new file mode 100644
> index 0000000..c776b9a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/crm_regs.h
> @@ -0,0 +1,583 @@
> +/*
> + * Copyright 2008-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
> +#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
> +
> +#define MX51_CCM_BASE ? ? ? ? ?MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
> +#define MX51_DPLL1_BASE ? ? ? ? ? ? ? ?MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
> +#define MX51_DPLL2_BASE ? ? ? ? ? ? ? ?MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)

.... skipping register definitions ....

> +#define MXC_SRPGC_EMI_PUPSCR ? (MXC_SRPGC_EMI_BASE + 0x4)
> +#define MXC_SRPGC_EMI_PDNSCR ? (MXC_SRPGC_EMI_BASE + 0x8)
> +
> +#endif ? ? ? ? ? ? ? ? ? ? ? ? /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
> diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> new file mode 100644
> index 0000000..55eb089
> --- /dev/null
> +++ b/arch/arm/mach-mx5/devices.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/platform_device.h>
> +#include <mach/hardware.h>
> +#include <mach/imx-uart.h>
> +
> +static struct resource uart0[] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .start = MX51_UART1_BASE_ADDR,
> + ? ? ? ? ? ? ? .end = MX51_UART1_BASE_ADDR + 0x0B5,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART1,
> + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART1,
> + ? ? ? ? ? ? ? .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 = MX51_UART2_BASE_ADDR,
> + ? ? ? ? ? ? ? .end = MX51_UART2_BASE_ADDR + 0x0B5,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART2,
> + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART2,
> + ? ? ? ? ? ? ? .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 = MX51_UART3_BASE_ADDR,
> + ? ? ? ? ? ? ? .end = MX51_UART3_BASE_ADDR + 0x0B5,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART3,
> + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART3,
> + ? ? ? ? ? ? ? .flags = IORESOURCE_IRQ,
> + ? ? ? },
> +};
> +
> +struct platform_device mxc_uart_device2 = {
> + ? ? ? .name = "imx-uart",
> + ? ? ? .id = 2,
> + ? ? ? .resource = uart2,
> + ? ? ? .num_resources = ARRAY_SIZE(uart2),
> +};
> +
> +static struct resource mxc_fec_resources[] = {
> + ? ? ? {
> + ? ? ? ? ? ? ? .start ?= MX51_MXC_FEC_BASE_ADDR,
> + ? ? ? ? ? ? ? .end ? ?= MX51_MXC_FEC_BASE_ADDR + 0xfff,
> + ? ? ? ? ? ? ? .flags ?= IORESOURCE_MEM,
> + ? ? ? }, {
> + ? ? ? ? ? ? ? .start ?= MX51_MXC_INT_FEC,
> + ? ? ? ? ? ? ? .end ? ?= MX51_MXC_INT_FEC,
> + ? ? ? ? ? ? ? .flags ?= IORESOURCE_IRQ,
> + ? ? ? },
> +};
> +
> +struct platform_device mxc_fec_device = {
> + ? ? ? .name = "fec",
> + ? ? ? .id = 0,
> + ? ? ? .num_resources = ARRAY_SIZE(mxc_fec_resources),
> + ? ? ? .resource = mxc_fec_resources,
> +};
> +
> +/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
> +int __init mxc_register_gpios(void)
> +{
> + ? ? ? return 0;
> +}
> diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> new file mode 100644
> index 0000000..f339ab8
> --- /dev/null
> +++ b/arch/arm/mach-mx5/devices.h
> @@ -0,0 +1,4 @@
> +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;
> diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
> new file mode 100644
> index 0000000..d66c31a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/mm.c
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright 2008-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + *
> + * Create static mapping between physical to virtual memory.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/init.h>
> +
> +#include <asm/mach/map.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-v3.h>
> +
> +/*
> + * Define the MX51 memory map.
> + */
> +static struct map_desc mxc_io_desc[] __initdata = {
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_IRAM_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
> + ? ? ? ?.length = MX51_IRAM_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_DEBUG_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
> + ? ? ? ?.length = MX51_DEBUG_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_TZIC_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
> + ? ? ? ?.length = MX51_TZIC_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
> + ? ? ? ?.length = MX51_AIPS1_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_SPBA0_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
> + ? ? ? ?.length = MX51_SPBA0_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_AIPS2_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
> + ? ? ? ?.length = MX51_AIPS2_SIZE,
> + ? ? ? ?.type = MT_DEVICE},
> + ? ? ? {
> + ? ? ? ?.virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
> + ? ? ? ?.pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
> + ? ? ? ?.length = MX51_NFC_AXI_SIZE,
> + ? ? ? ?.type = MT_DEVICE},

Weird alignment, guess due to leading white spaces?


.... skipping the rest ....

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
  2010-02-03  5:16             ` [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors Amit Kucheria
  2010-02-03  7:03             ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Eric Miao
@ 2010-02-03  9:24             ` Russell King - ARM Linux
  2010-02-03 11:04             ` Sascha Hauer
  2010-02-03 16:08             ` Rabin Vincent
  4 siblings, 0 replies; 40+ messages in thread
From: Russell King - ARM Linux @ 2010-02-03  9:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 09:16:27PM -0800, Amit Kucheria wrote:
> +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	u32 reg;
> +	void __iomem *pllbase;
> +
> +	long mfi, pdf, mfn, mfd = 999999;
> +	s64 temp64;
> +	unsigned long quad_parent_rate;
> +	unsigned long pll_hfsm, dp_ctl;
> +	unsigned long parent_rate;
> +
> +	parent_rate = clk_get_rate(clk->parent);
> +
> +	pllbase = _get_pll_base(clk);
> +
> +	quad_parent_rate = 4 * parent_rate;
> +	pdf = mfi = -1;
> +	while (++pdf < 16 && mfi < 5)
> +		mfi = rate * (pdf+1) / quad_parent_rate;
> +	if (mfi > 15)
> +		return -1;

Why not "return -EPERM" since what you're actually saying here by
returning -1 is "Permission Denied"?  If you didn't mean "Permission
Denied", then don't use return -1.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller
  2010-02-03  6:29         ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Eric Miao
@ 2010-02-03  9:40           ` Sascha Hauer
  0 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-02-03  9:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 10:29:50PM -0800, Eric Miao wrote:
> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
> > i.MX51 defines 4 values:
> >
> > 00: Low Drive Strength
> > 01: Medium Drive Strength
> > 10: High Drive Strength
> > 11: Max Drive Strength
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/plat-mxc/include/mach/iomux-v3.h | ? ?8 +++++---
> > ?1 files changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > index 1deda01..f2f73d3 100644
> > --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > @@ -81,11 +81,13 @@ struct pad_desc {
> >
> > ?#define PAD_CTL_ODE ? ? ? ? ? ? ? ? ? ?(1 << 3)
> >
> > -#define PAD_CTL_DSE_STANDARD ? ? ? ? ? (0 << 1)
> > -#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (1 << 1)
> > -#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(2 << 1)
> > +#define PAD_CTL_DSE_LOW ? ? ? ? ? ? ? ? ? ? ? ?(0 << 1)
> > +#define PAD_CTL_DSE_MED ? ? ? ? ? ? ? ? ? ? ? ?(1 << 1)
> > +#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (2 << 1)
> > +#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(3 << 1)
> >
> 
> I'm seeing some changes in recent kernel with introduction of PAD_CTL_DRV_*,
> which also affects mx3, think it's a tough problem to keep backward
> compatibility
> now, one way out is to introduce maybe PAD_CTL_DRV_EXTREME specifically
> for imx51.

Given that the values are the same on i.MX3 and i.MX51 we could also
do a

#define PAD_CTL_DSE(x)	((x) << 1)

and add a comment for allowed values 0..2 for i.MX3 and 0..3 for i.MX51.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03  6:23     ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Eric Miao
@ 2010-02-03  9:45       ` Sascha Hauer
  2010-02-03 13:24       ` Amit Kucheria
  1 sibling, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-02-03  9:45 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 10:23:21PM -0800, Eric Miao wrote:
> Hi Amit,
> 
> Just some nit-picking review comments, see below:
> 
> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
> > Freescale i.MX51 processor uses a new interrupt controller. Add
> > driver for TrustZone Interrupt Controller
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/plat-mxc/Kconfig ?| ? ?8 ++
> > ?arch/arm/plat-mxc/Makefile | ? ?3 +
> > ?arch/arm/plat-mxc/tzic.c ? | ?182 ++++++++++++++++++++++++++++++++++++++++++++
> > ?3 files changed, 193 insertions(+), 0 deletions(-)
> > ?create mode 100644 arch/arm/plat-mxc/tzic.c
> >
> > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> > index 8b0a1ee..59558c4 100644
> > --- a/arch/arm/plat-mxc/Kconfig
> > +++ b/arch/arm/plat-mxc/Kconfig
> > @@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
> > ? ? ? ? ?requirements for timing.
> > ? ? ? ? ?Say N here, unless you have a specialized requirement.
> >
> > +config MXC_TZIC
> > + ? ? ? bool "Enable TrustZone Interrupt Controller"
> > + ? ? ? depends on ARCH_MX51
> 
> This is the first patch of the base port, yet I cannot find any reference to
> this ARCH_MX51, did you miss something?
> 
> > + ? ? ? help
> > + ? ? ? ? This will be automatically selected for all processors
> > + ? ? ? ? containing this interrupt controller.
> > + ? ? ? ? Say N here only if you are really sure.
> > +
> > ?config MXC_PWM
> > ? ? ? ?tristate "Enable PWM driver"
> > ? ? ? ?depends on ARCH_MXC
> > diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> > index 996cbac..0202ad9 100644
> > --- a/arch/arm/plat-mxc/Makefile
> > +++ b/arch/arm/plat-mxc/Makefile
> > @@ -5,6 +5,9 @@
> > ?# Common support
> > ?obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
> >
> > +# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
> > +obj-$(CONFIG_MXC_TZIC) += tzic.o
> > +
> > ?obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> > diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> > new file mode 100644
> > index 0000000..00cb0ad
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/tzic.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + * Copyright 2004-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/init.h>
> > +#include <linux/device.h>
> > +#include <linux/errno.h>
> > +#include <linux/io.h>
> > +
> > +#include <asm/mach/irq.h>
> > +
> > +#include <mach/hardware.h>
> > +
> > +/*
> > + *****************************************
> > + * TZIC Registers ? ? ? ? ? ? ? ? ? ? ? ?*
> > + *****************************************
> > + */
> > +
> > +#define TZIC_INTCNTL ? ? ? ? ? ?0x0000 /* Control register */
> > +#define TZIC_INTTYPE ? ? ? ? ? ?0x0004 /* Controller Type register */
> > +#define TZIC_IMPID ? ? ? ? ? ? ?0x0008 /* Distributor Implementer Identification */
> > +#define TZIC_PRIOMASK ? ? ? ? ? 0x000C /* Priority Mask Reg */
> > +#define TZIC_SYNCCTRL ? ? ? ? ? 0x0010 /* Synchronizer Control register */
> > +#define TZIC_DSMINT ? ? ? ? ? ? 0x0014 /* DSM interrupt Holdoffregister */
> > +#define TZIC_INTSEC0 ? ? ? ? ? ?0x0080 /* Interrupt Security register 0 */
> > +#define TZIC_ENSET0 ? ? ? ? ? ? 0x0100 /* Enable Set Register 0 */
> > +#define TZIC_ENCLEAR0 ? ? ? ? ? 0x0180 /* Enable Clear Register 0 */
> > +#define TZIC_SRCSET0 ? ? ? ? ? ?0x0200 /* Source Set Register 0 */
> > +#define TZIC_SRCCLAR0 ? ? ? ? ? 0x0280 /* Source Clear Register 0 */
> > +#define TZIC_PRIORITY0 ? ? ? ? ?0x0400 /* Priority Register 0 */
> > +#define TZIC_PND0 ? ? ? ? ? ? ? 0x0D00 /* Pending Register 0 */
> > +#define TZIC_HIPND0 ? ? ? ? ? ? 0x0D80 /* High Priority Pending Register */
> > +#define TZIC_WAKEUP0 ? ? ? ? ? ?0x0E00 /* Wakeup Config Register */
> > +#define TZIC_SWINT ? ? ? ? ? ? ?0x0F00 /* Software Interrupt Rigger Register */
> > +#define TZIC_ID0 ? ? ? ? ? ? ? ?0x0FD0 /* Indentification Register 0 */
> > +
> > +void __iomem *tzic_base;
> 
> This can just be made to 'static' if it's not used elsewhere, and I'm
> wondering if it's neater to define them as:

It is used in entry-macro.S for the irq controller base. We should add a
comment to make this clear.

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03  6:43           ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Eric Miao
@ 2010-02-03  9:49             ` Sascha Hauer
  2010-02-03 13:38               ` Amit Kucheria
  0 siblings, 1 reply; 40+ messages in thread
From: Sascha Hauer @ 2010-02-03  9:49 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 10:43:33PM -0800, Eric Miao wrote:
> 
> Mmm.... this should be something that we really need to get rid of, it just
> makes a single kernel for both TZIC and AVIC together impossible, if that's
> so designed by HW, I'm thinking about keeping this into plat-mxc/ is a good
> way to go ...
> 
> Sascha, you have any better idea? Provided the other file debug-macro.S in
> the same directory already seems to break the support for multiple arches?
> 

I have the following patch which I'm not sure I like better. It can
support both irq controller types and does not add overhead if only one
of them is compiled in. It might need some refactoring to fit into Amits
patch stack.

Sascha


commit c30ed01dcd257bba813b27a423bc54d5f32fc878
Author: Sascha Hauer <s.hauer@pengutronix.de>
Date:   Tue Nov 17 16:23:24 2009 +0100

    MXC tzic support
    
    Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>

diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index ebe4b8c..377f792 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -84,4 +84,7 @@ config ARCH_MXC_IOMUX_V3
 config ARCH_MXC_AVIC
 	bool
 
+config ARCH_MXC_TZIC
+	bool
+
 endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 325d9da..37ce6ec 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -9,4 +9,5 @@ obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
+obj-$(CONFIG_ARCH_MXC_TZIC) += tzic.o
 obj-$(CONFIG_ARCH_MXC_AVIC) += irq.o
diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
index b073b7d..d46325e 100644
--- a/arch/arm/plat-mxc/cpu.c
+++ b/arch/arm/plat-mxc/cpu.c
@@ -11,4 +11,5 @@ void mxc_set_cpu_type(unsigned int type)
 }
 
 void __iomem *mxc_irq_base;
+int mxc_irq_controller_type;
 
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 286cb9b..d395763 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -44,5 +44,5 @@ extern void mxc_arch_reset_init(void __iomem *);
 extern void mxc91231_power_off(void);
 extern void mxc91231_arch_reset(int, const char *);
 extern void mxc91231_prepare_idle(void);
-
+extern void tzic_init_irq(void __iomem *);
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 55375df..049f740 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -13,6 +13,9 @@
 
 #define AVIC_NIMASK	0x04
 
+#define TZIC_HIPND0 0xd80
+
+
 	@ this macro disables fast irq (not implemented)
 	.macro	disable_fiq
 	.endm
@@ -28,10 +31,35 @@
 	.macro  arch_ret_to_user, tmp1, tmp2
 	.endm
 
-	@ this macro checks which interrupt occured
-	@ and returns its number in irqnr
-	@ and returns if an interrupt occured in irqstat
-	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
+	.macro	tzic_get_irqnr_and_base, irqnr, irqstat, base, tmp
+
+	@ Load offset & priority of the highest priority
+	@ interrupt pending.
+	ldr     \irqnr, =0
+	ldr     \irqstat, =TZIC_HIPND0
+1000:
+	ldr     \tmp,   [\base, \irqstat]
+	cmp     \tmp, #0
+	bne     1001f
+	addeq   \irqnr, \irqnr, #32
+	addeq   \irqstat, \irqstat, #4
+	cmp     \irqnr, #128
+	blo     1000b
+	b       2001f
+1001:	ldr     \irqstat, =1
+1002:	tst     \tmp, \irqstat
+	bne     2002f
+	movs    \irqstat, \irqstat, lsl #1
+	addne   \irqnr, \irqnr, #1
+	bne     1002b
+2001:
+	ldr  \irqnr, =0
+2002:
+	movs \irqnr, \irqnr
+	.endm
+
+	.macro	avic_get_irqnr_and_base, irqnr, irqstat, base, tmp
+
 	@ Load offset & priority of the highest priority
 	@ interrupt pending from AVIC_NIVECSR
 	ldr	\irqstat, [\base, #0x40]
@@ -47,6 +75,28 @@
 #endif
 	.endm
 
+	.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#if defined CONFIG_ARCH_MXC_TZIC && defined CONFIG_ARCH_MXC_AVIC
+	ldr	\tmp, =mxc_irq_controller_type
+	ldr	\tmp, [\tmp]
+	cmp	\tmp, #MXC_IRQ_TYPE_AVIC
+	beq	3001f
+
+	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+	b	3002f
+3001:
+	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+3002:
+
+#elif defined CONFIG_ARCH_MXC_TZIC
+	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#elif defined CONFIG_ARCH_MXC_AVIC
+	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#else
+#error no tzic and no avic?
+#endif
+	.endm
+
 	@ irq priority table (not used)
 	.macro	irq_prio_table
 	.endm
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index b64a269..6cf0f98 100644
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -129,8 +129,12 @@ extern unsigned int __mxc_cpu_type;
 #define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
 #define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
 
+#define	MXC_IRQ_TYPE_AVIC	1
+#define	MXC_IRQ_TYPE_TZIC	2
+
 #ifndef __ASSEMBLY__
 extern void __iomem *mxc_irq_base;
+extern int mxc_irq_controller_type;
 #endif
 
 #endif /*  __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index 4855a65..3e7ac84 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -116,6 +116,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
 	int i;
 
 	mxc_irq_base = irqbase;
+	mxc_irq_controller_type = MXC_IRQ_TYPE_AVIC;
 
 	/* put the AVIC into the reset value with
 	 * all interrupts disabled
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
new file mode 100644
index 0000000..2d14af4
--- /dev/null
+++ b/arch/arm/plat-mxc/tzic.c
@@ -0,0 +1,104 @@
+/*
+ *  Copyright 2004-2008 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
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+
+extern void __iomem *mxc_irq_base;
+extern int mxc_irq_controller_type;
+
+#define TZIC_INTCNTL            0x0000	/* control register */
+#define TZIC_INTTYPE            0x0004	/* Controller type register */
+#define TZIC_IMPID              0x0008	/* Distributor Implementer Identification Register */
+#define TZIC_PRIOMASK           0x000c	/* Priority Mask Reg */
+#define TZIC_SYNCCTRL           0x0010	/* Synchronizer Control register */
+#define TZIC_DSMINT             0x0014	/* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0            0x0080	/* interrupt security register 0 */
+#define TZIC_ENSET0             0x0100	/* Enable Set Register 0 */
+#define TZIC_ENCLEAR0           0x0180	/* Enable Clear Register 0 */
+#define TZIC_SRCSET0            0x0200	/* Source Set Register 0 */
+#define TZIC_SRCCLAR0           0x0280	/* Source Clear Register 0 */
+#define TZIC_PRIORITY0          0x0400	/* Priority Register 0 */
+#define TZIC_PND0               0x0d00	/* Pending Register 0 */
+#define TZIC_HIPND0             0x0d80	/* High Priority Pending Register */
+#define TZIC_WAKEUP0            0x0e00	/* Wakeup Config Register */
+#define TZIC_SWINT              0x0f00	/* Software Interrupt Rigger Register */
+#define TZIC_ID0                0x0fd0	/* Indentification Register 0 */
+
+static void mxc_mask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, mxc_irq_base + TZIC_ENCLEAR0 + (index << 2));
+}
+
+static void mxc_unmask_irq(unsigned int irq)
+{
+	int index, off;
+
+	index = irq >> 5;
+	off = irq & 0x1F;
+	__raw_writel(1 << off, mxc_irq_base + TZIC_ENSET0 + (index << 2));
+}
+
+static struct irq_chip mxc_tzic_chip = {
+	.name = "MXC_TZIC",
+	.ack = mxc_mask_irq,
+	.mask = mxc_mask_irq,
+	.unmask = mxc_unmask_irq,
+};
+
+void __init tzic_init_irq(void __iomem *base)
+{
+	int i;
+
+	mxc_irq_base = base;
+	mxc_irq_controller_type = MXC_IRQ_TYPE_TZIC;
+
+	/* put the TZIC into the reset value with
+	 * all interrupts disabled
+	 */
+	__raw_readl(mxc_irq_base + TZIC_INTCNTL);
+
+	__raw_writel(0x80010001, mxc_irq_base + TZIC_INTCNTL);
+	__raw_readl(mxc_irq_base + TZIC_INTCNTL);
+	__raw_writel(0x1f, mxc_irq_base + TZIC_PRIOMASK);
+	__raw_readl(mxc_irq_base + TZIC_PRIOMASK);
+	__raw_writel(0x02, mxc_irq_base + TZIC_SYNCCTRL);
+	__raw_readl(mxc_irq_base + TZIC_SYNCCTRL);
+
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xffffffff, mxc_irq_base + TZIC_INTSEC0 + i * 4);
+
+	/* disable all interrupts */
+	for (i = 0; i < 4; i++)
+		__raw_writel(0xffffffff, mxc_irq_base + TZIC_ENCLEAR0 + i * 4);
+
+	for (i = 0; i < 128; i++) {
+		set_irq_chip(i, &mxc_tzic_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+
+	printk(KERN_INFO "MXC IRQ initialized\n");
+}
-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply related	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
                               ` (2 preceding siblings ...)
  2010-02-03  9:24             ` Russell King - ARM Linux
@ 2010-02-03 11:04             ` Sascha Hauer
  2010-02-03 20:07               ` Amit Kucheria
  2010-02-03 16:08             ` Rabin Vincent
  4 siblings, 1 reply; 40+ messages in thread
From: Sascha Hauer @ 2010-02-03 11:04 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 09:16:27PM -0800, Amit Kucheria wrote:
> From: Amit Kucheria <amit.kucheria@verdurent.com>
> 
> Add basic clock support, cpu identification, I/O mapping and serial port.
> 
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
>  arch/arm/mach-mx5/clock.c                    |  848 ++++++++++++++++++++++++++
>  arch/arm/mach-mx5/cpu.c                      |   45 ++
>  arch/arm/mach-mx5/crm_regs.h                 |  583 ++++++++++++++++++
>  arch/arm/mach-mx5/devices.c                  |   96 +++
>  arch/arm/mach-mx5/devices.h                  |    4 +
>  arch/arm/mach-mx5/mm.c                       |   88 +++
>  arch/arm/plat-mxc/include/mach/common.h      |    1 +
>  arch/arm/plat-mxc/include/mach/debug-macro.S |    4 +-
>  arch/arm/plat-mxc/include/mach/iomux-mx51.h  |  340 +++++++++++
>  arch/arm/plat-mxc/include/mach/mx51.h        |  454 ++++++++++++++
>  10 files changed, 2461 insertions(+), 2 deletions(-)
>  create mode 100644 arch/arm/mach-mx5/clock.c
>  create mode 100644 arch/arm/mach-mx5/cpu.c
>  create mode 100644 arch/arm/mach-mx5/crm_regs.h
>  create mode 100644 arch/arm/mach-mx5/devices.c
>  create mode 100644 arch/arm/mach-mx5/devices.h
>  create mode 100644 arch/arm/mach-mx5/mm.c
>  create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
>  create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h
> 
> diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c

Can we rename this file to clock-mx51.c? We made this mistake on other
i.MX platforms and ended with a clock.c and a clock-mx35.c in the same
directory.

> new file mode 100644
> index 0000000..595f966
> --- /dev/null
> +++ b/arch/arm/mach-mx5/clock.c
> @@ -0,0 +1,848 @@
> +/*
> + * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/delay.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +
> +#include <asm/clkdev.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/clock.h>
> +
> +#include "crm_regs.h"
> +
> +static void __iomem *pll_base[] = {
> +	MX51_DPLL1_BASE,
> +	MX51_DPLL2_BASE,
> +	MX51_DPLL3_BASE,
> +};
> +
> +/* External clock values passed-in by the board code */
> +static unsigned long external_high_reference, external_low_reference;
> +static unsigned long oscillator_reference, ckih2_reference;
> +
> +static struct clk osc_clk;
> +static struct clk pll1_main_clk;
> +static struct clk pll1_sw_clk;
> +static struct clk pll2_sw_clk;
> +static struct clk pll3_sw_clk;
> +static struct clk lp_apm_clk;
> +static struct clk periph_apm_clk;
> +static struct clk ahb_clk;
> +static struct clk ipg_clk;
> +
> +#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
> +
> +static int _clk_ccgr_enable(struct clk *clk)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(clk->enable_reg);
> +	reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
> +	__raw_writel(reg, clk->enable_reg);
> +
> +	return 0;
> +}
> +
> +static void _clk_ccgr_disable(struct clk *clk)
> +{
> +	u32 reg;
> +	reg = __raw_readl(clk->enable_reg);
> +	reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
> +	__raw_writel(reg, clk->enable_reg);
> +
> +}
> +
> +static void _clk_ccgr_disable_inwait(struct clk *clk)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(clk->enable_reg);
> +	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
> +	reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
> +	__raw_writel(reg, clk->enable_reg);
> +}
> +
> +/*
> + * For the 4-to-1 muxed input clock
> + */
> +static inline u32 _get_mux(struct clk *parent, struct clk *m0,
> +			   struct clk *m1, struct clk *m2, struct clk *m3)
> +{
> +	if (parent == m0)
> +		return 0;
> +	else if (parent == m1)
> +		return 1;
> +	else if (parent == m2)
> +		return 2;
> +	else if (parent == m3)
> +		return 3;
> +	else
> +		BUG();
> +
> +	return -EINVAL;
> +}
> +
> +static inline void __iomem *_get_pll_base(struct clk *pll)
> +{
> +	if (pll == &pll1_main_clk)
> +		return pll_base[0];
> +	else if (pll == &pll2_sw_clk)
> +		return pll_base[1];
> +	else if (pll == &pll3_sw_clk)
> +		return pll_base[2];
> +	else

I see no purpose for the pll_base[] array. It is used only here and you
can return the values directly.

> +		BUG();
> +
> +	return NULL;
> +}
> +
> +static unsigned long clk_pll_get_rate(struct clk *clk)
> +{
> +	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
> +	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
> +	void __iomem *pllbase;
> +	s64 temp;
> +	unsigned long parent_rate;
> +
> +	parent_rate = clk_get_rate(clk->parent);
> +
> +	pllbase = _get_pll_base(clk);
> +
> +	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> +	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> +	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
> +
> +	if (pll_hfsm == 0) {
> +		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
> +		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
> +		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
> +	} else {
> +		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
> +		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
> +		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
> +	}
> +	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
> +	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
> +	mfi = (mfi <= 5) ? 5 : mfi;
> +	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
> +	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
> +	/* Sign extend to 32-bits */
> +	if (mfn >= 0x04000000) {
> +		mfn |= 0xFC000000;
> +		mfn_abs = -mfn;
> +	}
> +
> +	ref_clk = 2 * parent_rate;
> +	if (dbl != 0)
> +		ref_clk *= 2;
> +
> +	ref_clk /= (pdf + 1);
> +	temp = (u64) ref_clk * mfn_abs;
> +	do_div(temp, mfd + 1);
> +	if (mfn < 0)
> +		temp = -temp;
> +	temp = (ref_clk * mfi) + temp;
> +
> +	return temp;
> +}
> +
> +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
> +{
> +	u32 reg;
> +	void __iomem *pllbase;
> +
> +	long mfi, pdf, mfn, mfd = 999999;
> +	s64 temp64;
> +	unsigned long quad_parent_rate;
> +	unsigned long pll_hfsm, dp_ctl;
> +	unsigned long parent_rate;
> +
> +	parent_rate = clk_get_rate(clk->parent);
> +
> +	pllbase = _get_pll_base(clk);
> +
> +	quad_parent_rate = 4 * parent_rate;
> +	pdf = mfi = -1;
> +	while (++pdf < 16 && mfi < 5)
> +		mfi = rate * (pdf+1) / quad_parent_rate;
> +	if (mfi > 15)
> +		return -1;
> +	pdf--;
> +
> +	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
> +	do_div(temp64, quad_parent_rate/1000000);
> +	mfn = (long)temp64;
> +
> +	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> +	/* use dpdck0_2 */
> +	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
> +	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> +	if (pll_hfsm == 0) {
> +		reg = mfi << 4 | pdf;
> +		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
> +		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
> +		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
> +	} else {
> +		reg = mfi << 4 | pdf;
> +		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
> +		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
> +		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
> +	}
> +
> +	return 0;
> +}
> +
> +static int _clk_pll_enable(struct clk *clk)
> +{
> +	u32 reg;
> +	void __iomem *pllbase;
> +	int i = 0;
> +
> +	pllbase = _get_pll_base(clk);
> +	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
> +	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> +
> +	/* Wait for lock */
> +	while ((!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF))
> +		&& i < MAX_DPLL_WAIT_TRIES) {
> +		i++;
> +		udelay(1);
> +	}
> +
> +	if (i == MAX_DPLL_WAIT_TRIES) {
> +		printk(KERN_ERR "MX5: pll locking failed\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static void _clk_pll_disable(struct clk *clk)
> +{
> +	u32 reg;
> +	void __iomem *pllbase;
> +
> +	pllbase = _get_pll_base(clk);
> +	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
> +	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> +}
> +
> +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(MXC_CCM_CCSR);
> +
> +	/* When switching from pll_main_clk to a bypass clock, first select a
> +	   multiplexed clock in 'step_sel', then shift the glitchless mux
> +	   'pll1_sw_clk_sel'.
> +	   When switching back, do it in reverse order
> +	*/
> +	if (parent == &pll1_main_clk) {
> +		/* Switch to pll1_main_clk */
> +		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> +		__raw_writel(reg, MXC_CCM_CCSR);
> +		/* step_clk mux switched to lp_apm, to save power. */
> +		reg = __raw_readl(MXC_CCM_CCSR);
> +		reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> +			(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> +				MXC_CCM_CCSR_STEP_SEL_OFFSET);
> +	} else {
> +		if (parent == &lp_apm_clk) {
> +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> +				(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> +					MXC_CCM_CCSR_STEP_SEL_OFFSET);
> +		} else  if (parent == &pll2_sw_clk) {
> +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> +				(MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED <<
> +					MXC_CCM_CCSR_STEP_SEL_OFFSET);
> +		} else  if (parent == &pll3_sw_clk) {
> +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> +				(MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
> +					MXC_CCM_CCSR_STEP_SEL_OFFSET);

Can we write this as

			reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
			reg |= MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
					MXC_CCM_CCSR_STEP_SEL_OFFSET;

At least for me this is much easier to read. Also, the &= part can be
outside the if clause.

> +		} else
> +			return -EINVAL;
> +
> +		__raw_writel(reg, MXC_CCM_CCSR);
> +		/* Switch to step_clk */
> +		reg = __raw_readl(MXC_CCM_CCSR);
> +		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> +	}
> +	__raw_writel(reg, MXC_CCM_CCSR);
> +	return 0;
> +}
> +
> +static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
> +{
> +	u32 reg, div;
> +	unsigned long parent_rate;
> +
> +	parent_rate = clk_get_rate(clk->parent);
> +
> +	div = 1;
> +	reg = __raw_readl(MXC_CCM_CCSR);
> +
> +	if (clk->parent == &pll2_sw_clk) {
> +		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
> +		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
> +	} else if (clk->parent == &pll3_sw_clk) {
> +		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
> +		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
> +	}
> +	return parent_rate / div;

This will return parent rate if the parent is not pll2_sw_clk and not
pll3_sw_clk. Is this intended? If yes, you could write

	} else
		div = 1;

to emphasize this is not an accident.


> +}
> +
> +static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(MXC_CCM_CCSR);
> +
> +	if (parent == &pll2_sw_clk)
> +		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> +	else
> +		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;

What's the other clock in the else part? I think there is a check
missing.

> +
> +	__raw_writel(reg, MXC_CCM_CCSR);
> +	return 0;
> +}
> +
> +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	u32 reg;
> +
> +	if (parent == &osc_clk)
> +		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
> +	else
> +		return -EINVAL;
> +
> +	__raw_writel(reg, MXC_CCM_CCSR);
> +
> +	return 0;
> +}
> +
> +static unsigned long clk_arm_get_rate(struct clk *clk)
> +{
> +	u32 cacrr, div;
> +	unsigned long parent_rate;
> +
> +	parent_rate = clk_get_rate(clk->parent);
> +	cacrr = __raw_readl(MXC_CCM_CACRR);
> +	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
> +
> +	return parent_rate / div;
> +}
> +
> +static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	u32 reg, mux;
> +	int i = 0;
> +
> +	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
> +
> +	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
> +	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
> +	__raw_writel(reg, MXC_CCM_CBCMR);
> +
> +	/* Wait for lock */
> +	while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)
> +		&& i < MAX_DPLL_WAIT_TRIES) {
> +		i++;
> +		udelay(1);
> +	}
> +
> +	if (i == MAX_DPLL_WAIT_TRIES) {
> +		printk(KERN_ERR "MX5: Set parent for periph_apm clock failed\n");
> +		return -EINVAL;
> +	}
> +
> +	return 0;
> +}
> +
> +static unsigned long clk_main_bus_get_rate(struct clk *clk)
> +{
> +	return clk_get_rate(clk->parent);
> +}

The generic code will automatically return the parent rate if the
get_rate field is set to NULL.

> +
> +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
> +{
> +	u32 reg;
> +
> +	reg = __raw_readl(MXC_CCM_CBCDR);
> +
> +	if (parent == &pll2_sw_clk)
> +		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> +	else if (parent == &periph_apm_clk)
> +		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> +	else
> +		return -EINVAL;
> +
> +	__raw_writel(reg, MXC_CCM_CBCDR);
> +
> +	return 0;
> +}
> +

[snip]

> +
> +static void clk_tree_init(void)
> +{
> +	u32 reg;
> +
> +	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);

Something is wrong here. Here you set the ipg_perclk parent.
_clk_ipg_per_set_parent will then set the MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL
and MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL bits accordingly...

> +
> +	/*
> +	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
> +	 * 8MHz, its derived from lp_apm.
> +	 * FIXME: Verify if true for all boards
> +	 */
> +	reg = __raw_readl(MXC_CCM_CBCDR);
> +	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
> +	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
> +	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
> +	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
> +	__raw_writel(reg, MXC_CCM_CBCDR);
> +
> +	/* set parent for pll1, pll2 and pll3 */
> +	pll1_main_clk.parent = &osc_clk;
> +	pll2_sw_clk.parent = &osc_clk;
> +	pll3_sw_clk.parent = &osc_clk;
> +
> +	/* set ipg_perclk parent */
> +	ipg_perclk.parent = &lp_apm_clk;
> +	reg = __raw_readl(MXC_CCM_CBCMR);
> +	if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
> +		ipg_perclk.parent = &ipg_clk;
> +	} else {
> +		if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
> +			ipg_perclk.parent = &main_bus_clk;
> +	}

...And here you set the parent according to the register bits. What's
the intention here? Do you want to keep the bootloader settings or
do you want to overwrite them with a known value?

> +}
> +
> +int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> +			unsigned long ckih1, unsigned long ckih2)
> +{
> +	int i;
> +
> +	external_low_reference = ckil;
> +	external_high_reference = ckih1;
> +	ckih2_reference = ckih2;
> +	oscillator_reference = osc;
> +
> +	for (i = 0; i < ARRAY_SIZE(lookups); i++)
> +		clkdev_add(&lookups[i]);
> +
> +	clk_tree_init();
> +
> +	clk_enable(&cpu_clk);
> +	clk_enable(&main_bus_clk);
> +
> +	/* System timer */
> +	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> +		MX51_MXC_INT_GPT);
> +	return 0;
> +}
> diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
> new file mode 100644
> index 0000000..93f1d5a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/cpu.c
> @@ -0,0 +1,45 @@
> +/*
> + * Copyright 2008-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + *
> + * This file contains the CPU initialization code.
> + */
> +
> +#include <linux/types.h>
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <mach/hardware.h>
> +#include <asm/io.h>
> +
> +static int __init post_cpu_init(void)
> +{
> +	unsigned int reg;
> +	void __iomem *base;
> +
> +	if (cpu_is_mx51()) {

	if (!cpu_is_mx51())
		return 0;

please. This way we have one indention level more in case this function
gets more complicated.


> +		base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
> +		__raw_writel(0x0, base + 0x40);
> +		__raw_writel(0x0, base + 0x44);
> +		__raw_writel(0x0, base + 0x48);
> +		__raw_writel(0x0, base + 0x4C);
> +		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> +		__raw_writel(reg, base + 0x50);
> +
> +		base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
> +		__raw_writel(0x0, base + 0x40);
> +		__raw_writel(0x0, base + 0x44);
> +		__raw_writel(0x0, base + 0x48);
> +		__raw_writel(0x0, base + 0x4C);
> +		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> +		__raw_writel(reg, base + 0x50);
> +	}
> +	return 0;
> +}
> +
> +postcore_initcall(post_cpu_init);
> diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
> new file mode 100644
> index 0000000..c776b9a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/crm_regs.h

[snip]

> diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> new file mode 100644
> index 0000000..55eb089
> --- /dev/null
> +++ b/arch/arm/mach-mx5/devices.c
> @@ -0,0 +1,96 @@
> +/*
> + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/platform_device.h>
> +#include <mach/hardware.h>
> +#include <mach/imx-uart.h>
> +
> +static struct resource uart0[] = {
> +	{
> +		.start = MX51_UART1_BASE_ADDR,
> +		.end = MX51_UART1_BASE_ADDR + 0x0B5,

You can safely write MX51_UART1_BASE_ADDR + 0xfff here because that's
the register space this device actually has. The last register in the
datasheet is 0xb4 anyway and with 32bit register accesses the correct
value here would be 0xb7.

> +		.flags = IORESOURCE_MEM,
> +	}, {
> +		.start = MX51_MXC_INT_UART1,
> +		.end = MX51_MXC_INT_UART1,
> +		.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 = MX51_UART2_BASE_ADDR,
> +		.end = MX51_UART2_BASE_ADDR + 0x0B5,
> +		.flags = IORESOURCE_MEM,
> +	}, {
> +		.start = MX51_MXC_INT_UART2,
> +		.end = MX51_MXC_INT_UART2,
> +		.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 = MX51_UART3_BASE_ADDR,
> +		.end = MX51_UART3_BASE_ADDR + 0x0B5,
> +		.flags = IORESOURCE_MEM,
> +	}, {
> +		.start = MX51_MXC_INT_UART3,
> +		.end = MX51_MXC_INT_UART3,
> +		.flags = IORESOURCE_IRQ,
> +	},
> +};
> +
> +struct platform_device mxc_uart_device2 = {
> +	.name = "imx-uart",
> +	.id = 2,
> +	.resource = uart2,
> +	.num_resources = ARRAY_SIZE(uart2),
> +};
> +
> +static struct resource mxc_fec_resources[] = {
> +	{
> +		.start	= MX51_MXC_FEC_BASE_ADDR,
> +		.end	= MX51_MXC_FEC_BASE_ADDR + 0xfff,
> +		.flags	= IORESOURCE_MEM,
> +	}, {
> +		.start	= MX51_MXC_INT_FEC,
> +		.end	= MX51_MXC_INT_FEC,
> +		.flags	= IORESOURCE_IRQ,
> +	},
> +};
> +
> +struct platform_device mxc_fec_device = {
> +	.name = "fec",
> +	.id = 0,
> +	.num_resources = ARRAY_SIZE(mxc_fec_resources),
> +	.resource = mxc_fec_resources,
> +};
> +
> +/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
> +int __init mxc_register_gpios(void)
> +{
> +	return 0;
> +}
> diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> new file mode 100644
> index 0000000..f339ab8
> --- /dev/null
> +++ b/arch/arm/mach-mx5/devices.h
> @@ -0,0 +1,4 @@
> +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;
> diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
> new file mode 100644
> index 0000000..d66c31a
> --- /dev/null
> +++ b/arch/arm/mach-mx5/mm.c
> @@ -0,0 +1,88 @@
> +/*
> + * Copyright 2008-2009 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + *
> + * Create static mapping between physical to virtual memory.
> + */
> +
> +#include <linux/mm.h>
> +#include <linux/init.h>
> +
> +#include <asm/mach/map.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-v3.h>
> +
> +/*
> + * Define the MX51 memory map.
> + */
> +static struct map_desc mxc_io_desc[] __initdata = {
> +	{
> +	 .virtual = MX51_IRAM_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
> +	 .length = MX51_IRAM_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_DEBUG_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
> +	 .length = MX51_DEBUG_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_TZIC_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
> +	 .length = MX51_TZIC_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
> +	 .length = MX51_AIPS1_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_SPBA0_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
> +	 .length = MX51_SPBA0_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_AIPS2_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
> +	 .length = MX51_AIPS2_SIZE,
> +	 .type = MT_DEVICE},
> +	{
> +	 .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
> +	 .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
> +	 .length = MX51_NFC_AXI_SIZE,
> +	 .type = MT_DEVICE},
> +};
> +
> +/*
> + * 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 mx51_map_io(void)
> +{
> +	u32 tzic_addr;
> +
> +	if (mx51_revision() < MX51_CHIP_REV_2_0)
> +		tzic_addr = 0x8FFFC000;
> +	else
> +		tzic_addr = 0xE0003000;
> +	mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
> +
> +	mxc_set_cpu_type(MXC_CPU_MX51);
> +	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
> +	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
> +	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
> +}
> +
> +void __init mx51_init_irq(void)
> +{
> +	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
> +}
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 5250a3f..0a25576 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -30,6 +30,7 @@ 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 mx51_init_irq(void);
>  extern void mxc91231_init_irq(void);
>  extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
>  extern int mx1_clocks_init(unsigned long fref);
> diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> index 9fe7300..9d41bfd 100644
> --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> @@ -49,8 +49,8 @@
>  #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
>  #endif
>  #include <mach/mx51.h>
> -#define UART_PADDR	UART1_BASE_ADDR
> -#define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
> +#define UART_PADDR	MX51_UART1_BASE_ADDR
> +#define UART_VADDR	MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
>  #endif
>  
>  #ifdef CONFIG_ARCH_MXC91231
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> new file mode 100644
> index 0000000..14df0f5
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> @@ -0,0 +1,340 @@
> +/*
> + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com> 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#ifndef __MACH_IOMUX_MX51_H__
> +#define __MACH_IOMUX_MX51_H__
> +
> +#include <mach/iomux-v3.h>
> +
> +/*
> + * various IOMUX alternate output functions (1-7)
> + */
> +typedef enum iomux_config {
> +	IOMUX_CONFIG_ALT0,
> +	IOMUX_CONFIG_ALT1,
> +	IOMUX_CONFIG_ALT2,
> +	IOMUX_CONFIG_ALT3,
> +	IOMUX_CONFIG_ALT4,
> +	IOMUX_CONFIG_ALT5,
> +	IOMUX_CONFIG_ALT6,
> +	IOMUX_CONFIG_ALT7,
> +	IOMUX_CONFIG_GPIO,	/* added to help user use GPIO mode */
> +	IOMUX_CONFIG_SION = 0x1 << 4,	/* LOOPBACK:MUX SION bit */
> +} iomux_pin_cfg_t;
> +
> +/* Pad control groupings */
> +#define MX51_UART1_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
> +				PAD_CTL_DSE_HIGH)
> +#define MX51_UART2_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
> +				PAD_CTL_SRE_FAST)
> +#define MX51_UART3_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
> +				PAD_CTL_SRE_FAST)
> +
> +/*
> + * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named
> + * GPIO_<unit>_<num> see also iomux-v3.h
> + */
> +
> +/* REVISIT: This was converted using scripts from existing Freescale code to
> + * this form used upstream. Need to verify the name format.
> + */
> +
> +/*						PAD      MUX   ALT INPSE PATH PADCTRL */
> +
> +
> +/* UART1 */
> +#define MX51_BABBAGE_PAD_UART1_RXD__UART1_RXD	\
> +	IOMUX_PAD(0x618, 0x228,	IOMUX_CONFIG_ALT0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
> +#define MX51_BABBAGE_PAD_UART1_TXD__UART1_TXD	\
> +	IOMUX_PAD(0x61C, 0x22C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
> +#define MX51_BABBAGE_PAD_UART1_RTS__UART1_RTS	\
> +	IOMUX_PAD(0x620, 0x230, IOMUX_CONFIG_ALT0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
> +#define MX51_BABBAGE_PAD_UART1_CTS__UART1_CTS	\
> +	IOMUX_PAD(0x624, 0x234, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL)

I remember last time I said that you should move these macros here. I
think the situation is like this:

1) These are either known good values for the uart pins and therefore
   shouldn't have BABBAGE in their name.
2) There is something babbage specific in them, in this case they should
   be in the board specific file.

I vote for 1) here.

> +
> +/* UART2 */
> +#define MX51_BABBAGE_PAD_UART2_RXD__UART2_RXD	IOMUX_PAD(0x628, 0x238, IOMUX_CONFIG_ALT0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
> +#define MX51_BABBAGE_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x62C, 0x23C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART2_PAD_CTRL)
> +
> +/* UART3 */
> +#define MX51_BABBAGE_PAD_EIM_D25__UART3_RXD	IOMUX_PAD(0x414, 0x080, IOMUX_CONFIG_ALT3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
> +#define MX51_BABBAGE_PAD_EIM_D26__UART3_TXD	IOMUX_PAD(0x418, 0x084, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
> +#define MX51_BABBAGE_PAD_EIM_D27__UART3_RTS	IOMUX_PAD(0x41c, 0x088, IOMUX_CONFIG_ALT3, 0x9f0, 0, MX51_UART3_PAD_CTRL)
> +#define MX51_BABBAGE_PAD_EIM_D24__UART3_CTS	IOMUX_PAD(0x410, 0x07c, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
> +
> +#define MX51_BABBAGE_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))
> +

ditto

 Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 07/11] mxc: Add support for the Babbage board
  2010-02-03  5:16               ` [PATCHv2 07/11] mxc: Add support for the Babbage board Amit Kucheria
  2010-02-03  5:16                 ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Amit Kucheria
@ 2010-02-03 11:10                 ` Sascha Hauer
  1 sibling, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-02-03 11:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 09:16:29PM -0800, Amit Kucheria wrote:
> Babbage is a reference board from Freescale for their i.MX51 SoC.
> 
> Boot tested on a Babbage2.5 board
> 
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
>  arch/arm/mach-mx5/Kconfig               |    6 ++
>  arch/arm/mach-mx5/Makefile              |    2 +
>  arch/arm/mach-mx5/board-mx51_babbage.c  |   99 +++++++++++++++++++++++++++++++
>  arch/arm/plat-mxc/include/mach/common.h |    1 +
>  4 files changed, 108 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/mach-mx5/board-mx51_babbage.c
> 
> diff --git a/arch/arm/mach-mx5/Kconfig b/arch/arm/mach-mx5/Kconfig
> index ccd96fd..80a749c 100644
> --- a/arch/arm/mach-mx5/Kconfig
> +++ b/arch/arm/mach-mx5/Kconfig
> @@ -8,4 +8,10 @@ config ARCH_MX51
>  
>  comment "MX5 platforms:"
>  
> +config MACH_MX51_BABBAGE
> +	bool "Support MX51 BABBAGE platforms"
> +	help
> +	  Include support for MX51 Babbage platform. This includes specific
> +	  configurations for the board and its peripherals.
> +
>  endif
> diff --git a/arch/arm/mach-mx5/Makefile b/arch/arm/mach-mx5/Makefile
> index d74ce4f..e4cf91f 100644
> --- a/arch/arm/mach-mx5/Makefile
> +++ b/arch/arm/mach-mx5/Makefile
> @@ -5,3 +5,5 @@
>  # Object file lists.
>  obj-y   := cpu.o mm.o clock.o devices.o
>  
> +obj-$(CONFIG_MACH_MX51_BABBAGE) += board-mx51_babbage.o
> +
> diff --git a/arch/arm/mach-mx5/board-mx51_babbage.c b/arch/arm/mach-mx5/board-mx51_babbage.c

Uwe started to rename the board files on other i.MX platforms to
mach-*.c. Can you do the same please?

> new file mode 100644
> index 0000000..6cd0e14
> --- /dev/null
> +++ b/arch/arm/mach-mx5/board-mx51_babbage.c
> @@ -0,0 +1,99 @@
> +/*
> + * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + *
> + * The code contained herein is licensed under the GNU General Public
> + * License. You may obtain a copy of the GNU General Public License
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/init.h>
> +#include <linux/platform_device.h>
> +
> +#include <mach/common.h>
> +#include <mach/hardware.h>
> +#include <mach/imx-uart.h>
> +#include <mach/iomux-mx51.h>
> +
> +#include <asm/irq.h>
> +#include <asm/setup.h>
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include "crm_regs.h"

Is this needed?

> +#include "devices.h"
> +
> +static struct platform_device *devices[] __initdata = {
> +	&mxc_fec_device,
> +};
> +
> +static struct pad_desc mx51babbage_pads[] = {
> +	/* UART1 */
> +	MX51_BABBAGE_PAD_UART1_RXD__UART1_RXD,
> +	MX51_BABBAGE_PAD_UART1_TXD__UART1_TXD,
> +	MX51_BABBAGE_PAD_UART1_RTS__UART1_RTS,
> +	MX51_BABBAGE_PAD_UART1_CTS__UART1_CTS,
> +
> +	/* UART2 */
> +	MX51_BABBAGE_PAD_UART2_RXD__UART2_RXD,
> +	MX51_BABBAGE_PAD_UART2_TXD__UART2_TXD,
> +
> +	/* UART3 */
> +	MX51_BABBAGE_PAD_EIM_D25__UART3_RXD,
> +	MX51_BABBAGE_PAD_EIM_D26__UART3_TXD,
> +	MX51_BABBAGE_PAD_EIM_D27__UART3_RTS,
> +	MX51_BABBAGE_PAD_EIM_D24__UART3_CTS,
> +};
> +
> +/* Serial ports */
> +#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
> +static struct imxuart_platform_data uart_pdata = {
> +	.flags = IMXUART_HAVE_RTSCTS,
> +};
> +
> +static inline void mxc_init_imx_uart(void)
> +{
> +	mxc_register_device(&mxc_uart_device0, &uart_pdata);
> +	mxc_register_device(&mxc_uart_device1, &uart_pdata);
> +	mxc_register_device(&mxc_uart_device2, &uart_pdata);
> +}
> +#else /* !SERIAL_IMX */
> +static inline void mxc_init_imx_uart(void)
> +{
> +}
> +#endif /* SERIAL_IMX */
> +
> +/*
> + * Board specific initialization.
> + */
> +static void __init mxc_board_init(void)
> +{
> +	mxc_iomux_v3_setup_multiple_pads(mx51babbage_pads,
> +					ARRAY_SIZE(mx51babbage_pads));
> +	mxc_init_imx_uart();
> +	platform_add_devices(devices, ARRAY_SIZE(devices));
> +}
> +
> +static void __init mx51_babbage_timer_init(void)
> +{
> +	mx51_clocks_init(32768, 24000000, 22579200, 24576000);
> +}
> +
> +static struct sys_timer mxc_timer = {
> +	.init	= mx51_babbage_timer_init,
> +};
> +
> +MACHINE_START(MX51_BABBAGE, "Freescale MX51 Babbage Board")
> +	/* Maintainer: Amit Kucheria <amit.kucheria@canonical.com> */
> +	.phys_io = MX51_AIPS1_BASE_ADDR,
> +	.io_pg_offst = ((MX51_AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
> +	.boot_params = PHYS_OFFSET + 0x100,
> +	.map_io = mx51_map_io,
> +	.init_irq = mx51_init_irq,
> +	.init_machine = mxc_board_init,
> +	.timer = &mxc_timer,
> +MACHINE_END
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 0a25576..33d4496 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -21,6 +21,7 @@ extern void mx27_map_io(void);
>  extern void mx31_map_io(void);
>  extern void mx35_map_io(void);
>  extern void mx51_map_io(void);
> +extern void mx51_babbage_io_init(void);

Is this function used anywhere? I hope not...

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03  6:23     ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Eric Miao
  2010-02-03  9:45       ` Sascha Hauer
@ 2010-02-03 13:24       ` Amit Kucheria
  2010-02-03 15:09         ` Eric Miao
  2010-02-04 17:09         ` Nguyen Dinh-R00091
  1 sibling, 2 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03 13:24 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 Feb 02, Eric Miao wrote:
> Hi Amit,
> 
> Just some nit-picking review comments, see below:
> 
> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
> > Freescale i.MX51 processor uses a new interrupt controller. Add
> > driver for TrustZone Interrupt Controller
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/plat-mxc/Kconfig ?| ? ?8 ++
> > ?arch/arm/plat-mxc/Makefile | ? ?3 +
> > ?arch/arm/plat-mxc/tzic.c ? | ?182 ++++++++++++++++++++++++++++++++++++++++++++
> > ?3 files changed, 193 insertions(+), 0 deletions(-)
> > ?create mode 100644 arch/arm/plat-mxc/tzic.c
> >
> > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> > index 8b0a1ee..59558c4 100644
> > --- a/arch/arm/plat-mxc/Kconfig
> > +++ b/arch/arm/plat-mxc/Kconfig
> > @@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
> > ? ? ? ? ?requirements for timing.
> > ? ? ? ? ?Say N here, unless you have a specialized requirement.
> >
> > +config MXC_TZIC
> > + ? ? ? bool "Enable TrustZone Interrupt Controller"
> > + ? ? ? depends on ARCH_MX51
> 
> This is the first patch of the base port, yet I cannot find any reference to
> this ARCH_MX51, did you miss something?

ARCH_MX51 is only introduced in the later patches that add the core i.MX5
code. Since TZIC is not inherently dependent on i.MX5 (it's merely the first
processor to use it), I thought of splitting it out as a separate patch.

Does this break the sanctity of one self-contained change?

> > + ? ? ? help
> > + ? ? ? ? This will be automatically selected for all processors
> > + ? ? ? ? containing this interrupt controller.
> > + ? ? ? ? Say N here only if you are really sure.
> > +
> > ?config MXC_PWM
> > ? ? ? ?tristate "Enable PWM driver"
> > ? ? ? ?depends on ARCH_MXC
> > diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> > index 996cbac..0202ad9 100644
> > --- a/arch/arm/plat-mxc/Makefile
> > +++ b/arch/arm/plat-mxc/Makefile
> > @@ -5,6 +5,9 @@
> > ?# Common support
> > ?obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
> >
> > +# MX51 uses the TZIC interrupt controller, older platforms use AVIC (irq.o)
> > +obj-$(CONFIG_MXC_TZIC) += tzic.o
> > +
> > ?obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> > diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> > new file mode 100644
> > index 0000000..00cb0ad
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/tzic.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + * Copyright 2004-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/init.h>
> > +#include <linux/device.h>
> > +#include <linux/errno.h>
> > +#include <linux/io.h>
> > +
> > +#include <asm/mach/irq.h>
> > +
> > +#include <mach/hardware.h>
> > +
> > +/*
> > + *****************************************
> > + * TZIC Registers ? ? ? ? ? ? ? ? ? ? ? ?*
> > + *****************************************
> > + */
> > +
> > +#define TZIC_INTCNTL ? ? ? ? ? ?0x0000 /* Control register */
> > +#define TZIC_INTTYPE ? ? ? ? ? ?0x0004 /* Controller Type register */
> > +#define TZIC_IMPID ? ? ? ? ? ? ?0x0008 /* Distributor Implementer Identification */
> > +#define TZIC_PRIOMASK ? ? ? ? ? 0x000C /* Priority Mask Reg */
> > +#define TZIC_SYNCCTRL ? ? ? ? ? 0x0010 /* Synchronizer Control register */
> > +#define TZIC_DSMINT ? ? ? ? ? ? 0x0014 /* DSM interrupt Holdoffregister */
> > +#define TZIC_INTSEC0 ? ? ? ? ? ?0x0080 /* Interrupt Security register 0 */
> > +#define TZIC_ENSET0 ? ? ? ? ? ? 0x0100 /* Enable Set Register 0 */
> > +#define TZIC_ENCLEAR0 ? ? ? ? ? 0x0180 /* Enable Clear Register 0 */
> > +#define TZIC_SRCSET0 ? ? ? ? ? ?0x0200 /* Source Set Register 0 */
> > +#define TZIC_SRCCLAR0 ? ? ? ? ? 0x0280 /* Source Clear Register 0 */
> > +#define TZIC_PRIORITY0 ? ? ? ? ?0x0400 /* Priority Register 0 */
> > +#define TZIC_PND0 ? ? ? ? ? ? ? 0x0D00 /* Pending Register 0 */
> > +#define TZIC_HIPND0 ? ? ? ? ? ? 0x0D80 /* High Priority Pending Register */
> > +#define TZIC_WAKEUP0 ? ? ? ? ? ?0x0E00 /* Wakeup Config Register */
> > +#define TZIC_SWINT ? ? ? ? ? ? ?0x0F00 /* Software Interrupt Rigger Register */
> > +#define TZIC_ID0 ? ? ? ? ? ? ? ?0x0FD0 /* Indentification Register 0 */
> > +
> > +void __iomem *tzic_base;
> 
> This can just be made to 'static' if it's not used elsewhere, and I'm
> wondering if it's neater to define them as:
> 
> #define TZIC_INTCNTL		(tzic_base + 0x0000)
> 
> so to make the code below short and handy.

tzic_base is actually used in entry-macro.S in patch 0004. I've tried to follow
AVIC's way of doing things.

> > +
> > +/*
> > + * Disable interrupt number "irq" in the TZIC
> 
> I don't think this follows kernel API doc exactly, you may want to have a
> look into Documentation/kernel-doc-nano-HOWTO.txt.

OK.

> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number
> > + */
> > +static void tzic_mask_irq(unsigned int irq)
> > +{
> > + ? ? ? int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0 + (index << 2));
> 
> I'll normally define TZIC_ENCLEAR0 then as:
> 
> #define TZIC_ENCLEAR(i)		(0x0180 + ((i) << 2))
> 
> so the above can be written as:
> 
> 	__raw_writel(1 << off, tzic_base + TZIC_ENCLEAR(index));
> 
> or by including tzic_base into TZIC_*, simply as:
> 
> 	__raw_writel(1 << off, TZIC_ENCLEAR(index));

OK.

> > +}
> > +
> > +/*
> > + * Enable interrupt number "irq" in the TZIC
> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number
> > + */
> > +static void tzic_unmask_irq(unsigned int irq)
> > +{
> > + ? ? ? int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENSET0 + (index << 2));
> > +}
> > +
> > +static unsigned int wakeup_intr[4];
> > +
> > +/*
> > + * Set interrupt number "irq" in the TZIC as a wake-up source.
> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number
> > + * @param ?enable ? ? ? enable as wake-up if equal to non-zero
> > + * ? ? ? ? ? ? ? ? ? ? disble as wake-up if equal to zero
> > + *
> > + * @return ? ? ? This function returns 0 on success.
> > + */
> > +static int tzic_set_wake_irq(unsigned int irq, unsigned int enable)
> > +{
> > + ? ? ? unsigned int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > +
> > + ? ? ? if (index > 3)
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? if (enable)
> > + ? ? ? ? ? ? ? wakeup_intr[index] |= (1 << off);
> > + ? ? ? else
> > + ? ? ? ? ? ? ? wakeup_intr[index] &= ~(1 << off);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static struct irq_chip mxc_tzic_chip = {
> > + ? ? ? .name = "MXC_TZIC",
> > + ? ? ? .ack = tzic_mask_irq,
> > + ? ? ? .mask = tzic_mask_irq,
> > + ? ? ? .unmask = tzic_unmask_irq,
> > + ? ? ? .set_wake = tzic_set_wake_irq,
> > +};
> > +
> > +/*
> > + * This function initializes the TZIC hardware and disables all the
> > + * interrupts. It registers the interrupt enable and disable functions
> > + * to the kernel for each interrupt source.
> > + */
> > +void __init tzic_init_irq(void __iomem *irqbase)
> > +{
> > + ? ? ? int i;
> > +
> > + ? ? ? tzic_base = irqbase;
> > + ? ? ? /* put the TZIC into the reset value with
> > + ? ? ? ?* all interrupts disabled
> > + ? ? ? ?*/
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);
> 
> Mixing the use of 'i' as both a signed counter and register value might
> not be a good idea, provided it's not guaranteed from theory that 'i' as
> an integer could not be sufficient to hold the value returned from
> __raw_readl()

Fair enough.

> > +
> > + ? ? ? __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);
> > + ? ? ? __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_PRIOMASK);
> > + ? ? ? __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_SYNCCTRL);
> 
> Are these read-back really necessary? We can start without them and add them
> later if they do cause issues.

Can anybody from Freescale comment whether the read-back is necessary?

I'll remove it for now to see what happens in my testing.

> > +
> > + ? ? ? for (i = 0; i < 4; i++)
> > + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0 + i * 4);
> > +
> > + ? ? ? /* disable all interrupts */
> > + ? ? ? for (i = 0; i < 4; i++)
> > + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0 + i * 4);
> > +
> > + ? ? ? /* all IRQ no FIQ Warning :: No selection */
> > +
> > + ? ? ? for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
> > + ? ? ? ? ? ? ? set_irq_chip(i, &mxc_tzic_chip);
> > + ? ? ? ? ? ? ? set_irq_handler(i, handle_level_irq);
> > + ? ? ? ? ? ? ? set_irq_flags(i, IRQF_VALID);
> > + ? ? ? }
> > +
> > + ? ? ? printk(KERN_INFO "TrustZone Interrupt Controller (TZIC) initialized\n");
> 
> You may want to use pr_info() for short.

OK

> > +}
> > +
> > +/*
> > + * enable wakeup interrupt
> > + *
> > + * @param is_idle ? ? ? ? ? ? ?1 if called in idle loop (ENSET register);
> > + * ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 to be used when called from low power entry
> > + * @return ? ? ? ? ? ? ? ? ? ? 0 if successful; non-zero otherwise
> > + *
> > + */
> > +int tzic_enable_wake(int is_idle)
> > +{
> > + ? ? ? unsigned int i, v;
> > +
> > + ? ? ? __raw_writel(1, tzic_base + TZIC_DSMINT);
> > + ? ? ? if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
> > + ? ? ? ? ? ? ? return -EAGAIN;
> 
> Looks like an unnecessary read-back provided the silicon is sane enough.

Again, Dinh/Rob can you comment?

> > +
> > + ? ? ? if (likely(is_idle)) {
> > + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> > + ? ? ? ? ? ? ? ? ? ? ? v = __raw_readl(tzic_base + TZIC_ENSET0 + i * 4);
> > + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> > + ? ? ? ? ? ? ? ? ? ? ? v = wakeup_intr[i];
> > + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i * 4);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? }
> 
> Or could be simplified to:
> 
> 	for (i = 0; i < 4; i++) {
> 		v = is_idle ? __raw_readl(TZIC_ENSET(i)) : wakeup_intr[i];
> 		__raw_writel(v, TZIC_WAKEUP(i));
> 	}

OK

> but just nit-picking comments, so it's up to you.
> 
> > + ? ? ? return 0;
> > +}
> 
> Mmmm.... this being called elsewhere, I'm thinking about making this a
> sys_device and having this called within sysdev_class.suspend() to make
> this file rather self-contained.

That is the idea once the base port is upstream.

Thanks for the review.

/Amit
-- 
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria at canonical.com
----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03  9:49             ` Sascha Hauer
@ 2010-02-03 13:38               ` Amit Kucheria
  2010-02-03 15:16                 ` Eric Miao
  0 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03 13:38 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 Feb 03, Sascha Hauer wrote:
> On Tue, Feb 02, 2010 at 10:43:33PM -0800, Eric Miao wrote:
> > 
> > Mmm.... this should be something that we really need to get rid of, it just
> > makes a single kernel for both TZIC and AVIC together impossible, if that's
> > so designed by HW, I'm thinking about keeping this into plat-mxc/ is a good
> > way to go ...
> > 
> > Sascha, you have any better idea? Provided the other file debug-macro.S in
> > the same directory already seems to break the support for multiple arches?
> > 
> 
> I have the following patch which I'm not sure I like better. It can
> support both irq controller types and does not add overhead if only one
> of them is compiled in. It might need some refactoring to fit into Amits
> patch stack.

Is co-existence of TZIC and AVIC a blocker to merging i.MX5 code? I've
already made changes so that i.MX5 doesn't explode if AVIC is compiled in.

Admittedly the assembly is a bit hard to rid, but we can fix in another set
of patches geared towards unification of an i.MX kernel. IMHO, making these
changes along with introducing a new SoC will make things a bit hard to
follow/merge.

Regards,
Amit

> Sascha
> 
> 
> commit c30ed01dcd257bba813b27a423bc54d5f32fc878
> Author: Sascha Hauer <s.hauer@pengutronix.de>
> Date:   Tue Nov 17 16:23:24 2009 +0100
> 
>     MXC tzic support
>     
>     Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> 
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index ebe4b8c..377f792 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -84,4 +84,7 @@ config ARCH_MXC_IOMUX_V3
>  config ARCH_MXC_AVIC
>  	bool
>  
> +config ARCH_MXC_TZIC
> +	bool
> +
>  endif
> diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> index 325d9da..37ce6ec 100644
> --- a/arch/arm/plat-mxc/Makefile
> +++ b/arch/arm/plat-mxc/Makefile
> @@ -9,4 +9,5 @@ obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
>  obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
>  obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
>  obj-$(CONFIG_MXC_PWM)  += pwm.o
> +obj-$(CONFIG_ARCH_MXC_TZIC) += tzic.o
>  obj-$(CONFIG_ARCH_MXC_AVIC) += irq.o
> diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c
> index b073b7d..d46325e 100644
> --- a/arch/arm/plat-mxc/cpu.c
> +++ b/arch/arm/plat-mxc/cpu.c
> @@ -11,4 +11,5 @@ void mxc_set_cpu_type(unsigned int type)
>  }
>  
>  void __iomem *mxc_irq_base;
> +int mxc_irq_controller_type;
>  
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 286cb9b..d395763 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -44,5 +44,5 @@ extern void mxc_arch_reset_init(void __iomem *);
>  extern void mxc91231_power_off(void);
>  extern void mxc91231_arch_reset(int, const char *);
>  extern void mxc91231_prepare_idle(void);
> -
> +extern void tzic_init_irq(void __iomem *);
>  #endif
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index 55375df..049f740 100644
> --- a/arch/arm/plat-mxc/include/mach/entry-macro.S
> +++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
> @@ -13,6 +13,9 @@
>  
>  #define AVIC_NIMASK	0x04
>  
> +#define TZIC_HIPND0 0xd80
> +
> +
>  	@ this macro disables fast irq (not implemented)
>  	.macro	disable_fiq
>  	.endm
> @@ -28,10 +31,35 @@
>  	.macro  arch_ret_to_user, tmp1, tmp2
>  	.endm
>  
> -	@ this macro checks which interrupt occured
> -	@ and returns its number in irqnr
> -	@ and returns if an interrupt occured in irqstat
> -	.macro	get_irqnr_and_base, irqnr, irqstat, base, tmp
> +	.macro	tzic_get_irqnr_and_base, irqnr, irqstat, base, tmp
> +
> +	@ Load offset & priority of the highest priority
> +	@ interrupt pending.
> +	ldr     \irqnr, =0
> +	ldr     \irqstat, =TZIC_HIPND0
> +1000:
> +	ldr     \tmp,   [\base, \irqstat]
> +	cmp     \tmp, #0
> +	bne     1001f
> +	addeq   \irqnr, \irqnr, #32
> +	addeq   \irqstat, \irqstat, #4
> +	cmp     \irqnr, #128
> +	blo     1000b
> +	b       2001f
> +1001:	ldr     \irqstat, =1
> +1002:	tst     \tmp, \irqstat
> +	bne     2002f
> +	movs    \irqstat, \irqstat, lsl #1
> +	addne   \irqnr, \irqnr, #1
> +	bne     1002b
> +2001:
> +	ldr  \irqnr, =0
> +2002:
> +	movs \irqnr, \irqnr
> +	.endm
> +
> +	.macro	avic_get_irqnr_and_base, irqnr, irqstat, base, tmp
> +
>  	@ Load offset & priority of the highest priority
>  	@ interrupt pending from AVIC_NIVECSR
>  	ldr	\irqstat, [\base, #0x40]
> @@ -47,6 +75,28 @@
>  #endif
>  	.endm
>  
> +	.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> +#if defined CONFIG_ARCH_MXC_TZIC && defined CONFIG_ARCH_MXC_AVIC
> +	ldr	\tmp, =mxc_irq_controller_type
> +	ldr	\tmp, [\tmp]
> +	cmp	\tmp, #MXC_IRQ_TYPE_AVIC
> +	beq	3001f
> +
> +	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +	b	3002f
> +3001:
> +	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +3002:
> +
> +#elif defined CONFIG_ARCH_MXC_TZIC
> +	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#elif defined CONFIG_ARCH_MXC_AVIC
> +	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#else
> +#error no tzic and no avic?
> +#endif
> +	.endm
> +
>  	@ irq priority table (not used)
>  	.macro	irq_prio_table
>  	.endm
> diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> index b64a269..6cf0f98 100644
> --- a/arch/arm/plat-mxc/include/mach/mxc.h
> +++ b/arch/arm/plat-mxc/include/mach/mxc.h
> @@ -129,8 +129,12 @@ extern unsigned int __mxc_cpu_type;
>  #define cpu_is_mx3()	(cpu_is_mx31() || cpu_is_mx35() || cpu_is_mxc91231())
>  #define cpu_is_mx2()	(cpu_is_mx21() || cpu_is_mx27())
>  
> +#define	MXC_IRQ_TYPE_AVIC	1
> +#define	MXC_IRQ_TYPE_TZIC	2
> +
>  #ifndef __ASSEMBLY__
>  extern void __iomem *mxc_irq_base;
> +extern int mxc_irq_controller_type;
>  #endif
>  
>  #endif /*  __ASM_ARCH_MXC_H__ */
> diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
> index 4855a65..3e7ac84 100644
> --- a/arch/arm/plat-mxc/irq.c
> +++ b/arch/arm/plat-mxc/irq.c
> @@ -116,6 +116,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
>  	int i;
>  
>  	mxc_irq_base = irqbase;
> +	mxc_irq_controller_type = MXC_IRQ_TYPE_AVIC;
>  
>  	/* put the AVIC into the reset value with
>  	 * all interrupts disabled
> diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
> new file mode 100644
> index 0000000..2d14af4
> --- /dev/null
> +++ b/arch/arm/plat-mxc/tzic.c
> @@ -0,0 +1,104 @@
> +/*
> + *  Copyright 2004-2008 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
> + * Version 2 or later at the following locations:
> + *
> + * http://www.opensource.org/licenses/gpl-license.html
> + * http://www.gnu.org/copyleft/gpl.html
> + */
> +
> +#include <linux/module.h>
> +#include <linux/moduleparam.h>
> +#include <linux/init.h>
> +#include <linux/device.h>
> +#include <linux/errno.h>
> +#include <linux/io.h>
> +#include <asm/irq.h>
> +#include <asm/mach/irq.h>
> +#include <mach/common.h>
> +#include <mach/hardware.h>
> +
> +extern void __iomem *mxc_irq_base;
> +extern int mxc_irq_controller_type;
> +
> +#define TZIC_INTCNTL            0x0000	/* control register */
> +#define TZIC_INTTYPE            0x0004	/* Controller type register */
> +#define TZIC_IMPID              0x0008	/* Distributor Implementer Identification Register */
> +#define TZIC_PRIOMASK           0x000c	/* Priority Mask Reg */
> +#define TZIC_SYNCCTRL           0x0010	/* Synchronizer Control register */
> +#define TZIC_DSMINT             0x0014	/* DSM interrupt Holdoffregister */
> +#define TZIC_INTSEC0            0x0080	/* interrupt security register 0 */
> +#define TZIC_ENSET0             0x0100	/* Enable Set Register 0 */
> +#define TZIC_ENCLEAR0           0x0180	/* Enable Clear Register 0 */
> +#define TZIC_SRCSET0            0x0200	/* Source Set Register 0 */
> +#define TZIC_SRCCLAR0           0x0280	/* Source Clear Register 0 */
> +#define TZIC_PRIORITY0          0x0400	/* Priority Register 0 */
> +#define TZIC_PND0               0x0d00	/* Pending Register 0 */
> +#define TZIC_HIPND0             0x0d80	/* High Priority Pending Register */
> +#define TZIC_WAKEUP0            0x0e00	/* Wakeup Config Register */
> +#define TZIC_SWINT              0x0f00	/* Software Interrupt Rigger Register */
> +#define TZIC_ID0                0x0fd0	/* Indentification Register 0 */
> +
> +static void mxc_mask_irq(unsigned int irq)
> +{
> +	int index, off;
> +
> +	index = irq >> 5;
> +	off = irq & 0x1F;
> +	__raw_writel(1 << off, mxc_irq_base + TZIC_ENCLEAR0 + (index << 2));
> +}
> +
> +static void mxc_unmask_irq(unsigned int irq)
> +{
> +	int index, off;
> +
> +	index = irq >> 5;
> +	off = irq & 0x1F;
> +	__raw_writel(1 << off, mxc_irq_base + TZIC_ENSET0 + (index << 2));
> +}
> +
> +static struct irq_chip mxc_tzic_chip = {
> +	.name = "MXC_TZIC",
> +	.ack = mxc_mask_irq,
> +	.mask = mxc_mask_irq,
> +	.unmask = mxc_unmask_irq,
> +};
> +
> +void __init tzic_init_irq(void __iomem *base)
> +{
> +	int i;
> +
> +	mxc_irq_base = base;
> +	mxc_irq_controller_type = MXC_IRQ_TYPE_TZIC;
> +
> +	/* put the TZIC into the reset value with
> +	 * all interrupts disabled
> +	 */
> +	__raw_readl(mxc_irq_base + TZIC_INTCNTL);
> +
> +	__raw_writel(0x80010001, mxc_irq_base + TZIC_INTCNTL);
> +	__raw_readl(mxc_irq_base + TZIC_INTCNTL);
> +	__raw_writel(0x1f, mxc_irq_base + TZIC_PRIOMASK);
> +	__raw_readl(mxc_irq_base + TZIC_PRIOMASK);
> +	__raw_writel(0x02, mxc_irq_base + TZIC_SYNCCTRL);
> +	__raw_readl(mxc_irq_base + TZIC_SYNCCTRL);
> +
> +	for (i = 0; i < 4; i++)
> +		__raw_writel(0xffffffff, mxc_irq_base + TZIC_INTSEC0 + i * 4);
> +
> +	/* disable all interrupts */
> +	for (i = 0; i < 4; i++)
> +		__raw_writel(0xffffffff, mxc_irq_base + TZIC_ENCLEAR0 + i * 4);
> +
> +	for (i = 0; i < 128; i++) {
> +		set_irq_chip(i, &mxc_tzic_chip);
> +		set_irq_handler(i, handle_level_irq);
> +		set_irq_flags(i, IRQF_VALID);
> +	}
> +
> +	printk(KERN_INFO "MXC IRQ initialized\n");
> +}
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

-- 
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria at canonical.com
----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  7:03             ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Eric Miao
@ 2010-02-03 14:20               ` Amit Kucheria
  0 siblings, 0 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03 14:20 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 Feb 02, Eric Miao wrote:
> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
> > From: Amit Kucheria <amit.kucheria@verdurent.com>
> >
> > Add basic clock support, cpu identification, I/O mapping and serial port.
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/mach-mx5/clock.c ? ? ? ? ? ? ? ? ? ?| ?848 ++++++++++++++++++++++++++
> > ?arch/arm/mach-mx5/cpu.c ? ? ? ? ? ? ? ? ? ? ?| ? 45 ++
> > ?arch/arm/mach-mx5/crm_regs.h ? ? ? ? ? ? ? ? | ?583 ++++++++++++++++++
> > ?arch/arm/mach-mx5/devices.c ? ? ? ? ? ? ? ? ?| ? 96 +++
> > ?arch/arm/mach-mx5/devices.h ? ? ? ? ? ? ? ? ?| ? ?4 +
> > ?arch/arm/mach-mx5/mm.c ? ? ? ? ? ? ? ? ? ? ? | ? 88 +++
> > ?arch/arm/plat-mxc/include/mach/common.h ? ? ?| ? ?1 +
> > ?arch/arm/plat-mxc/include/mach/debug-macro.S | ? ?4 +-
> > ?arch/arm/plat-mxc/include/mach/iomux-mx51.h ?| ?340 +++++++++++
> > ?arch/arm/plat-mxc/include/mach/mx51.h ? ? ? ?| ?454 ++++++++++++++
> > ?10 files changed, 2461 insertions(+), 2 deletions(-)
> > ?create mode 100644 arch/arm/mach-mx5/clock.c
> > ?create mode 100644 arch/arm/mach-mx5/cpu.c
> > ?create mode 100644 arch/arm/mach-mx5/crm_regs.h
> > ?create mode 100644 arch/arm/mach-mx5/devices.c
> > ?create mode 100644 arch/arm/mach-mx5/devices.h
> > ?create mode 100644 arch/arm/mach-mx5/mm.c
> > ?create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
> > ?create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h
> >
> > diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
> > new file mode 100644
> > index 0000000..595f966
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/clock.c
> > @@ -0,0 +1,848 @@
> > +/*
> > + * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> > + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> > + *
> > + * The code contained herein is licensed under the GNU General Public
> > + * License. You may obtain a copy of the GNU General Public License
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/mm.h>
> > +#include <linux/delay.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +
> > +#include <asm/clkdev.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +#include <mach/clock.h>
> > +
> > +#include "crm_regs.h"
> > +
> > +static void __iomem *pll_base[] = {
> > + ? ? ? MX51_DPLL1_BASE,
> > + ? ? ? MX51_DPLL2_BASE,
> > + ? ? ? MX51_DPLL3_BASE,
> > +};
> > +
> > +/* External clock values passed-in by the board code */
> > +static unsigned long external_high_reference, external_low_reference;
> > +static unsigned long oscillator_reference, ckih2_reference;
> > +
> > +static struct clk osc_clk;
> > +static struct clk pll1_main_clk;
> > +static struct clk pll1_sw_clk;
> > +static struct clk pll2_sw_clk;
> > +static struct clk pll3_sw_clk;
> > +static struct clk lp_apm_clk;
> > +static struct clk periph_apm_clk;
> > +static struct clk ahb_clk;
> > +static struct clk ipg_clk;
> > +
> > +#define MAX_DPLL_WAIT_TRIES ? ?1000 /* 1000 * udelay(1) = 1ms */
> > +
> > +static int _clk_ccgr_enable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(clk->enable_reg);
> > + ? ? ? reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
> > + ? ? ? __raw_writel(reg, clk->enable_reg);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static void _clk_ccgr_disable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > + ? ? ? reg = __raw_readl(clk->enable_reg);
> > + ? ? ? reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
> > + ? ? ? __raw_writel(reg, clk->enable_reg);
> > +
> > +}
> > +
> > +static void _clk_ccgr_disable_inwait(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(clk->enable_reg);
> > + ? ? ? reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
> > + ? ? ? reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
> > + ? ? ? __raw_writel(reg, clk->enable_reg);
> > +}
> > +
> > +/*
> > + * For the 4-to-1 muxed input clock
> > + */
> > +static inline u32 _get_mux(struct clk *parent, struct clk *m0,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ?struct clk *m1, struct clk *m2, struct clk *m3)
> > +{
> > + ? ? ? if (parent == m0)
> > + ? ? ? ? ? ? ? return 0;
> > + ? ? ? else if (parent == m1)
> > + ? ? ? ? ? ? ? return 1;
> > + ? ? ? else if (parent == m2)
> > + ? ? ? ? ? ? ? return 2;
> > + ? ? ? else if (parent == m3)
> > + ? ? ? ? ? ? ? return 3;
> > + ? ? ? else
> > + ? ? ? ? ? ? ? BUG();
> > +
> > + ? ? ? return -EINVAL;
> > +}
> > +
> > +static inline void __iomem *_get_pll_base(struct clk *pll)
> > +{
> > + ? ? ? if (pll == &pll1_main_clk)
> > + ? ? ? ? ? ? ? return pll_base[0];
> > + ? ? ? else if (pll == &pll2_sw_clk)
> > + ? ? ? ? ? ? ? return pll_base[1];
> > + ? ? ? else if (pll == &pll3_sw_clk)
> > + ? ? ? ? ? ? ? return pll_base[2];
> > + ? ? ? else
> > + ? ? ? ? ? ? ? BUG();
> > +
> > + ? ? ? return NULL;
> > +}
> > +
> > +static unsigned long clk_pll_get_rate(struct clk *clk)
> > +{
> > + ? ? ? long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
> > + ? ? ? unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
> > + ? ? ? void __iomem *pllbase;
> > + ? ? ? s64 temp;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? pllbase = _get_pll_base(clk);
> > +
> > + ? ? ? dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> > + ? ? ? pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> > + ? ? ? dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
> > +
> > + ? ? ? if (pll_hfsm == 0) {
> > + ? ? ? ? ? ? ? dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
> > + ? ? ? ? ? ? ? dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
> > + ? ? ? ? ? ? ? dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
> > + ? ? ? ? ? ? ? dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
> > + ? ? ? ? ? ? ? dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
> > + ? ? ? }
> > + ? ? ? pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
> > + ? ? ? mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
> > + ? ? ? mfi = (mfi <= 5) ? 5 : mfi;
> > + ? ? ? mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
> > + ? ? ? mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
> > + ? ? ? /* Sign extend to 32-bits */
> > + ? ? ? if (mfn >= 0x04000000) {
> > + ? ? ? ? ? ? ? mfn |= 0xFC000000;
> > + ? ? ? ? ? ? ? mfn_abs = -mfn;
> > + ? ? ? }
> > +
> > + ? ? ? ref_clk = 2 * parent_rate;
> > + ? ? ? if (dbl != 0)
> > + ? ? ? ? ? ? ? ref_clk *= 2;
> > +
> > + ? ? ? ref_clk /= (pdf + 1);
> > + ? ? ? temp = (u64) ref_clk * mfn_abs;
> > + ? ? ? do_div(temp, mfd + 1);
> > + ? ? ? if (mfn < 0)
> > + ? ? ? ? ? ? ? temp = -temp;
> > + ? ? ? temp = (ref_clk * mfi) + temp;
> > +
> > + ? ? ? return temp;
> > +}
> > +
> > +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > + ? ? ? u32 reg;
> > + ? ? ? void __iomem *pllbase;
> > +
> > + ? ? ? long mfi, pdf, mfn, mfd = 999999;
> > + ? ? ? s64 temp64;
> > + ? ? ? unsigned long quad_parent_rate;
> > + ? ? ? unsigned long pll_hfsm, dp_ctl;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? pllbase = _get_pll_base(clk);
> > +
> > + ? ? ? quad_parent_rate = 4 * parent_rate;
> > + ? ? ? pdf = mfi = -1;
> > + ? ? ? while (++pdf < 16 && mfi < 5)
> > + ? ? ? ? ? ? ? mfi = rate * (pdf+1) / quad_parent_rate;
> > + ? ? ? if (mfi > 15)
> > + ? ? ? ? ? ? ? return -1;
> > + ? ? ? pdf--;
> > +
> > + ? ? ? temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
> > + ? ? ? do_div(temp64, quad_parent_rate/1000000);
> > + ? ? ? mfn = (long)temp64;
> > +
> > + ? ? ? dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> > + ? ? ? /* use dpdck0_2 */
> > + ? ? ? __raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
> > + ? ? ? pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> > + ? ? ? if (pll_hfsm == 0) {
> > + ? ? ? ? ? ? ? reg = mfi << 4 | pdf;
> > + ? ? ? ? ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_OP);
> > + ? ? ? ? ? ? ? __raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
> > + ? ? ? ? ? ? ? __raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? reg = mfi << 4 | pdf;
> > + ? ? ? ? ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
> > + ? ? ? ? ? ? ? __raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
> > + ? ? ? ? ? ? ? __raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
> > + ? ? ? }
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static int _clk_pll_enable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > + ? ? ? void __iomem *pllbase;
> > + ? ? ? int i = 0;
> > +
> > + ? ? ? pllbase = _get_pll_base(clk);
> > + ? ? ? reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
> > + ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> > +
> > + ? ? ? /* Wait for lock */
> > + ? ? ? while ((!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF))
> > + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? i++;
> > + ? ? ? ? ? ? ? udelay(1);
> > + ? ? ? }
> 
> 
> Mmm... this really hurts my eyes:
> 
> 	
> 	do {
> 		v = __raw_readl(pllbase + MXC_PLL_DP_CTL)
> 		if (v & MXC_PLL_DP_CTL_LRF)
> 			break;
> 		
> 		udelay(1);
> 	} while (++i < MAX_DPLL_WAIT_TRIES);

(Shrug) I picked it up from OMAP code. But your style is better.

> > +
> > + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: pll locking failed\n");
> > + ? ? ? ? ? ? ? return -EINVAL;
> > + ? ? ? }
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static void _clk_pll_disable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > + ? ? ? void __iomem *pllbase;
> > +
> > + ? ? ? pllbase = _get_pll_base(clk);
> > + ? ? ? reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
> > + ? ? ? __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> > +}
> > +
> > +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > + ? ? ? /* When switching from pll_main_clk to a bypass clock, first select a
> > + ? ? ? ? ?multiplexed clock in 'step_sel', then shift the glitchless mux
> > + ? ? ? ? ?'pll1_sw_clk_sel'.
> > + ? ? ? ? ?When switching back, do it in reverse order
> > + ? ? ? */
> 
> comment style ... not sure if this leaks apw's checkscripts, heh :)

The patch was checkpatch approved ;)
But will fix.

> > + ? ? ? if (parent == &pll1_main_clk) {
> > + ? ? ? ? ? ? ? /* Switch to pll1_main_clk */
> > + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> > + ? ? ? ? ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> > + ? ? ? ? ? ? ? /* step_clk mux switched to lp_apm, to save power. */
> > + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> > + ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > + ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? if (parent == &lp_apm_clk) {
> > + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > + ? ? ? ? ? ? ? } else ?if (parent == &pll2_sw_clk) {
> > + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED <<
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > + ? ? ? ? ? ? ? } else ?if (parent == &pll3_sw_clk) {
> > + ? ? ? ? ? ? ? ? ? ? ? reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > + ? ? ? ? ? ? ? } else
> > + ? ? ? ? ? ? ? ? ? ? ? return -EINVAL;
> 
> Again, hurts my eyes:
> 
> 		if (...)
> 			step = MXC_CCM_CCSR_STEP_SEL_LP_APM;
> 		else if (...)
> 			step = MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED;
> 		else if (...)
> 			step = ...
> 
> 		reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
> 		reg |= step << MXC_CCM_CCSR_STEP_SEL_OFFSET;
> 		...

Fixed.

> > +
> > + ? ? ? ? ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> > + ? ? ? ? ? ? ? /* Switch to step_clk */
> > + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> > + ? ? ? ? ? ? ? reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> > + ? ? ? }
> > + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> > + ? ? ? return 0;
> > +}
> > +
> > +static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
> > +{
> > + ? ? ? u32 reg, div;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? div = 1;
> > + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > + ? ? ? if (clk->parent == &pll2_sw_clk) {
> > + ? ? ? ? ? ? ? div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
> > + ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
> > + ? ? ? } else if (clk->parent == &pll3_sw_clk) {
> > + ? ? ? ? ? ? ? div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
> > + ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
> > + ? ? ? }
> > + ? ? ? return parent_rate / div;
> > +}
> > +
> > +static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > + ? ? ? if (parent == &pll2_sw_clk)
> > + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> > + ? ? ? else
> > + ? ? ? ? ? ? ? reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> > +
> > + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> > + ? ? ? return 0;
> > +}
> > +
> > +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? if (parent == &osc_clk)
> > + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
> > + ? ? ? else
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? __raw_writel(reg, MXC_CCM_CCSR);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static unsigned long clk_arm_get_rate(struct clk *clk)
> > +{
> > + ? ? ? u32 cacrr, div;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > + ? ? ? cacrr = __raw_readl(MXC_CCM_CACRR);
> > + ? ? ? div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
> > +
> > + ? ? ? return parent_rate / div;
> > +}
> > +
> > +static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg, mux;
> > + ? ? ? int i = 0;
> > +
> > + ? ? ? mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
> > + ? ? ? reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
> > + ? ? ? __raw_writel(reg, MXC_CCM_CBCMR);
> > +
> > + ? ? ? /* Wait for lock */
> > + ? ? ? while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)
> > + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? i++;
> > + ? ? ? ? ? ? ? udelay(1);
> > + ? ? ? }
> > +
> > + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: Set parent for periph_apm clock failed\n");
> > + ? ? ? ? ? ? ? return -EINVAL;
> > + ? ? ? }
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static unsigned long clk_main_bus_get_rate(struct clk *clk)
> > +{
> > + ? ? ? return clk_get_rate(clk->parent);
> > +}
> > +
> > +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > +
> > + ? ? ? if (parent == &pll2_sw_clk)
> > + ? ? ? ? ? ? ? reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> > + ? ? ? else if (parent == &periph_apm_clk)
> > + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> > + ? ? ? else
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static struct clk main_bus_clk = {
> > + ? ? ? .parent = &pll2_sw_clk,
> > + ? ? ? .set_parent = _clk_main_bus_set_parent,
> > + ? ? ? .get_rate = clk_main_bus_get_rate,
> > +};
> > +
> > +static unsigned long clk_ahb_get_rate(struct clk *clk)
> > +{
> > + ? ? ? u32 reg, div;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > + ? ? ? div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
> > + ? ? ? ? ? ? ?MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
> > + ? ? ? return parent_rate / div;
> > +}
> > +
> > +
> > +static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > + ? ? ? u32 reg, div;
> > + ? ? ? unsigned long parent_rate;
> > + ? ? ? int i = 0;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? div = parent_rate / rate;
> > + ? ? ? if (div > 8 || div < 1 || ((parent_rate / div) != rate))
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > + ? ? ? reg &= ~MXC_CCM_CBCDR_AHB_PODF_MASK;
> > + ? ? ? reg |= (div - 1) << MXC_CCM_CBCDR_AHB_PODF_OFFSET;
> > + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> > +
> > + ? ? ? /* Wait for lock */
> > + ? ? ? while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_AHB_PODF_BUSY)
> > + ? ? ? ? ? ? ? && i < MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? i++;
> > + ? ? ? ? ? ? ? udelay(1);
> > + ? ? ? }
> 
> Provided this loop sequence appears so many times here, maybe we can just
> invent a static inline function for this, e.g. dpll_wait_flags(register, flags)

Will investigate.

> > +
> > + ? ? ? if (i == MAX_DPLL_WAIT_TRIES) {
> > + ? ? ? ? ? ? ? printk(KERN_ERR "MX5: clk_ahb_set_rate failed\n");
> > + ? ? ? ? ? ? ? return -EINVAL;
> > + ? ? ? }
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static unsigned long _clk_ahb_round_rate(struct clk *clk,
> > + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? unsigned long rate)
> > +{
> > + ? ? ? u32 div;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? div = parent_rate / rate;
> > + ? ? ? if (div > 8)
> > + ? ? ? ? ? ? ? div = 8;
> > + ? ? ? else if (div == 0)
> > + ? ? ? ? ? ? ? div++;
> > + ? ? ? return parent_rate / div;
> > +}
> > +
> > +
> > +static int _clk_max_enable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? _clk_ccgr_enable(clk);
> > +
> > + ? ? ? /* Handshake with MAX when LPM is entered. */
> > + ? ? ? reg = __raw_readl(MXC_CCM_CLPCR);
> > + ? ? ? reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
> > + ? ? ? __raw_writel(reg, MXC_CCM_CLPCR);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static void _clk_max_disable(struct clk *clk)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? _clk_ccgr_disable_inwait(clk);
> > +
> > + ? ? ? /* No Handshake with MAX when LPM is entered as its disabled. */
> > + ? ? ? reg = __raw_readl(MXC_CCM_CLPCR);
> > + ? ? ? reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
> > + ? ? ? __raw_writel(reg, MXC_CCM_CLPCR);
> > +}
> > +
> > +static unsigned long clk_ipg_get_rate(struct clk *clk)
> > +{
> > + ? ? ? u32 reg, div;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > + ? ? ? div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
> > + ? ? ? ? ? ? ?MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
> > +
> > + ? ? ? return parent_rate / div;
> > +}
> > +
> > +static unsigned long clk_ipg_per_get_rate(struct clk *clk)
> > +{
> > + ? ? ? u32 reg, prediv1, prediv2, podf;
> > + ? ? ? unsigned long parent_rate;
> > +
> > + ? ? ? parent_rate = clk_get_rate(clk->parent);
> > +
> > + ? ? ? if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
> > + ? ? ? ? ? ? ? /* the main_bus_clk is the one before the DVFS engine */
> > + ? ? ? ? ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > + ? ? ? ? ? ? ? prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
> > + ? ? ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
> > + ? ? ? ? ? ? ? prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
> > + ? ? ? ? ? ? ? ? ? ? ? ? ?MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
> > + ? ? ? ? ? ? ? podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
> > + ? ? ? ? ? ? ? ? ? ? ? MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
> > + ? ? ? ? ? ? ? return parent_rate / (prediv1 * prediv2 * podf);
> > + ? ? ? } else if (clk->parent == &ipg_clk) {
> > + ? ? ? ? ? ? ? return parent_rate;
> 
> unnecessary braces
> 
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? BUG();
> 
> ditto
> 
> > + ? ? ? }
> > +}
> > +
> > +static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR);
> > +
> > + ? ? ? reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
> > + ? ? ? reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
> > +
> > + ? ? ? if (parent == &ipg_clk)
> > + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
> > + ? ? ? else if (parent == &lp_apm_clk)
> > + ? ? ? ? ? ? ? reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
> > + ? ? ? else if (parent != &main_bus_clk)
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? __raw_writel(reg, MXC_CCM_CBCMR);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static unsigned long clk_uart_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_UART_CLK_PRED_MASK) >>
> > + ? ? ? ? ? ? ? ? MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
> > + ? ? ? podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
> > + ? ? ? ? ? ? ? MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
> > +
> > + ? ? ? return parent_rate / (prediv * podf);
> > +}
> > +
> > +static int _clk_uart_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_UART_CLK_SEL_MASK;
> > + ? ? ? reg |= mux << MXC_CCM_CSCMR1_UART_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;
> > +}
> > +
> > +static unsigned long get_low_reference_clock_rate(struct clk *clk)
> > +{
> > + ? ? ? return external_low_reference;
> > +}
> > +
> > +static unsigned long get_oscillator_reference_clock_rate(struct clk *clk)
> > +{
> > + ? ? ? return oscillator_reference;
> > +}
> > +
> > +static unsigned long get_ckih2_reference_clock_rate(struct clk *clk)
> > +{
> > + ? ? ? return ckih2_reference;
> > +}
> > +
> > +/* External high frequency clock */
> > +static struct clk ckih_clk = {
> > + ? ? ? .get_rate = get_high_reference_clock_rate,
> > +};
> > +
> > +static struct clk ckih2_clk = {
> > + ? ? ? .get_rate = get_ckih2_reference_clock_rate,
> > +};
> > +
> > +static struct clk osc_clk = {
> > + ? ? ? .get_rate = get_oscillator_reference_clock_rate,
> > +};
> > +
> > +/* External low frequency (32kHz) clock */
> > +static struct clk ckil_clk = {
> > + ? ? ? .get_rate = get_low_reference_clock_rate,
> > +};
> 
> That's why Jerremy is coming up with a clk_fixed, to address exactly such
> awkward situations :)
 
Heh, yes :)

> > +
> > +static struct clk pll1_main_clk = {
> > + ? ? ? .parent = &osc_clk,
> > + ? ? ? .get_rate = clk_pll_get_rate,
> > + ? ? ? .enable = _clk_pll_enable,
> > + ? ? ? .disable = _clk_pll_disable,
> > +};
> > +
> > +/* Clock tree block diagram (WIP):
> > + * ? ? CCM: Clock Controller Module
> > + *
> > + * PLL output -> |
> > + * ? ? ? ? ? ? ? | CCM Switcher -> CCM_CLK_ROOT_GEN ->
> > + * PLL bypass -> |
> > + *
> > + */
> > +
> > +/* PLL1 SW supplies to ARM core */
> > +static struct clk pll1_sw_clk = {
> > + ? ? ? .parent = &pll1_main_clk,
> > + ? ? ? .set_parent = _clk_pll1_sw_set_parent,
> > + ? ? ? .get_rate = clk_pll1_sw_get_rate,
> > +};
> > +
> > +/* PLL2 SW supplies to AXI/AHB/IP buses */
> > +static struct clk pll2_sw_clk = {
> > + ? ? ? .parent = &osc_clk,
> > + ? ? ? .get_rate = clk_pll_get_rate,
> > + ? ? ? .set_rate = _clk_pll_set_rate,
> > + ? ? ? .set_parent = _clk_pll2_sw_set_parent,
> > + ? ? ? .enable = _clk_pll_enable,
> > + ? ? ? .disable = _clk_pll_disable,
> > +};
> > +
> > +/* PLL3 SW supplies to serial clocks like USB, SSI, etc. */
> > +static struct clk pll3_sw_clk = {
> > + ? ? ? .parent = &osc_clk,
> > + ? ? ? .set_rate = _clk_pll_set_rate,
> > + ? ? ? .get_rate = clk_pll_get_rate,
> > + ? ? ? .enable = _clk_pll_enable,
> > + ? ? ? .disable = _clk_pll_disable,
> > +};
> > +
> > +/* Low-power Audio Playback Mode clock */
> > +static struct clk lp_apm_clk = {
> > + ? ? ? .parent = &osc_clk,
> > + ? ? ? .set_parent = _clk_lp_apm_set_parent,
> > +};
> > +
> > +static struct clk periph_apm_clk = {
> > + ? ? ? .parent = &pll1_sw_clk,
> > + ? ? ? .set_parent = _clk_periph_apm_set_parent,
> > +};
> > +
> > +static struct clk cpu_clk = {
> > + ? ? ? .parent = &pll1_sw_clk,
> > + ? ? ? .get_rate = clk_arm_get_rate,
> > +};
> > +
> > +static struct clk ahb_clk = {
> > + ? ? ? .parent = &main_bus_clk,
> > + ? ? ? .get_rate = clk_ahb_get_rate,
> > + ? ? ? .set_rate = _clk_ahb_set_rate,
> > + ? ? ? .round_rate = _clk_ahb_round_rate,
> > +};
> > +
> > +/* Main IP interface clock for access to registers */
> > +static struct clk ipg_clk = {
> > + ? ? ? .parent = &ahb_clk,
> > + ? ? ? .get_rate = clk_ipg_get_rate,
> > +};
> > +
> > +static struct clk ipg_perclk = {
> > + ? ? ? .parent = &lp_apm_clk,
> > + ? ? ? .get_rate = clk_ipg_per_get_rate,
> > + ? ? ? .set_parent = _clk_ipg_per_set_parent,
> > +};
> > +
> > +static struct clk uart_root_clk = {
> > + ? ? ? .parent = &pll2_sw_clk,
> > + ? ? ? .get_rate = clk_uart_get_rate,
> > + ? ? ? .set_parent = _clk_uart_set_parent,
> > +};
> > +
> > +static struct clk ahb_max_clk = {
> > + ? ? ? .parent = &ahb_clk,
> > + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> > + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
> > + ? ? ? .enable = _clk_max_enable,
> > + ? ? ? .disable = _clk_max_disable,
> > +};
> > +
> > +static struct clk aips_tz1_clk = {
> > + ? ? ? .parent = &ahb_clk,
> > + ? ? ? .secondary = &ahb_max_clk,
> > + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> > + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
> > + ? ? ? .enable = _clk_ccgr_enable,
> > + ? ? ? .disable = _clk_ccgr_disable_inwait,
> > +};
> > +
> > +static struct clk aips_tz2_clk = {
> > + ? ? ? .parent = &ahb_clk,
> > + ? ? ? .secondary = &ahb_max_clk,
> > + ? ? ? .enable_reg = MXC_CCM_CCGR0,
> > + ? ? ? .enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
> > + ? ? ? .enable = _clk_ccgr_enable,
> > + ? ? ? .disable = _clk_ccgr_disable_inwait,
> > +};
> > +
> > +static struct clk gpt_32k_clk = {
> > + ? ? ? .id = 0,
> > + ? ? ? .parent = &ckil_clk,
> > +};
> > +
> > +#define DEFINE_CLOCK(name, i, er, es, gr, sr, p, s) ? ?\
> > + ? ? ? static struct clk name = { ? ? ? ? ? ? ? ? ? ? ?\
> > + ? ? ? ? ? ? ? .id ? ? ? ? ? ? = i, ? ? ? ? ? ? ? ? ? ?\
> > + ? ? ? ? ? ? ? .enable_reg ? ? = er, ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? .enable_shift ? = es, ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? .get_rate ? ? ? = gr, ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? .set_rate ? ? ? = sr, ? ? ? ? ? ? ? ? ? \
> > + ? ? ? ? ? ? ? .enable ? ? ? ? = _clk_ccgr_enable, ? ? \
> > + ? ? ? ? ? ? ? .disable ? ? ? ?= _clk_ccgr_disable, ? ?\
> > + ? ? ? ? ? ? ? .parent ? ? ? ? = p, ? ? ? ? ? ? ? ? ? ?\
> > + ? ? ? ? ? ? ? .secondary ? ? ?= s, ? ? ? ? ? ? ? ? ? ?\
> > + ? ? ? }
> > +
> > +/* DEFINE_CLOCK(name, id, enable_reg, enable_shift,
> > + ? get_rate, set_rate, parent, secondary); */
> > +
> > +/* Shared peripheral bus arbiter */
> > +DEFINE_CLOCK(spba_clk, 0, MXC_CCM_CCGR5, MXC_CCM_CCGRx_CG0_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> > +
> > +/* UART */
> > +DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG4_OFFSET,
> > + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> > +DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG6_OFFSET,
> > + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> > +DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG8_OFFSET,
> > + ? ? ? NULL, ?NULL, &uart_root_clk, NULL);
> > +DEFINE_CLOCK(uart1_ipg_clk, 0, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG3_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, &aips_tz1_clk);
> > +DEFINE_CLOCK(uart2_ipg_clk, 1, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG5_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, &aips_tz1_clk);
> > +DEFINE_CLOCK(uart3_ipg_clk, 2, MXC_CCM_CCGR1, MXC_CCM_CCGRx_CG7_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, &spba_clk);
> > +
> > +/* GPT */
> > +DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG9_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_perclk, NULL);
> > +DEFINE_CLOCK(gpt_ipg_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG10_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> > +
> > +/* FEC */
> > +DEFINE_CLOCK(fec_clk, 0, MXC_CCM_CCGR2, MXC_CCM_CCGRx_CG12_OFFSET,
> > + ? ? ? NULL, ?NULL, &ipg_clk, NULL);
> > +
> > +#define _REGISTER_CLOCK(d, n, c) \
> > + ? ? ? { \
> > + ? ? ? ? ? ? ? .dev_id = d, \
> > + ? ? ? ? ? ? ? .con_id = n, \
> > + ? ? ? ? ? ? ? .clk = &c, ? \
> > + ? ? ? },
> > +
> > +static struct clk_lookup lookups[] __initdata = {
> > + ? ? ? _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(NULL, "gpt", gpt_clk)
> > + ? ? ? _REGISTER_CLOCK("fec.0", NULL, fec_clk)
> > +};
> > +
> > +static void clk_tree_init(void)
> > +{
> > + ? ? ? u32 reg;
> > +
> > + ? ? ? ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
> > +
> > + ? ? ? /*
> > + ? ? ? ?* Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
> > + ? ? ? ?* 8MHz, its derived from lp_apm.
> > + ? ? ? ?* FIXME: Verify if true for all boards
> > + ? ? ? ?*/
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCDR);
> > + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
> > + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
> > + ? ? ? reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
> > + ? ? ? reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
> > + ? ? ? __raw_writel(reg, MXC_CCM_CBCDR);
> > +
> > + ? ? ? /* set parent for pll1, pll2 and pll3 */
> > + ? ? ? pll1_main_clk.parent = &osc_clk;
> > + ? ? ? pll2_sw_clk.parent = &osc_clk;
> > + ? ? ? pll3_sw_clk.parent = &osc_clk;
> > +
> > + ? ? ? /* set ipg_perclk parent */
> > + ? ? ? ipg_perclk.parent = &lp_apm_clk;
> > + ? ? ? reg = __raw_readl(MXC_CCM_CBCMR);
> > + ? ? ? if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
> > + ? ? ? ? ? ? ? ipg_perclk.parent = &ipg_clk;
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
> > + ? ? ? ? ? ? ? ? ? ? ? ipg_perclk.parent = &main_bus_clk;
> > + ? ? ? }
> > +}
> > +
> > +int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> > + ? ? ? ? ? ? ? ? ? ? ? unsigned long ckih1, unsigned long ckih2)
> > +{
> > + ? ? ? int i;
> > +
> > + ? ? ? external_low_reference = ckil;
> > + ? ? ? external_high_reference = ckih1;
> > + ? ? ? ckih2_reference = ckih2;
> > + ? ? ? oscillator_reference = osc;
> > +
> > + ? ? ? for (i = 0; i < ARRAY_SIZE(lookups); i++)
> > + ? ? ? ? ? ? ? clkdev_add(&lookups[i]);
> > +
> > + ? ? ? clk_tree_init();
> > +
> > + ? ? ? clk_enable(&cpu_clk);
> > + ? ? ? clk_enable(&main_bus_clk);
> > +
> > + ? ? ? /* System timer */
> > + ? ? ? mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> > + ? ? ? ? ? ? ? MX51_MXC_INT_GPT);
> > + ? ? ? return 0;
> > +}
> > diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
> > new file mode 100644
> > index 0000000..93f1d5a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/cpu.c
> > @@ -0,0 +1,45 @@
> > +/*
> > + * Copyright 2008-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + *
> > + * This file contains the CPU initialization code.
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <linux/kernel.h>
> > +#include <linux/init.h>
> > +#include <mach/hardware.h>
> > +#include <asm/io.h>
> > +
> > +static int __init post_cpu_init(void)
> > +{
> > + ? ? ? unsigned int reg;
> > + ? ? ? void __iomem *base;
> > +
> > + ? ? ? if (cpu_is_mx51()) {
> > + ? ? ? ? ? ? ? base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x40);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x44);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x48);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x4C);
> > + ? ? ? ? ? ? ? reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> > + ? ? ? ? ? ? ? __raw_writel(reg, base + 0x50);
> > +
> > + ? ? ? ? ? ? ? base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x40);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x44);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x48);
> > + ? ? ? ? ? ? ? __raw_writel(0x0, base + 0x4C);
> > + ? ? ? ? ? ? ? reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> > + ? ? ? ? ? ? ? __raw_writel(reg, base + 0x50);
> > + ? ? ? }
> > + ? ? ? return 0;
> > +}
> > +
> > +postcore_initcall(post_cpu_init);
> > diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
> > new file mode 100644
> > index 0000000..c776b9a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/crm_regs.h
> > @@ -0,0 +1,583 @@
> > +/*
> > + * Copyright 2008-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
> > +#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
> > +
> > +#define MX51_CCM_BASE ? ? ? ? ?MX51_IO_ADDRESS(MX51_CCM_BASE_ADDR)
> > +#define MX51_DPLL1_BASE ? ? ? ? ? ? ? ?MX51_IO_ADDRESS(MX51_PLL1_BASE_ADDR)
> > +#define MX51_DPLL2_BASE ? ? ? ? ? ? ? ?MX51_IO_ADDRESS(MX51_PLL2_BASE_ADDR)
> 
> .... skipping register definitions ....
> 
> > +#define MXC_SRPGC_EMI_PUPSCR ? (MXC_SRPGC_EMI_BASE + 0x4)
> > +#define MXC_SRPGC_EMI_PDNSCR ? (MXC_SRPGC_EMI_BASE + 0x8)
> > +
> > +#endif ? ? ? ? ? ? ? ? ? ? ? ? /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
> > diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> > new file mode 100644
> > index 0000000..55eb089
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/devices.c
> > @@ -0,0 +1,96 @@
> > +/*
> > + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
> > + *
> > + * The code contained herein is licensed under the GNU General Public
> > + * License. You may obtain a copy of the GNU General Public License
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/platform_device.h>
> > +#include <mach/hardware.h>
> > +#include <mach/imx-uart.h>
> > +
> > +static struct resource uart0[] = {
> > + ? ? ? {
> > + ? ? ? ? ? ? ? .start = MX51_UART1_BASE_ADDR,
> > + ? ? ? ? ? ? ? .end = MX51_UART1_BASE_ADDR + 0x0B5,
> > + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> > + ? ? ? }, {
> > + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART1,
> > + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART1,
> > + ? ? ? ? ? ? ? .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 = MX51_UART2_BASE_ADDR,
> > + ? ? ? ? ? ? ? .end = MX51_UART2_BASE_ADDR + 0x0B5,
> > + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> > + ? ? ? }, {
> > + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART2,
> > + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART2,
> > + ? ? ? ? ? ? ? .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 = MX51_UART3_BASE_ADDR,
> > + ? ? ? ? ? ? ? .end = MX51_UART3_BASE_ADDR + 0x0B5,
> > + ? ? ? ? ? ? ? .flags = IORESOURCE_MEM,
> > + ? ? ? }, {
> > + ? ? ? ? ? ? ? .start = MX51_MXC_INT_UART3,
> > + ? ? ? ? ? ? ? .end = MX51_MXC_INT_UART3,
> > + ? ? ? ? ? ? ? .flags = IORESOURCE_IRQ,
> > + ? ? ? },
> > +};
> > +
> > +struct platform_device mxc_uart_device2 = {
> > + ? ? ? .name = "imx-uart",
> > + ? ? ? .id = 2,
> > + ? ? ? .resource = uart2,
> > + ? ? ? .num_resources = ARRAY_SIZE(uart2),
> > +};
> > +
> > +static struct resource mxc_fec_resources[] = {
> > + ? ? ? {
> > + ? ? ? ? ? ? ? .start ?= MX51_MXC_FEC_BASE_ADDR,
> > + ? ? ? ? ? ? ? .end ? ?= MX51_MXC_FEC_BASE_ADDR + 0xfff,
> > + ? ? ? ? ? ? ? .flags ?= IORESOURCE_MEM,
> > + ? ? ? }, {
> > + ? ? ? ? ? ? ? .start ?= MX51_MXC_INT_FEC,
> > + ? ? ? ? ? ? ? .end ? ?= MX51_MXC_INT_FEC,
> > + ? ? ? ? ? ? ? .flags ?= IORESOURCE_IRQ,
> > + ? ? ? },
> > +};
> > +
> > +struct platform_device mxc_fec_device = {
> > + ? ? ? .name = "fec",
> > + ? ? ? .id = 0,
> > + ? ? ? .num_resources = ARRAY_SIZE(mxc_fec_resources),
> > + ? ? ? .resource = mxc_fec_resources,
> > +};
> > +
> > +/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
> > +int __init mxc_register_gpios(void)
> > +{
> > + ? ? ? return 0;
> > +}
> > diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> > new file mode 100644
> > index 0000000..f339ab8
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/devices.h
> > @@ -0,0 +1,4 @@
> > +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;
> > diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
> > new file mode 100644
> > index 0000000..d66c31a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/mm.c
> > @@ -0,0 +1,88 @@
> > +/*
> > + * Copyright 2008-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + *
> > + * Create static mapping between physical to virtual memory.
> > + */
> > +
> > +#include <linux/mm.h>
> > +#include <linux/init.h>
> > +
> > +#include <asm/mach/map.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +#include <mach/iomux-v3.h>
> > +
> > +/*
> > + * Define the MX51 memory map.
> > + */
> > +static struct map_desc mxc_io_desc[] __initdata = {
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_IRAM_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
> > + ? ? ? ?.length = MX51_IRAM_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_DEBUG_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
> > + ? ? ? ?.length = MX51_DEBUG_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_TZIC_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
> > + ? ? ? ?.length = MX51_TZIC_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_AIPS1_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
> > + ? ? ? ?.length = MX51_AIPS1_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_SPBA0_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
> > + ? ? ? ?.length = MX51_SPBA0_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_AIPS2_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
> > + ? ? ? ?.length = MX51_AIPS2_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> > + ? ? ? {
> > + ? ? ? ?.virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
> > + ? ? ? ?.pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
> > + ? ? ? ?.length = MX51_NFC_AXI_SIZE,
> > + ? ? ? ?.type = MT_DEVICE},
> 
> Weird alignment, guess due to leading white spaces?

Fixed.

> 
> .... skipping the rest ....

Thanks for the review.

/Amit
-- 
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria at canonical.com
----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03 13:24       ` Amit Kucheria
@ 2010-02-03 15:09         ` Eric Miao
  2010-02-04  0:54           ` Eric Miao
  2010-02-04 17:09         ` Nguyen Dinh-R00091
  1 sibling, 1 reply; 40+ messages in thread
From: Eric Miao @ 2010-02-03 15:09 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 3, 2010 at 5:24 AM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> On 10 Feb 02, Eric Miao wrote:
>> Hi Amit,
>>
>> Just some nit-picking review comments, see below:
>>
>> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria
>> <amit.kucheria@canonical.com> wrote:
>> > Freescale i.MX51 processor uses a new interrupt controller. Add
>> > driver for TrustZone Interrupt Controller
>> >
>> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
>> > ---
>> > ?arch/arm/plat-mxc/Kconfig ?| ? ?8 ++
>> > ?arch/arm/plat-mxc/Makefile | ? ?3 +
>> > ?arch/arm/plat-mxc/tzic.c ? | ?182 ++++++++++++++++++++++++++++++++++++++++++++
>> > ?3 files changed, 193 insertions(+), 0 deletions(-)
>> > ?create mode 100644 arch/arm/plat-mxc/tzic.c
>> >
>> > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
>> > index 8b0a1ee..59558c4 100644
>> > --- a/arch/arm/plat-mxc/Kconfig
>> > +++ b/arch/arm/plat-mxc/Kconfig
>> > @@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
>> > ? ? ? ? ?requirements for timing.
>> > ? ? ? ? ?Say N here, unless you have a specialized requirement.
>> >
>> > +config MXC_TZIC
>> > + ? ? ? bool "Enable TrustZone Interrupt Controller"
>> > + ? ? ? depends on ARCH_MX51
>>
>> This is the first patch of the base port, yet I cannot find any reference to
>> this ARCH_MX51, did you miss something?
>
> ARCH_MX51 is only introduced in the later patches that add the core i.MX5
> code. Since TZIC is not inherently dependent on i.MX5 (it's merely the first
> processor to use it), I thought of splitting it out as a separate patch.
>
> Does this break the sanctity of one self-contained change?
>

This breaks git-bisect, we may want a buildable kernel every commit if possible.

>> > + ? ? ? help
>> > + ? ? ? ? This will be automatically selected for all processors
>> > + ? ? ? ? containing this interrupt controller.
>> > + ? ? ? ? Say N here only if you are really sure.
>> > +

...

>
> Thanks for the review.
>

No problem, dude.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03 13:38               ` Amit Kucheria
@ 2010-02-03 15:16                 ` Eric Miao
  0 siblings, 0 replies; 40+ messages in thread
From: Eric Miao @ 2010-02-03 15:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 3, 2010 at 5:38 AM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> On 10 Feb 03, Sascha Hauer wrote:
>> On Tue, Feb 02, 2010 at 10:43:33PM -0800, Eric Miao wrote:
>> >
>> > Mmm.... this should be something that we really need to get rid of, it just
>> > makes a single kernel for both TZIC and AVIC together impossible, if that's
>> > so designed by HW, I'm thinking about keeping this into plat-mxc/ is a good
>> > way to go ...
>> >
>> > Sascha, you have any better idea? Provided the other file debug-macro.S in
>> > the same directory already seems to break the support for multiple arches?
>> >
>>
>> I have the following patch which I'm not sure I like better. It can
>> support both irq controller types and does not add overhead if only one
>> of them is compiled in. It might need some refactoring to fit into Amits
>> patch stack.
>
> Is co-existence of TZIC and AVIC a blocker to merging i.MX5 code? I've
> already made changes so that i.MX5 doesn't explode if AVIC is compiled in.
>
> Admittedly the assembly is a bit hard to rid, but we can fix in another set
> of patches geared towards unification of an i.MX kernel. IMHO, making these
> changes along with introducing a new SoC will make things a bit hard to
> follow/merge.
>

I personally don't feel that's a hard requirement, as long as it can be fixed.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
                               ` (3 preceding siblings ...)
  2010-02-03 11:04             ` Sascha Hauer
@ 2010-02-03 16:08             ` Rabin Vincent
  4 siblings, 0 replies; 40+ messages in thread
From: Rabin Vincent @ 2010-02-03 16:08 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 02, 2010 at 09:16:27PM -0800, Amit Kucheria wrote:
> diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
[...]
> +static struct clk_lookup lookups[] __initdata = {
> +	_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(NULL, "gpt", gpt_clk)
> +	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
> +};

This shouldn't be __initdata.  clk_get() uses this, and modules may use
clk_get().

Rabin

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions
  2010-02-03  5:16     ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Amit Kucheria
  2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
@ 2010-02-03 16:23       ` Grant Likely
  1 sibling, 0 replies; 40+ messages in thread
From: Grant Likely @ 2010-02-03 16:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> From: Sascha Hauer <s.hauer@pengutronix.de>
>
> Refactor the timer code into version 1 and version 2.
>
> Essentially there are 2 versions of the timer hardware. Version 1 is found on
> MX1/MXL and MX21. Version 2 is found on MX25, MX27, MX31, MX35, MX37, MX51,
> and future parts.
>
> Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
> Acked-by: Amit Kucheria <amit.kucheria@canonical.com>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/plat-mxc/time.c | ? 19 +++++++++++--------
> ?1 files changed, 11 insertions(+), 8 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
> index 844567e..7d6499e 100644
> --- a/arch/arm/plat-mxc/time.c
> +++ b/arch/arm/plat-mxc/time.c
> @@ -57,6 +57,9 @@
> ?#define MX3_TCN ? ? ? ? ? ? ? ? ? ? ? ?0x24
> ?#define MX3_TCMP ? ? ? ? ? ? ? 0x10
>
> +#define timer_is_v1() ?(cpu_is_mx1() || cpu_is_mx27())
> +#define timer_is_v2() ?(cpu_is_mx3() || cpu_is_mx25())

Just from a defensive programming standpoint, it may be better to
define timer_is_v2() as (!timer_is_v1()).  I assume future parts are
more likely to be v2, and doing it that way means one less place in
the code to modify when new parts appear.

Otherwise,
Acked-by: Grant Likely <grant.likely@secretlab.ca>

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller
  2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
  2010-02-03  6:29         ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Eric Miao
@ 2010-02-03 16:27         ` Grant Likely
  2010-02-04  0:25           ` Amit Kucheria
  2 siblings, 1 reply; 40+ messages in thread
From: Grant Likely @ 2010-02-03 16:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> i.MX51 defines 4 values:
>
> 00: Low Drive Strength
> 01: Medium Drive Strength
> 10: High Drive Strength
> 11: Max Drive Strength
>
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
> ?arch/arm/plat-mxc/include/mach/iomux-v3.h | ? ?8 +++++---
> ?1 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> index 1deda01..f2f73d3 100644
> --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
> +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> @@ -81,11 +81,13 @@ struct pad_desc {
>
> ?#define PAD_CTL_ODE ? ? ? ? ? ? ? ? ? ?(1 << 3)
>
> -#define PAD_CTL_DSE_STANDARD ? ? ? ? ? (0 << 1)
> -#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (1 << 1)
> -#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(2 << 1)
> +#define PAD_CTL_DSE_LOW ? ? ? ? ? ? ? ? ? ? ? ?(0 << 1)
> +#define PAD_CTL_DSE_MED ? ? ? ? ? ? ? ? ? ? ? ?(1 << 1)
> +#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (2 << 1)
> +#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(3 << 1)
>
> ?#define PAD_CTL_SRE_FAST ? ? ? ? ? ? ? (1 << 0)
> +#define PAD_CTL_SRE_SLOW ? ? ? ? ? ? ? (0 << 0)

Shouldn't the addition/change of #defines be done in patches that
actually use them?

It would also help to include in the commit description what the
impact of the change in values is.  The description as written doesn't
really give any indication on why the patch is important, which makes
it hard to review.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5
  2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
  2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
  2010-02-03  6:43           ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Eric Miao
@ 2010-02-03 16:35           ` Grant Likely
  2 siblings, 0 replies; 40+ messages in thread
From: Grant Likely @ 2010-02-03 16:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> Changes separted to help in the review process

<soapbox>Commit log needs to talk about what the patch is, not how it
has changed.  Please state what the patch does and why.  It is also
helpful to have testing information.  The goal is to make it easy for
both patch reviewers on the mailing list *and* people looking at the
commit in git after it is merged.  This commit message doesn't provide
the reader with any helpful information.

Patch version/review information like your comment above typically
goes below the '---' line.</soapbox>

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 08/11] fec: fix uninitialized rx buffer usage
  2010-02-03  5:16                 ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Amit Kucheria
  2010-02-03  5:16                   ` [PATCHv2 09/11] fec: Add LAN8700 phy support Amit Kucheria
@ 2010-02-03 16:46                   ` Grant Likely
  2010-02-03 18:33                     ` Amit Kucheria
  1 sibling, 1 reply; 40+ messages in thread
From: Grant Likely @ 2010-02-03 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> From: Rob Herring <r.herring@freescale.com>
>
> The fec driver was enabling receive buffer descriptor without allocating
> the buffers. Make sure the buffer descriptors are initialized to not
> start receiving packets.
>
> Open also calls fec_restart after the rx buffers are allocated. With the code
> in fec_restart, it zeroes out the buffer descriptors that have just been
> setup.

fec related patches 8 & 9 look okay to me.

g.

-- 
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 08/11] fec: fix uninitialized rx buffer usage
  2010-02-03 16:46                   ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Grant Likely
@ 2010-02-03 18:33                     ` Amit Kucheria
  2010-02-03 18:38                       ` Grant Likely
  0 siblings, 1 reply; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03 18:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 3, 2010 at 8:46 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
>> From: Rob Herring <r.herring@freescale.com>
>>
>> The fec driver was enabling receive buffer descriptor without allocating
>> the buffers. Make sure the buffer descriptors are initialized to not
>> start receiving packets.
>>
>> Open also calls fec_restart after the rx buffers are allocated. With the code
>> in fec_restart, it zeroes out the buffer descriptors that have just been
>> setup.
>
> fec related patches 8 & 9 look okay to me.
>
> g.
>
> --
> Grant Likely, B.Sc., P.Eng.
> Secret Lab Technologies Ltd.

Can I take that as an Acked-by?

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 08/11] fec: fix uninitialized rx buffer usage
  2010-02-03 18:33                     ` Amit Kucheria
@ 2010-02-03 18:38                       ` Grant Likely
  2010-02-03 20:23                         ` Grant Likely
  0 siblings, 1 reply; 40+ messages in thread
From: Grant Likely @ 2010-02-03 18:38 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 3, 2010 at 11:33 AM, Amit Kucheria
<amit.kucheria@canonical.com> wrote:
> On Wed, Feb 3, 2010 at 8:46 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>> On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
>> <amit.kucheria@canonical.com> wrote:
>>> From: Rob Herring <r.herring@freescale.com>
>>>
>>> The fec driver was enabling receive buffer descriptor without allocating
>>> the buffers. Make sure the buffer descriptors are initialized to not
>>> start receiving packets.
>>>
>>> Open also calls fec_restart after the rx buffers are allocated. With the code
>>> in fec_restart, it zeroes out the buffer descriptors that have just been
>>> setup.
>>
>> fec related patches 8 & 9 look okay to me.
>>
>> g.
>>
>> --
>> Grant Likely, B.Sc., P.Eng.
>> Secret Lab Technologies Ltd.
>
> Can I take that as an Acked-by?

of course.

g.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale
  2010-02-03 11:04             ` Sascha Hauer
@ 2010-02-03 20:07               ` Amit Kucheria
  0 siblings, 0 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-03 20:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 Feb 03, Sascha Hauer wrote:
> On Tue, Feb 02, 2010 at 09:16:27PM -0800, Amit Kucheria wrote:
> > From: Amit Kucheria <amit.kucheria@verdurent.com>
> > 
> > Add basic clock support, cpu identification, I/O mapping and serial port.
> > 
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> >  arch/arm/mach-mx5/clock.c                    |  848 ++++++++++++++++++++++++++
> >  arch/arm/mach-mx5/cpu.c                      |   45 ++
> >  arch/arm/mach-mx5/crm_regs.h                 |  583 ++++++++++++++++++
> >  arch/arm/mach-mx5/devices.c                  |   96 +++
> >  arch/arm/mach-mx5/devices.h                  |    4 +
> >  arch/arm/mach-mx5/mm.c                       |   88 +++
> >  arch/arm/plat-mxc/include/mach/common.h      |    1 +
> >  arch/arm/plat-mxc/include/mach/debug-macro.S |    4 +-
> >  arch/arm/plat-mxc/include/mach/iomux-mx51.h  |  340 +++++++++++
> >  arch/arm/plat-mxc/include/mach/mx51.h        |  454 ++++++++++++++
> >  10 files changed, 2461 insertions(+), 2 deletions(-)
> >  create mode 100644 arch/arm/mach-mx5/clock.c
> >  create mode 100644 arch/arm/mach-mx5/cpu.c
> >  create mode 100644 arch/arm/mach-mx5/crm_regs.h
> >  create mode 100644 arch/arm/mach-mx5/devices.c
> >  create mode 100644 arch/arm/mach-mx5/devices.h
> >  create mode 100644 arch/arm/mach-mx5/mm.c
> >  create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx51.h
> >  create mode 100644 arch/arm/plat-mxc/include/mach/mx51.h
> > 
> > diff --git a/arch/arm/mach-mx5/clock.c b/arch/arm/mach-mx5/clock.c
> 
> Can we rename this file to clock-mx51.c? We made this mistake on other
> i.MX platforms and ended with a clock.c and a clock-mx35.c in the same
> directory.

Will fix.

> > new file mode 100644
> > index 0000000..595f966
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/clock.c
> > @@ -0,0 +1,848 @@
> > +/*
> > + * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> > + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> > + *
> > + * The code contained herein is licensed under the GNU General Public
> > + * License. You may obtain a copy of the GNU General Public License
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/mm.h>
> > +#include <linux/delay.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +
> > +#include <asm/clkdev.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +#include <mach/clock.h>
> > +
> > +#include "crm_regs.h"
> > +
> > +static void __iomem *pll_base[] = {
> > +	MX51_DPLL1_BASE,
> > +	MX51_DPLL2_BASE,
> > +	MX51_DPLL3_BASE,
> > +};
> > +
> > +/* External clock values passed-in by the board code */
> > +static unsigned long external_high_reference, external_low_reference;
> > +static unsigned long oscillator_reference, ckih2_reference;
> > +
> > +static struct clk osc_clk;
> > +static struct clk pll1_main_clk;
> > +static struct clk pll1_sw_clk;
> > +static struct clk pll2_sw_clk;
> > +static struct clk pll3_sw_clk;
> > +static struct clk lp_apm_clk;
> > +static struct clk periph_apm_clk;
> > +static struct clk ahb_clk;
> > +static struct clk ipg_clk;
> > +
> > +#define MAX_DPLL_WAIT_TRIES	1000 /* 1000 * udelay(1) = 1ms */
> > +
> > +static int _clk_ccgr_enable(struct clk *clk)
> > +{
> > +	u32 reg;
> > +
> > +	reg = __raw_readl(clk->enable_reg);
> > +	reg |= MXC_CCM_CCGRx_MOD_ON << clk->enable_shift;
> > +	__raw_writel(reg, clk->enable_reg);
> > +
> > +	return 0;
> > +}
> > +
> > +static void _clk_ccgr_disable(struct clk *clk)
> > +{
> > +	u32 reg;
> > +	reg = __raw_readl(clk->enable_reg);
> > +	reg &= ~(MXC_CCM_CCGRx_MOD_OFF << clk->enable_shift);
> > +	__raw_writel(reg, clk->enable_reg);
> > +
> > +}
> > +
> > +static void _clk_ccgr_disable_inwait(struct clk *clk)
> > +{
> > +	u32 reg;
> > +
> > +	reg = __raw_readl(clk->enable_reg);
> > +	reg &= ~(MXC_CCM_CCGRx_CG_MASK << clk->enable_shift);
> > +	reg |= MXC_CCM_CCGRx_MOD_IDLE << clk->enable_shift;
> > +	__raw_writel(reg, clk->enable_reg);
> > +}
> > +
> > +/*
> > + * For the 4-to-1 muxed input clock
> > + */
> > +static inline u32 _get_mux(struct clk *parent, struct clk *m0,
> > +			   struct clk *m1, struct clk *m2, struct clk *m3)
> > +{
> > +	if (parent == m0)
> > +		return 0;
> > +	else if (parent == m1)
> > +		return 1;
> > +	else if (parent == m2)
> > +		return 2;
> > +	else if (parent == m3)
> > +		return 3;
> > +	else
> > +		BUG();
> > +
> > +	return -EINVAL;
> > +}
> > +
> > +static inline void __iomem *_get_pll_base(struct clk *pll)
> > +{
> > +	if (pll == &pll1_main_clk)
> > +		return pll_base[0];
> > +	else if (pll == &pll2_sw_clk)
> > +		return pll_base[1];
> > +	else if (pll == &pll3_sw_clk)
> > +		return pll_base[2];
> > +	else
> 
> I see no purpose for the pll_base[] array. It is used only here and you
> can return the values directly.

Fixed.

> > +		BUG();
> > +
> > +	return NULL;
> > +}
> > +
> > +static unsigned long clk_pll_get_rate(struct clk *clk)
> > +{
> > +	long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
> > +	unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
> > +	void __iomem *pllbase;
> > +	s64 temp;
> > +	unsigned long parent_rate;
> > +
> > +	parent_rate = clk_get_rate(clk->parent);
> > +
> > +	pllbase = _get_pll_base(clk);
> > +
> > +	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> > +	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> > +	dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
> > +
> > +	if (pll_hfsm == 0) {
> > +		dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
> > +		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
> > +		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
> > +	} else {
> > +		dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
> > +		dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
> > +		dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
> > +	}
> > +	pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
> > +	mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
> > +	mfi = (mfi <= 5) ? 5 : mfi;
> > +	mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
> > +	mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
> > +	/* Sign extend to 32-bits */
> > +	if (mfn >= 0x04000000) {
> > +		mfn |= 0xFC000000;
> > +		mfn_abs = -mfn;
> > +	}
> > +
> > +	ref_clk = 2 * parent_rate;
> > +	if (dbl != 0)
> > +		ref_clk *= 2;
> > +
> > +	ref_clk /= (pdf + 1);
> > +	temp = (u64) ref_clk * mfn_abs;
> > +	do_div(temp, mfd + 1);
> > +	if (mfn < 0)
> > +		temp = -temp;
> > +	temp = (ref_clk * mfi) + temp;
> > +
> > +	return temp;
> > +}
> > +
> > +static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
> > +{
> > +	u32 reg;
> > +	void __iomem *pllbase;
> > +
> > +	long mfi, pdf, mfn, mfd = 999999;
> > +	s64 temp64;
> > +	unsigned long quad_parent_rate;
> > +	unsigned long pll_hfsm, dp_ctl;
> > +	unsigned long parent_rate;
> > +
> > +	parent_rate = clk_get_rate(clk->parent);
> > +
> > +	pllbase = _get_pll_base(clk);
> > +
> > +	quad_parent_rate = 4 * parent_rate;
> > +	pdf = mfi = -1;
> > +	while (++pdf < 16 && mfi < 5)
> > +		mfi = rate * (pdf+1) / quad_parent_rate;
> > +	if (mfi > 15)
> > +		return -1;
> > +	pdf--;
> > +
> > +	temp64 = rate * (pdf+1) - quad_parent_rate * mfi;
> > +	do_div(temp64, quad_parent_rate/1000000);
> > +	mfn = (long)temp64;
> > +
> > +	dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
> > +	/* use dpdck0_2 */
> > +	__raw_writel(dp_ctl | 0x1000L, pllbase + MXC_PLL_DP_CTL);
> > +	pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
> > +	if (pll_hfsm == 0) {
> > +		reg = mfi << 4 | pdf;
> > +		__raw_writel(reg, pllbase + MXC_PLL_DP_OP);
> > +		__raw_writel(mfd, pllbase + MXC_PLL_DP_MFD);
> > +		__raw_writel(mfn, pllbase + MXC_PLL_DP_MFN);
> > +	} else {
> > +		reg = mfi << 4 | pdf;
> > +		__raw_writel(reg, pllbase + MXC_PLL_DP_HFS_OP);
> > +		__raw_writel(mfd, pllbase + MXC_PLL_DP_HFS_MFD);
> > +		__raw_writel(mfn, pllbase + MXC_PLL_DP_HFS_MFN);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static int _clk_pll_enable(struct clk *clk)
> > +{
> > +	u32 reg;
> > +	void __iomem *pllbase;
> > +	int i = 0;
> > +
> > +	pllbase = _get_pll_base(clk);
> > +	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
> > +	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> > +
> > +	/* Wait for lock */
> > +	while ((!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF))
> > +		&& i < MAX_DPLL_WAIT_TRIES) {
> > +		i++;
> > +		udelay(1);
> > +	}
> > +
> > +	if (i == MAX_DPLL_WAIT_TRIES) {
> > +		printk(KERN_ERR "MX5: pll locking failed\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static void _clk_pll_disable(struct clk *clk)
> > +{
> > +	u32 reg;
> > +	void __iomem *pllbase;
> > +
> > +	pllbase = _get_pll_base(clk);
> > +	reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
> > +	__raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
> > +}
> > +
> > +static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > +	u32 reg;
> > +
> > +	reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > +	/* When switching from pll_main_clk to a bypass clock, first select a
> > +	   multiplexed clock in 'step_sel', then shift the glitchless mux
> > +	   'pll1_sw_clk_sel'.
> > +	   When switching back, do it in reverse order
> > +	*/
> > +	if (parent == &pll1_main_clk) {
> > +		/* Switch to pll1_main_clk */
> > +		reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> > +		__raw_writel(reg, MXC_CCM_CCSR);
> > +		/* step_clk mux switched to lp_apm, to save power. */
> > +		reg = __raw_readl(MXC_CCM_CCSR);
> > +		reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > +			(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> > +				MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > +	} else {
> > +		if (parent == &lp_apm_clk) {
> > +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > +				(MXC_CCM_CCSR_STEP_SEL_LP_APM <<
> > +					MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > +		} else  if (parent == &pll2_sw_clk) {
> > +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > +				(MXC_CCM_CCSR_STEP_SEL_PLL2_DIVIDED <<
> > +					MXC_CCM_CCSR_STEP_SEL_OFFSET);
> > +		} else  if (parent == &pll3_sw_clk) {
> > +			reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
> > +				(MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
> > +					MXC_CCM_CCSR_STEP_SEL_OFFSET);
> 
> Can we write this as
> 
> 			reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
> 			reg |= MXC_CCM_CCSR_STEP_SEL_PLL3_DIVIDED <<
> 					MXC_CCM_CCSR_STEP_SEL_OFFSET;
> 
> At least for me this is much easier to read. Also, the &= part can be
> outside the if clause.

Fixed per Eric's comments

> > +		} else
> > +			return -EINVAL;
> > +
> > +		__raw_writel(reg, MXC_CCM_CCSR);
> > +		/* Switch to step_clk */
> > +		reg = __raw_readl(MXC_CCM_CCSR);
> > +		reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
> > +	}
> > +	__raw_writel(reg, MXC_CCM_CCSR);
> > +	return 0;
> > +}
> > +
> > +static unsigned long clk_pll1_sw_get_rate(struct clk *clk)
> > +{
> > +	u32 reg, div;
> > +	unsigned long parent_rate;
> > +
> > +	parent_rate = clk_get_rate(clk->parent);
> > +
> > +	div = 1;
> > +	reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > +	if (clk->parent == &pll2_sw_clk) {
> > +		div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
> > +		       MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
> > +	} else if (clk->parent == &pll3_sw_clk) {
> > +		div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
> > +		       MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
> > +	}
> > +	return parent_rate / div;
> 
> This will return parent rate if the parent is not pll2_sw_clk and not
> pll3_sw_clk. Is this intended? If yes, you could write
> 
> 	} else
> 		div = 1;
> 
> to emphasize this is not an accident.

Fixed.

> > +}
> > +
> > +static int _clk_pll2_sw_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > +	u32 reg;
> > +
> > +	reg = __raw_readl(MXC_CCM_CCSR);
> > +
> > +	if (parent == &pll2_sw_clk)
> > +		reg &= ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> > +	else
> > +		reg |= MXC_CCM_CCSR_PLL2_SW_CLK_SEL;
> 
> What's the other clock in the else part? I think there is a check
> missing.

The other clock is the external pll2 bypass clock. And the reference manual
indicates that the bit should only be enabled for testing.

> > +
> > +	__raw_writel(reg, MXC_CCM_CCSR);
> > +	return 0;
> > +}
> > +
> > +static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > +	u32 reg;
> > +
> > +	if (parent == &osc_clk)
> > +		reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
> > +	else
> > +		return -EINVAL;
> > +
> > +	__raw_writel(reg, MXC_CCM_CCSR);
> > +
> > +	return 0;
> > +}
> > +
> > +static unsigned long clk_arm_get_rate(struct clk *clk)
> > +{
> > +	u32 cacrr, div;
> > +	unsigned long parent_rate;
> > +
> > +	parent_rate = clk_get_rate(clk->parent);
> > +	cacrr = __raw_readl(MXC_CCM_CACRR);
> > +	div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
> > +
> > +	return parent_rate / div;
> > +}
> > +
> > +static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > +	u32 reg, mux;
> > +	int i = 0;
> > +
> > +	mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
> > +
> > +	reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
> > +	reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
> > +	__raw_writel(reg, MXC_CCM_CBCMR);
> > +
> > +	/* Wait for lock */
> > +	while ((__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY)
> > +		&& i < MAX_DPLL_WAIT_TRIES) {
> > +		i++;
> > +		udelay(1);
> > +	}
> > +
> > +	if (i == MAX_DPLL_WAIT_TRIES) {
> > +		printk(KERN_ERR "MX5: Set parent for periph_apm clock failed\n");
> > +		return -EINVAL;
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> > +static unsigned long clk_main_bus_get_rate(struct clk *clk)
> > +{
> > +	return clk_get_rate(clk->parent);
> > +}
> 
> The generic code will automatically return the parent rate if the
> get_rate field is set to NULL.

OK. removing...
> > +
> > +static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
> > +{
> > +	u32 reg;
> > +
> > +	reg = __raw_readl(MXC_CCM_CBCDR);
> > +
> > +	if (parent == &pll2_sw_clk)
> > +		reg &= ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> > +	else if (parent == &periph_apm_clk)
> > +		reg |= MXC_CCM_CBCDR_PERIPH_CLK_SEL;
> > +	else
> > +		return -EINVAL;
> > +
> > +	__raw_writel(reg, MXC_CCM_CBCDR);
> > +
> > +	return 0;
> > +}
> > +
> 
> [snip]
> 
> > +
> > +static void clk_tree_init(void)
> > +{
> > +	u32 reg;
> > +
> > +	ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
> 
> Something is wrong here. Here you set the ipg_perclk parent.
> _clk_ipg_per_set_parent will then set the MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL
> and MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL bits accordingly...
> 
> > +
> > +	/*
> > +	 * Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
> > +	 * 8MHz, its derived from lp_apm.
> > +	 * FIXME: Verify if true for all boards
> > +	 */
> > +	reg = __raw_readl(MXC_CCM_CBCDR);
> > +	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
> > +	reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
> > +	reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
> > +	reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
> > +	__raw_writel(reg, MXC_CCM_CBCDR);
> > +
> > +	/* set parent for pll1, pll2 and pll3 */
> > +	pll1_main_clk.parent = &osc_clk;
> > +	pll2_sw_clk.parent = &osc_clk;
> > +	pll3_sw_clk.parent = &osc_clk;
> > +
> > +	/* set ipg_perclk parent */
> > +	ipg_perclk.parent = &lp_apm_clk;
> > +	reg = __raw_readl(MXC_CCM_CBCMR);
> > +	if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
> > +		ipg_perclk.parent = &ipg_clk;
> > +	} else {
> > +		if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
> > +			ipg_perclk.parent = &main_bus_clk;
> > +	}
> 
> ...And here you set the parent according to the register bits. What's
> the intention here? Do you want to keep the bootloader settings or
> do you want to overwrite them with a known value?

It does look pointless. Infact, since MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL is
set because of the call on the top, this entire if statement does nothing
new.

> > +}
> > +
> > +int __init mx51_clocks_init(unsigned long ckil, unsigned long osc,
> > +			unsigned long ckih1, unsigned long ckih2)
> > +{
> > +	int i;
> > +
> > +	external_low_reference = ckil;
> > +	external_high_reference = ckih1;
> > +	ckih2_reference = ckih2;
> > +	oscillator_reference = osc;
> > +
> > +	for (i = 0; i < ARRAY_SIZE(lookups); i++)
> > +		clkdev_add(&lookups[i]);
> > +
> > +	clk_tree_init();
> > +
> > +	clk_enable(&cpu_clk);
> > +	clk_enable(&main_bus_clk);
> > +
> > +	/* System timer */
> > +	mxc_timer_init(&gpt_clk, MX51_IO_ADDRESS(MX51_GPT1_BASE_ADDR),
> > +		MX51_MXC_INT_GPT);
> > +	return 0;
> > +}
> > diff --git a/arch/arm/mach-mx5/cpu.c b/arch/arm/mach-mx5/cpu.c
> > new file mode 100644
> > index 0000000..93f1d5a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/cpu.c
> > @@ -0,0 +1,45 @@
> > +/*
> > + * Copyright 2008-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + *
> > + * This file contains the CPU initialization code.
> > + */
> > +
> > +#include <linux/types.h>
> > +#include <linux/kernel.h>
> > +#include <linux/init.h>
> > +#include <mach/hardware.h>
> > +#include <asm/io.h>
> > +
> > +static int __init post_cpu_init(void)
> > +{
> > +	unsigned int reg;
> > +	void __iomem *base;
> > +
> > +	if (cpu_is_mx51()) {
> 
> 	if (!cpu_is_mx51())
> 		return 0;
> 
> please. This way we have one indention level more in case this function
> gets more complicated.
> 

Neat. Fixed.

> > +		base = MX51_IO_ADDRESS(MX51_AIPS1_BASE_ADDR);
> > +		__raw_writel(0x0, base + 0x40);
> > +		__raw_writel(0x0, base + 0x44);
> > +		__raw_writel(0x0, base + 0x48);
> > +		__raw_writel(0x0, base + 0x4C);
> > +		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> > +		__raw_writel(reg, base + 0x50);
> > +
> > +		base = MX51_IO_ADDRESS(MX51_AIPS2_BASE_ADDR);
> > +		__raw_writel(0x0, base + 0x40);
> > +		__raw_writel(0x0, base + 0x44);
> > +		__raw_writel(0x0, base + 0x48);
> > +		__raw_writel(0x0, base + 0x4C);
> > +		reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
> > +		__raw_writel(reg, base + 0x50);
> > +	}
> > +	return 0;
> > +}
> > +
> > +postcore_initcall(post_cpu_init);
> > diff --git a/arch/arm/mach-mx5/crm_regs.h b/arch/arm/mach-mx5/crm_regs.h
> > new file mode 100644
> > index 0000000..c776b9a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/crm_regs.h
> 
> [snip]
> 
> > diff --git a/arch/arm/mach-mx5/devices.c b/arch/arm/mach-mx5/devices.c
> > new file mode 100644
> > index 0000000..55eb089
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/devices.c
> > @@ -0,0 +1,96 @@
> > +/*
> > + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com>
> > + *
> > + * The code contained herein is licensed under the GNU General Public
> > + * License. You may obtain a copy of the GNU General Public License
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/platform_device.h>
> > +#include <mach/hardware.h>
> > +#include <mach/imx-uart.h>
> > +
> > +static struct resource uart0[] = {
> > +	{
> > +		.start = MX51_UART1_BASE_ADDR,
> > +		.end = MX51_UART1_BASE_ADDR + 0x0B5,
> 
> You can safely write MX51_UART1_BASE_ADDR + 0xfff here because that's
> the register space this device actually has. The last register in the
> datasheet is 0xb4 anyway and with 32bit register accesses the correct
> value here would be 0xb7.

Oops. Fixed.

> > +		.flags = IORESOURCE_MEM,
> > +	}, {
> > +		.start = MX51_MXC_INT_UART1,
> > +		.end = MX51_MXC_INT_UART1,
> > +		.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 = MX51_UART2_BASE_ADDR,
> > +		.end = MX51_UART2_BASE_ADDR + 0x0B5,
> > +		.flags = IORESOURCE_MEM,
> > +	}, {
> > +		.start = MX51_MXC_INT_UART2,
> > +		.end = MX51_MXC_INT_UART2,
> > +		.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 = MX51_UART3_BASE_ADDR,
> > +		.end = MX51_UART3_BASE_ADDR + 0x0B5,
> > +		.flags = IORESOURCE_MEM,
> > +	}, {
> > +		.start = MX51_MXC_INT_UART3,
> > +		.end = MX51_MXC_INT_UART3,
> > +		.flags = IORESOURCE_IRQ,
> > +	},
> > +};
> > +
> > +struct platform_device mxc_uart_device2 = {
> > +	.name = "imx-uart",
> > +	.id = 2,
> > +	.resource = uart2,
> > +	.num_resources = ARRAY_SIZE(uart2),
> > +};
> > +
> > +static struct resource mxc_fec_resources[] = {
> > +	{
> > +		.start	= MX51_MXC_FEC_BASE_ADDR,
> > +		.end	= MX51_MXC_FEC_BASE_ADDR + 0xfff,
> > +		.flags	= IORESOURCE_MEM,
> > +	}, {
> > +		.start	= MX51_MXC_INT_FEC,
> > +		.end	= MX51_MXC_INT_FEC,
> > +		.flags	= IORESOURCE_IRQ,
> > +	},
> > +};
> > +
> > +struct platform_device mxc_fec_device = {
> > +	.name = "fec",
> > +	.id = 0,
> > +	.num_resources = ARRAY_SIZE(mxc_fec_resources),
> > +	.resource = mxc_fec_resources,
> > +};
> > +
> > +/* Dummy definition to allow compiling in AVIC and TZIC simultaneously */
> > +int __init mxc_register_gpios(void)
> > +{
> > +	return 0;
> > +}
> > diff --git a/arch/arm/mach-mx5/devices.h b/arch/arm/mach-mx5/devices.h
> > new file mode 100644
> > index 0000000..f339ab8
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/devices.h
> > @@ -0,0 +1,4 @@
> > +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;
> > diff --git a/arch/arm/mach-mx5/mm.c b/arch/arm/mach-mx5/mm.c
> > new file mode 100644
> > index 0000000..d66c31a
> > --- /dev/null
> > +++ b/arch/arm/mach-mx5/mm.c
> > @@ -0,0 +1,88 @@
> > +/*
> > + * Copyright 2008-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + *
> > + * Create static mapping between physical to virtual memory.
> > + */
> > +
> > +#include <linux/mm.h>
> > +#include <linux/init.h>
> > +
> > +#include <asm/mach/map.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +#include <mach/iomux-v3.h>
> > +
> > +/*
> > + * Define the MX51 memory map.
> > + */
> > +static struct map_desc mxc_io_desc[] __initdata = {
> > +	{
> > +	 .virtual = MX51_IRAM_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_IRAM_BASE_ADDR),
> > +	 .length = MX51_IRAM_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_DEBUG_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_DEBUG_BASE_ADDR),
> > +	 .length = MX51_DEBUG_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_TZIC_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_TZIC_BASE_ADDR),
> > +	 .length = MX51_TZIC_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_AIPS1_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_AIPS1_BASE_ADDR),
> > +	 .length = MX51_AIPS1_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_SPBA0_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_SPBA0_BASE_ADDR),
> > +	 .length = MX51_SPBA0_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_AIPS2_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_AIPS2_BASE_ADDR),
> > +	 .length = MX51_AIPS2_SIZE,
> > +	 .type = MT_DEVICE},
> > +	{
> > +	 .virtual = MX51_NFC_AXI_BASE_ADDR_VIRT,
> > +	 .pfn = __phys_to_pfn(MX51_NFC_AXI_BASE_ADDR),
> > +	 .length = MX51_NFC_AXI_SIZE,
> > +	 .type = MT_DEVICE},
> > +};
> > +
> > +/*
> > + * 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 mx51_map_io(void)
> > +{
> > +	u32 tzic_addr;
> > +
> > +	if (mx51_revision() < MX51_CHIP_REV_2_0)
> > +		tzic_addr = 0x8FFFC000;
> > +	else
> > +		tzic_addr = 0xE0003000;
> > +	mxc_io_desc[2].pfn =  __phys_to_pfn(tzic_addr);
> > +
> > +	mxc_set_cpu_type(MXC_CPU_MX51);
> > +	mxc_iomux_v3_init(MX51_IO_ADDRESS(MX51_IOMUXC_BASE_ADDR));
> > +	mxc_arch_reset_init(MX51_IO_ADDRESS(MX51_WDOG_BASE_ADDR));
> > +	iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
> > +}
> > +
> > +void __init mx51_init_irq(void)
> > +{
> > +	tzic_init_irq(MX51_IO_ADDRESS(MX51_TZIC_BASE_ADDR));
> > +}
> > diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> > index 5250a3f..0a25576 100644
> > --- a/arch/arm/plat-mxc/include/mach/common.h
> > +++ b/arch/arm/plat-mxc/include/mach/common.h
> > @@ -30,6 +30,7 @@ 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 mx51_init_irq(void);
> >  extern void mxc91231_init_irq(void);
> >  extern void mxc_timer_init(struct clk *timer_clk, void __iomem *, int);
> >  extern int mx1_clocks_init(unsigned long fref);
> > diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > index 9fe7300..9d41bfd 100644
> > --- a/arch/arm/plat-mxc/include/mach/debug-macro.S
> > +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S
> > @@ -49,8 +49,8 @@
> >  #error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> >  #endif
> >  #include <mach/mx51.h>
> > -#define UART_PADDR	UART1_BASE_ADDR
> > -#define UART_VADDR	AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
> > +#define UART_PADDR	MX51_UART1_BASE_ADDR
> > +#define UART_VADDR	MX51_AIPS1_IO_ADDRESS(MX51_UART1_BASE_ADDR)
> >  #endif
> >  
> >  #ifdef CONFIG_ARCH_MXC91231
> > diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx51.h b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> > new file mode 100644
> > index 0000000..14df0f5
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/include/mach/iomux-mx51.h
> > @@ -0,0 +1,340 @@
> > +/*
> > + * Copyright 2009 Amit Kucheria <amit.kucheria@canonical.com> 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#ifndef __MACH_IOMUX_MX51_H__
> > +#define __MACH_IOMUX_MX51_H__
> > +
> > +#include <mach/iomux-v3.h>
> > +
> > +/*
> > + * various IOMUX alternate output functions (1-7)
> > + */
> > +typedef enum iomux_config {
> > +	IOMUX_CONFIG_ALT0,
> > +	IOMUX_CONFIG_ALT1,
> > +	IOMUX_CONFIG_ALT2,
> > +	IOMUX_CONFIG_ALT3,
> > +	IOMUX_CONFIG_ALT4,
> > +	IOMUX_CONFIG_ALT5,
> > +	IOMUX_CONFIG_ALT6,
> > +	IOMUX_CONFIG_ALT7,
> > +	IOMUX_CONFIG_GPIO,	/* added to help user use GPIO mode */
> > +	IOMUX_CONFIG_SION = 0x1 << 4,	/* LOOPBACK:MUX SION bit */
> > +} iomux_pin_cfg_t;
> > +
> > +/* Pad control groupings */
> > +#define MX51_UART1_PAD_CTRL	(PAD_CTL_HYS | PAD_CTL_PKE | PAD_CTL_PUE | \
> > +				PAD_CTL_DSE_HIGH)
> > +#define MX51_UART2_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_DSE_HIGH | \
> > +				PAD_CTL_SRE_FAST)
> > +#define MX51_UART3_PAD_CTRL	(PAD_CTL_PKE | PAD_CTL_DSE_HIGH | \
> > +				PAD_CTL_SRE_FAST)
> > +
> > +/*
> > + * The naming convention for the pad modes is MX51_PAD_<padname>__<padmode>
> > + * If <padname> or <padmode> refers to a GPIO, it is named
> > + * GPIO_<unit>_<num> see also iomux-v3.h
> > + */
> > +
> > +/* REVISIT: This was converted using scripts from existing Freescale code to
> > + * this form used upstream. Need to verify the name format.
> > + */
> > +
> > +/*						PAD      MUX   ALT INPSE PATH PADCTRL */
> > +
> > +
> > +/* UART1 */
> > +#define MX51_BABBAGE_PAD_UART1_RXD__UART1_RXD	\
> > +	IOMUX_PAD(0x618, 0x228,	IOMUX_CONFIG_ALT0, 0x9e4, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
> > +#define MX51_BABBAGE_PAD_UART1_TXD__UART1_TXD	\
> > +	IOMUX_PAD(0x61C, 0x22C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL | PAD_CTL_SRE_FAST)
> > +#define MX51_BABBAGE_PAD_UART1_RTS__UART1_RTS	\
> > +	IOMUX_PAD(0x620, 0x230, IOMUX_CONFIG_ALT0, 0x9e0, 0, MX51_UART1_PAD_CTRL)
> > +#define MX51_BABBAGE_PAD_UART1_CTS__UART1_CTS	\
> > +	IOMUX_PAD(0x624, 0x234, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART1_PAD_CTRL)
> 
> I remember last time I said that you should move these macros here. I
> think the situation is like this:
> 
> 1) These are either known good values for the uart pins and therefore
>    shouldn't have BABBAGE in their name.
> 2) There is something babbage specific in them, in this case they should
>    be in the board specific file.
> 
> I vote for 1) here.

At the moment, I only have a babbage for testing. So I don't know if these
are globally good values. But I'll change 'em since that is the only board we
support for now.

> > +
> > +/* UART2 */
> > +#define MX51_BABBAGE_PAD_UART2_RXD__UART2_RXD	IOMUX_PAD(0x628, 0x238, IOMUX_CONFIG_ALT0, 0x9ec, 2, MX51_UART2_PAD_CTRL)
> > +#define MX51_BABBAGE_PAD_UART2_TXD__UART2_TXD	IOMUX_PAD(0x62C, 0x23C, IOMUX_CONFIG_ALT0, 0x0, 0, MX51_UART2_PAD_CTRL)
> > +
> > +/* UART3 */
> > +#define MX51_BABBAGE_PAD_EIM_D25__UART3_RXD	IOMUX_PAD(0x414, 0x080, IOMUX_CONFIG_ALT3, 0x9f4, 0, MX51_UART3_PAD_CTRL)
> > +#define MX51_BABBAGE_PAD_EIM_D26__UART3_TXD	IOMUX_PAD(0x418, 0x084, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
> > +#define MX51_BABBAGE_PAD_EIM_D27__UART3_RTS	IOMUX_PAD(0x41c, 0x088, IOMUX_CONFIG_ALT3, 0x9f0, 0, MX51_UART3_PAD_CTRL)
> > +#define MX51_BABBAGE_PAD_EIM_D24__UART3_CTS	IOMUX_PAD(0x410, 0x07c, IOMUX_CONFIG_ALT3, 0x0, 0, MX51_UART3_PAD_CTRL)
> > +
> > +#define MX51_BABBAGE_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))
> > +
> 
> ditto
> 
>  Sascha
> 
> -- 
> Pengutronix e.K.                           |                             |
> Industrial Linux Solutions                 | http://www.pengutronix.de/  |
> Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
> Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Thanks for the review. An updated patchset coming up.

Regards,
Amit
-- 
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria at canonical.com
----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 08/11] fec: fix uninitialized rx buffer usage
  2010-02-03 18:38                       ` Grant Likely
@ 2010-02-03 20:23                         ` Grant Likely
  0 siblings, 0 replies; 40+ messages in thread
From: Grant Likely @ 2010-02-03 20:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Feb 3, 2010 at 11:38 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
> On Wed, Feb 3, 2010 at 11:33 AM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
>> On Wed, Feb 3, 2010 at 8:46 AM, Grant Likely <grant.likely@secretlab.ca> wrote:
>>>
>>> fec related patches 8 & 9 look okay to me.
>>>
>>> g.
>>
>> Can I take that as an Acked-by?
>
> of course.

BTW, since these 2 patches are essentially independent, you may find
it easier to get all the patches merged if you post the FEC changes in
a separate patch series.

g.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller
  2010-02-03 16:27         ` Grant Likely
@ 2010-02-04  0:25           ` Amit Kucheria
  0 siblings, 0 replies; 40+ messages in thread
From: Amit Kucheria @ 2010-02-04  0:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 10 Feb 03, Grant Likely wrote:
> On Tue, Feb 2, 2010 at 10:16 PM, Amit Kucheria
> <amit.kucheria@canonical.com> wrote:
> > i.MX51 defines 4 values:
> >
> > 00: Low Drive Strength
> > 01: Medium Drive Strength
> > 10: High Drive Strength
> > 11: Max Drive Strength
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/plat-mxc/include/mach/iomux-v3.h | ? ?8 +++++---
> > ?1 files changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/arch/arm/plat-mxc/include/mach/iomux-v3.h b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > index 1deda01..f2f73d3 100644
> > --- a/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > +++ b/arch/arm/plat-mxc/include/mach/iomux-v3.h
> > @@ -81,11 +81,13 @@ struct pad_desc {
> >
> > ?#define PAD_CTL_ODE ? ? ? ? ? ? ? ? ? ?(1 << 3)
> >
> > -#define PAD_CTL_DSE_STANDARD ? ? ? ? ? (0 << 1)
> > -#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (1 << 1)
> > -#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(2 << 1)
> > +#define PAD_CTL_DSE_LOW ? ? ? ? ? ? ? ? ? ? ? ?(0 << 1)
> > +#define PAD_CTL_DSE_MED ? ? ? ? ? ? ? ? ? ? ? ?(1 << 1)
> > +#define PAD_CTL_DSE_HIGH ? ? ? ? ? ? ? (2 << 1)
> > +#define PAD_CTL_DSE_MAX ? ? ? ? ? ? ? ? ? ? ? ?(3 << 1)
> >
> > ?#define PAD_CTL_SRE_FAST ? ? ? ? ? ? ? (1 << 0)
> > +#define PAD_CTL_SRE_SLOW ? ? ? ? ? ? ? (0 << 0)
> 
> Shouldn't the addition/change of #defines be done in patches that
> actually use them?

I'll merge it into patch 5 that adds the core support for i.MX5. I kept it
separate because the #defines are a (standalone) property of the IOMUX
controller regardless of whether they are used by i.MX5 or not.

Thanks for all the reviews.

/Amit

-- 
-------------------------------------------------------------------------
Amit Kucheria,				 Kernel Developer, Verdurent
-------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03 15:09         ` Eric Miao
@ 2010-02-04  0:54           ` Eric Miao
  0 siblings, 0 replies; 40+ messages in thread
From: Eric Miao @ 2010-02-04  0:54 UTC (permalink / raw)
  To: linux-arm-kernel

> >> > +config MXC_TZIC
> >> > + ? ? ? bool "Enable TrustZone Interrupt Controller"
> >> > + ? ? ? depends on ARCH_MX51
> >>
> >> This is the first patch of the base port, yet I cannot find any reference to
> >> this ARCH_MX51, did you miss something?
> >
> > ARCH_MX51 is only introduced in the later patches that add the core i.MX5
> > code. Since TZIC is not inherently dependent on i.MX5 (it's merely the first
> > processor to use it), I thought of splitting it out as a separate patch.
> >
> > Does this break the sanctity of one self-contained change?
> >
>
> This breaks git-bisect, we may want a buildable kernel every commit if possible.
>

Hmm... you may safely ignore this, it's not going to break the build
since it won't be selected without ARCH_MX51 being defined.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family
  2010-02-03 13:24       ` Amit Kucheria
  2010-02-03 15:09         ` Eric Miao
@ 2010-02-04 17:09         ` Nguyen Dinh-R00091
  1 sibling, 0 replies; 40+ messages in thread
From: Nguyen Dinh-R00091 @ 2010-02-04 17:09 UTC (permalink / raw)
  To: linux-arm-kernel

 

-----Original Message-----
From: Amit Kucheria [mailto:amit.kucheria at canonical.com] 
Sent: Wednesday, February 03, 2010 7:24 AM
To: Eric Miao
Cc: List Linux Kernel; linux at arm.linux.org.uk; Nguyen Dinh-R00091; s.hauer at pengutronix.de; grant.likely at secretlab.ca; Herring Robert-RA7055; linux-arm-kernel at lists.infradead.org; daniel at caiaq.de; bryan.wu at canonical.com; valentin.longchamp at epfl.ch
Subject: Re: [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family

On 10 Feb 02, Eric Miao wrote:
> Hi Amit,
> 
> Just some nit-picking review comments, see below:
> 
> On Tue, Feb 2, 2010 at 9:16 PM, Amit Kucheria 
> <amit.kucheria@canonical.com> wrote:
> > Freescale i.MX51 processor uses a new interrupt controller. Add 
> > driver for TrustZone Interrupt Controller
> >
> > Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> > ---
> > ?arch/arm/plat-mxc/Kconfig ?| ? ?8 ++
> > ?arch/arm/plat-mxc/Makefile | ? ?3 +
> > ?arch/arm/plat-mxc/tzic.c ? | ?182 
> > ++++++++++++++++++++++++++++++++++++++++++++
> > ?3 files changed, 193 insertions(+), 0 deletions(-)
> > ?create mode 100644 arch/arm/plat-mxc/tzic.c
> >
> > diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig 
> > index 8b0a1ee..59558c4 100644
> > --- a/arch/arm/plat-mxc/Kconfig
> > +++ b/arch/arm/plat-mxc/Kconfig
> > @@ -62,6 +62,14 @@ config MXC_IRQ_PRIOR
> > ? ? ? ? ?requirements for timing.
> > ? ? ? ? ?Say N here, unless you have a specialized requirement.
> >
> > +config MXC_TZIC
> > + ? ? ? bool "Enable TrustZone Interrupt Controller"
> > + ? ? ? depends on ARCH_MX51
> 
> This is the first patch of the base port, yet I cannot find any 
> reference to this ARCH_MX51, did you miss something?

ARCH_MX51 is only introduced in the later patches that add the core i.MX5 code. Since TZIC is not inherently dependent on i.MX5 (it's merely the first processor to use it), I thought of splitting it out as a separate patch.

Does this break the sanctity of one self-contained change?

> > + ? ? ? help
> > + ? ? ? ? This will be automatically selected for all processors
> > + ? ? ? ? containing this interrupt controller.
> > + ? ? ? ? Say N here only if you are really sure.
> > +
> > ?config MXC_PWM
> > ? ? ? ?tristate "Enable PWM driver"
> > ? ? ? ?depends on ARCH_MXC
> > diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile 
> > index 996cbac..0202ad9 100644
> > --- a/arch/arm/plat-mxc/Makefile
> > +++ b/arch/arm/plat-mxc/Makefile
> > @@ -5,6 +5,9 @@
> > ?# Common support
> > ?obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o
> >
> > +# MX51 uses the TZIC interrupt controller, older platforms use AVIC 
> > +(irq.o)
> > +obj-$(CONFIG_MXC_TZIC) += tzic.o
> > +
> > ?obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
> > ?obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o diff --git 
> > a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c new file mode 
> > 100644 index 0000000..00cb0ad
> > --- /dev/null
> > +++ b/arch/arm/plat-mxc/tzic.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + * Copyright 2004-2009 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
> > + * Version 2 or later at the following locations:
> > + *
> > + * http://www.opensource.org/licenses/gpl-license.html
> > + * http://www.gnu.org/copyleft/gpl.html
> > + */
> > +
> > +#include <linux/module.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/init.h>
> > +#include <linux/device.h>
> > +#include <linux/errno.h>
> > +#include <linux/io.h>
> > +
> > +#include <asm/mach/irq.h>
> > +
> > +#include <mach/hardware.h>
> > +
> > +/*
> > + *****************************************
> > + * TZIC Registers ? ? ? ? ? ? ? ? ? ? ? ?*
> > + *****************************************
> > + */
> > +
> > +#define TZIC_INTCNTL ? ? ? ? ? ?0x0000 /* Control register */ 
> > +#define TZIC_INTTYPE ? ? ? ? ? ?0x0004 /* Controller Type register 
> > +*/ #define TZIC_IMPID ? ? ? ? ? ? ?0x0008 /* Distributor 
> > +Implementer Identification */ #define TZIC_PRIOMASK ? ? ? ? ? 
> > +0x000C /* Priority Mask Reg */ #define TZIC_SYNCCTRL ? ? ? ? ? 
> > +0x0010 /* Synchronizer Control register */ #define TZIC_DSMINT ? ? ? ? ? ? 
> > +0x0014 /* DSM interrupt Holdoffregister */ #define TZIC_INTSEC0 ? ? ? ? ? ?
> > +0x0080 /* Interrupt Security register 0 */ #define TZIC_ENSET0 ? ? ? ? ? ? 
> > +0x0100 /* Enable Set Register 0 */ #define TZIC_ENCLEAR0 ? ? ? ? ? 
> > +0x0180 /* Enable Clear Register 0 */ #define TZIC_SRCSET0 ? ? ? ? ? ?
> > +0x0200 /* Source Set Register 0 */ #define TZIC_SRCCLAR0 ? ? ? ? ? 
> > +0x0280 /* Source Clear Register 0 */ #define TZIC_PRIORITY0 ? ? ? ? ?
> > +0x0400 /* Priority Register 0 */ #define TZIC_PND0 ? ? ? ? ? ? ? 
> > +0x0D00 /* Pending Register 0 */ #define TZIC_HIPND0 ? ? ? ? ? ? 
> > +0x0D80 /* High Priority Pending Register */ #define TZIC_WAKEUP0 ? ? ? ? ? ?
> > +0x0E00 /* Wakeup Config Register */ #define TZIC_SWINT ? ? ? ? ? ? ?
> > +0x0F00 /* Software Interrupt Rigger Register */ #define TZIC_ID0 ? ? ? ? ? ? ? ?
> > +0x0FD0 /* Indentification Register 0 */
> > +
> > +void __iomem *tzic_base;
> 
> This can just be made to 'static' if it's not used elsewhere, and I'm 
> wondering if it's neater to define them as:
> 
> #define TZIC_INTCNTL		(tzic_base + 0x0000)
> 
> so to make the code below short and handy.

tzic_base is actually used in entry-macro.S in patch 0004. I've tried to follow AVIC's way of doing things.

> > +
> > +/*
> > + * Disable interrupt number "irq" in the TZIC
> 
> I don't think this follows kernel API doc exactly, you may want to 
> have a look into Documentation/kernel-doc-nano-HOWTO.txt.

OK.

> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number  */ static void 
> > +tzic_mask_irq(unsigned int irq) {
> > + ? ? ? int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENCLEAR0 + (index << 
> > + 2));
> 
> I'll normally define TZIC_ENCLEAR0 then as:
> 
> #define TZIC_ENCLEAR(i)		(0x0180 + ((i) << 2))
> 
> so the above can be written as:
> 
> 	__raw_writel(1 << off, tzic_base + TZIC_ENCLEAR(index));
> 
> or by including tzic_base into TZIC_*, simply as:
> 
> 	__raw_writel(1 << off, TZIC_ENCLEAR(index));

OK.

> > +}
> > +
> > +/*
> > + * Enable interrupt number "irq" in the TZIC
> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number  */ static void 
> > +tzic_unmask_irq(unsigned int irq) {
> > + ? ? ? int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > + ? ? ? __raw_writel(1 << off, tzic_base + TZIC_ENSET0 + (index << 
> > +2)); }
> > +
> > +static unsigned int wakeup_intr[4];
> > +
> > +/*
> > + * Set interrupt number "irq" in the TZIC as a wake-up source.
> > + *
> > + * @param ?irq ? ? ? ? ?interrupt source number
> > + * @param ?enable ? ? ? enable as wake-up if equal to non-zero
> > + * ? ? ? ? ? ? ? ? ? ? disble as wake-up if equal to zero
> > + *
> > + * @return ? ? ? This function returns 0 on success.
> > + */
> > +static int tzic_set_wake_irq(unsigned int irq, unsigned int enable) 
> > +{
> > + ? ? ? unsigned int index, off;
> > +
> > + ? ? ? index = irq >> 5;
> > + ? ? ? off = irq & 0x1F;
> > +
> > + ? ? ? if (index > 3)
> > + ? ? ? ? ? ? ? return -EINVAL;
> > +
> > + ? ? ? if (enable)
> > + ? ? ? ? ? ? ? wakeup_intr[index] |= (1 << off);
> > + ? ? ? else
> > + ? ? ? ? ? ? ? wakeup_intr[index] &= ~(1 << off);
> > +
> > + ? ? ? return 0;
> > +}
> > +
> > +static struct irq_chip mxc_tzic_chip = {
> > + ? ? ? .name = "MXC_TZIC",
> > + ? ? ? .ack = tzic_mask_irq,
> > + ? ? ? .mask = tzic_mask_irq,
> > + ? ? ? .unmask = tzic_unmask_irq,
> > + ? ? ? .set_wake = tzic_set_wake_irq, };
> > +
> > +/*
> > + * This function initializes the TZIC hardware and disables all the
> > + * interrupts. It registers the interrupt enable and disable 
> > +functions
> > + * to the kernel for each interrupt source.
> > + */
> > +void __init tzic_init_irq(void __iomem *irqbase) {
> > + ? ? ? int i;
> > +
> > + ? ? ? tzic_base = irqbase;
> > + ? ? ? /* put the TZIC into the reset value with
> > + ? ? ? ?* all interrupts disabled
> > + ? ? ? ?*/
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);
> 
> Mixing the use of 'i' as both a signed counter and register value 
> might not be a good idea, provided it's not guaranteed from theory 
> that 'i' as an integer could not be sufficient to hold the value 
> returned from
> __raw_readl()

Fair enough.

> > +
> > + ? ? ? __raw_writel(0x80010001, tzic_base + TZIC_INTCNTL);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_INTCNTL);
> > + ? ? ? __raw_writel(0x1f, tzic_base + TZIC_PRIOMASK);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_PRIOMASK);
> > + ? ? ? __raw_writel(0x02, tzic_base + TZIC_SYNCCTRL);
> > + ? ? ? i = __raw_readl(tzic_base + TZIC_SYNCCTRL);
> 
> Are these read-back really necessary? We can start without them and 
> add them later if they do cause issues.

Can anybody from Freescale comment whether the read-back is necessary?

I'll remove it for now to see what happens in my testing.

[Dinh] - This piece of code was taken from our silicon validation code where it was check the values of the read-backs. The read-backs can be removed.

> > +
> > + ? ? ? for (i = 0; i < 4; i++)
> > + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_INTSEC0 + 
> > + i * 4);
> > +
> > + ? ? ? /* disable all interrupts */
> > + ? ? ? for (i = 0; i < 4; i++)
> > + ? ? ? ? ? ? ? __raw_writel(0xFFFFFFFF, tzic_base + TZIC_ENCLEAR0 + 
> > + i * 4);
> > +
> > + ? ? ? /* all IRQ no FIQ Warning :: No selection */
> > +
> > + ? ? ? for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
> > + ? ? ? ? ? ? ? set_irq_chip(i, &mxc_tzic_chip);
> > + ? ? ? ? ? ? ? set_irq_handler(i, handle_level_irq);
> > + ? ? ? ? ? ? ? set_irq_flags(i, IRQF_VALID);
> > + ? ? ? }
> > +
> > + ? ? ? printk(KERN_INFO "TrustZone Interrupt Controller (TZIC) 
> > + initialized\n");
> 
> You may want to use pr_info() for short.

OK

> > +}
> > +
> > +/*
> > + * enable wakeup interrupt
> > + *
> > + * @param is_idle ? ? ? ? ? ? ?1 if called in idle loop (ENSET 
> > +register);
> > + * ? ? ? ? ? ? ? ? ? ? ? ? ? ? 0 to be used when called from low 
> > +power entry
> > + * @return ? ? ? ? ? ? ? ? ? ? 0 if successful; non-zero otherwise
> > + *
> > + */
> > +int tzic_enable_wake(int is_idle)
> > +{
> > + ? ? ? unsigned int i, v;
> > +
> > + ? ? ? __raw_writel(1, tzic_base + TZIC_DSMINT);
> > + ? ? ? if (unlikely(__raw_readl(tzic_base + TZIC_DSMINT) == 0))
> > + ? ? ? ? ? ? ? return -EAGAIN;
> 
> Looks like an unnecessary read-back provided the silicon is sane enough.

Again, Dinh/Rob can you comment?

[Dinh] - Can be removed.

> > +
> > + ? ? ? if (likely(is_idle)) {
> > + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> > + ? ? ? ? ? ? ? ? ? ? ? v = __raw_readl(tzic_base + TZIC_ENSET0 + i 
> > + * 4);
> > + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i 
> > + * 4);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? } else {
> > + ? ? ? ? ? ? ? for (i = 0; i < 4; i++) {
> > + ? ? ? ? ? ? ? ? ? ? ? v = wakeup_intr[i];
> > + ? ? ? ? ? ? ? ? ? ? ? __raw_writel(v, tzic_base + TZIC_WAKEUP0 + i 
> > + * 4);
> > + ? ? ? ? ? ? ? }
> > + ? ? ? }
> 
> Or could be simplified to:
> 
> 	for (i = 0; i < 4; i++) {
> 		v = is_idle ? __raw_readl(TZIC_ENSET(i)) : wakeup_intr[i];
> 		__raw_writel(v, TZIC_WAKEUP(i));
> 	}

OK

> but just nit-picking comments, so it's up to you.
> 
> > + ? ? ? return 0;
> > +}
> 
> Mmmm.... this being called elsewhere, I'm thinking about making this a 
> sys_device and having this called within sysdev_class.suspend() to 
> make this file rather self-contained.

That is the idea once the base port is upstream.

Thanks for the review.

/Amit
--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit.kucheria at canonical.com
----------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCHv2 11/11] mxc: Add imx51_defconfig
  2010-02-03  5:16                       ` [PATCHv2 11/11] mxc: Add imx51_defconfig Amit Kucheria
@ 2010-02-05  6:48                         ` Sascha Hauer
  0 siblings, 0 replies; 40+ messages in thread
From: Sascha Hauer @ 2010-02-05  6:48 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Amit,

On Tue, Feb 02, 2010 at 09:16:33PM -0800, Amit Kucheria wrote:
> This config is used to test the base support for i.MX51 processors on the
> Babbage board
> 
> Signed-off-by: Amit Kucheria <amit.kucheria@canonical.com>
> ---
>  arch/arm/configs/imx51_defconfig | 1286 ++++++++++++++++++++++++++++++++++++++
>  1 files changed, 1286 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/configs/imx51_defconfig

Can you rename this to mx51_defconfig? All other i.MX defconfigs begin
with mx.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2010-02-05  6:48 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <cover.1265173480.git.amit.kucheria@canonical.com>
2010-02-03  5:16 ` [PATCHv2 00/11] Base support for Freescale i.MX51 SoC platform Amit Kucheria
2010-02-03  5:16   ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Amit Kucheria
2010-02-03  5:16     ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Amit Kucheria
2010-02-03  5:16       ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Amit Kucheria
2010-02-03  5:16         ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Amit Kucheria
2010-02-03  5:16           ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Amit Kucheria
2010-02-03  5:16             ` [PATCHv2 06/11] mxc: enable support for Freescale i.MX5 series of processors Amit Kucheria
2010-02-03  5:16               ` [PATCHv2 07/11] mxc: Add support for the Babbage board Amit Kucheria
2010-02-03  5:16                 ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Amit Kucheria
2010-02-03  5:16                   ` [PATCHv2 09/11] fec: Add LAN8700 phy support Amit Kucheria
2010-02-03  5:16                     ` [PATCHv2 10/11] fec: Add ARCH_MX5 as a dependency Amit Kucheria
2010-02-03  5:16                       ` [PATCHv2 11/11] mxc: Add imx51_defconfig Amit Kucheria
2010-02-05  6:48                         ` Sascha Hauer
2010-02-03 16:46                   ` [PATCHv2 08/11] fec: fix uninitialized rx buffer usage Grant Likely
2010-02-03 18:33                     ` Amit Kucheria
2010-02-03 18:38                       ` Grant Likely
2010-02-03 20:23                         ` Grant Likely
2010-02-03 11:10                 ` [PATCHv2 07/11] mxc: Add support for the Babbage board Sascha Hauer
2010-02-03  7:03             ` [PATCHv2 05/11] mxc: Core support for i.MX5 series of processors from Freescale Eric Miao
2010-02-03 14:20               ` Amit Kucheria
2010-02-03  9:24             ` Russell King - ARM Linux
2010-02-03 11:04             ` Sascha Hauer
2010-02-03 20:07               ` Amit Kucheria
2010-02-03 16:08             ` Rabin Vincent
2010-02-03  6:43           ` [PATCHv2 04/11] mxc: changes to common plat-mxc code to add support for i.MX5 Eric Miao
2010-02-03  9:49             ` Sascha Hauer
2010-02-03 13:38               ` Amit Kucheria
2010-02-03 15:16                 ` Eric Miao
2010-02-03 16:35           ` Grant Likely
2010-02-03  6:29         ` [PATCHv2 03/11] mxc: Fix Drive Strength Field in the IOMUX controller Eric Miao
2010-02-03  9:40           ` Sascha Hauer
2010-02-03 16:27         ` Grant Likely
2010-02-04  0:25           ` Amit Kucheria
2010-02-03 16:23       ` [PATCHv2 02/11] mxc timer: refactor timer code to use timer versions Grant Likely
2010-02-03  6:23     ` [PATCHv2 01/11] arm: mxc: TrustZone interrupt controller (TZIC) for i.MX5 family Eric Miao
2010-02-03  9:45       ` Sascha Hauer
2010-02-03 13:24       ` Amit Kucheria
2010-02-03 15:09         ` Eric Miao
2010-02-04  0:54           ` Eric Miao
2010-02-04 17:09         ` Nguyen Dinh-R00091

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).