All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
@ 2010-11-15 14:36 Shawn Guo
  2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
                   ` (11 more replies)
  0 siblings, 12 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

This patchset adds the initial support of i.MX28, and the target device
is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
and adding codes into arch/arm/mxc and arch/arm/mach-imx.

 git://git.pengutronix.de/git/imx/linux-2.6.git imx-single-kernel

Please take the time to review the patchset. Thanks.

Regards,
Shawn

Shawn Guo (11):
 arch/arm/mach-imx/Kconfig                       |   20 +
 arch/arm/mach-imx/Makefile                      |    4 +
 arch/arm/mach-imx/Makefile.boot                 |    4 +
 arch/arm/mach-imx/clock-imx28.c                 |  733 +++++++++++++++++++++++
 arch/arm/mach-imx/devices-imx28.h               |   20 +
 arch/arm/mach-imx/devices.c                     |   27 +-
 arch/arm/mach-imx/mach-mx28evk.c                |  109 ++++
 arch/arm/mach-imx/mm-imx28.c                    |   50 ++
 arch/arm/mach-imx/regs-clkctrl-mx28.h           |  662 ++++++++++++++++++++
 arch/arm/plat-mxc/Kconfig                       |   12 +
 arch/arm/plat-mxc/Makefile                      |    4 +-
 arch/arm/plat-mxc/devices/Kconfig               |    3 +
 arch/arm/plat-mxc/devices/Makefile              |    1 +
 arch/arm/plat-mxc/devices/platform-duart.c      |   42 ++
 arch/arm/plat-mxc/devices/platform-fec.c        |    5 +
 arch/arm/plat-mxc/gpio.c                        |  186 +++++-
 arch/arm/plat-mxc/icoll.c                       |   79 +++
 arch/arm/plat-mxc/include/mach/common.h         |    5 +
 arch/arm/plat-mxc/include/mach/devices-common.h |   11 +
 arch/arm/plat-mxc/include/mach/entry-macro.S    |   22 +-
 arch/arm/plat-mxc/include/mach/hardware.h       |    9 +-
 arch/arm/plat-mxc/include/mach/iomux-mx28.h     |   50 ++
 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h  |   91 +++
 arch/arm/plat-mxc/include/mach/irqs.h           |   11 +-
 arch/arm/plat-mxc/include/mach/memory.h         |    5 +-
 arch/arm/plat-mxc/include/mach/mx28.h           |  232 +++++++
 arch/arm/plat-mxc/include/mach/mxc.h            |   14 +
 arch/arm/plat-mxc/include/mach/uncompress.h     |   20 +-
 arch/arm/plat-mxc/iomux-pinctrl.c               |   94 +++
 arch/arm/plat-mxc/system.c                      |  104 ++++-
 arch/arm/plat-mxc/time.c                        |  120 +++-
 31 files changed, 2674 insertions(+), 75 deletions(-)

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

* [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:25   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/include/mach/hardware.h |    9 +-
 arch/arm/plat-mxc/include/mach/irqs.h     |   11 +-
 arch/arm/plat-mxc/include/mach/memory.h   |    5 +-
 arch/arm/plat-mxc/include/mach/mx28.h     |  232 +++++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/mxc.h      |   14 ++
 5 files changed, 264 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/plat-mxc/include/mach/mx28.h

diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 2f59b63..499b14c 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
  *
  * This program is free software; you can redistribute it and/or
@@ -63,6 +63,9 @@
  *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
  *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
  *	X_MEMC	0xd8000000+0x100000	->	0xf5c00000+0x100000
+ * mx28:
+ *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
+ *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
  * mx31:
  *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
  *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
@@ -127,6 +130,10 @@
 # include <mach/mx25.h>
 #endif
 
+#ifdef CONFIG_ARCH_MX28
+# include <mach/mx28.h>
+#endif
+
 #ifdef CONFIG_ARCH_MXC91231
 # include <mach/mxc91231.h>
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 86781f7..2f810c5 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -1,5 +1,5 @@
 /*
- *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -12,12 +12,13 @@
 #define __ASM_ARCH_MXC_IRQS_H__
 
 /*
- * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
+ * SoCs with AVIC interrupt controller have 64 IRQs,
+ * those with TZIC and ICOLL have 128.
  */
-#ifdef CONFIG_MXC_TZIC
-#define MXC_INTERNAL_IRQS	128
-#else
+#ifdef CONFIG_MXC_AVIC
 #define MXC_INTERNAL_IRQS	64
+#else
+#define MXC_INTERNAL_IRQS	128
 #endif
 
 #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index 564ec9d..af090e3 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -15,6 +15,7 @@
 #define MX21_PHYS_OFFSET	UL(0xc0000000)
 #define MX25_PHYS_OFFSET	UL(0x80000000)
 #define MX27_PHYS_OFFSET	UL(0xa0000000)
+#define MX28_PHYS_OFFSET	UL(0x40000000)
 #define MX3x_PHYS_OFFSET	UL(0x80000000)
 #define MX51_PHYS_OFFSET	UL(0x90000000)
 #define MXC91231_PHYS_OFFSET	UL(0x90000000)
@@ -28,6 +29,8 @@
 #  define PHYS_OFFSET		MX25_PHYS_OFFSET
 # elif defined CONFIG_MACH_MX27
 #  define PHYS_OFFSET		MX27_PHYS_OFFSET
+# elif defined CONFIG_ARCH_MX28
+#  define PHYS_OFFSET		MX28_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MX3
 #  define PHYS_OFFSET		MX3x_PHYS_OFFSET
 # elif defined CONFIG_ARCH_MXC91231
diff --git a/arch/arm/plat-mxc/include/mach/mx28.h b/arch/arm/plat-mxc/include/mach/mx28.h
new file mode 100644
index 0000000..6f73888
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx28.h
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_MX28_H__
+#define __MACH_MX28_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+#define SET_ADDR			0x4
+#define CLR_ADDR			0x8
+#define TOG_ADDR			0xc
+
+/*
+ * OCRAM
+ */
+#define MX28_OCRAM_BASE_ADDR		0x00000000
+#define MX28_OCRAM_SIZE			SZ_128K
+
+/*
+ * IO
+ */
+#define MX28_IO_BASE_ADDR		0x80000000
+#define MX28_IO_SIZE			SZ_1M
+
+#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
+#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
+#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
+#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
+#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
+#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
+#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
+#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
+#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
+#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
+#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
+#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
+#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
+#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
+#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
+#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
+#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
+#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
+#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
+#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
+#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
+#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
+#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
+#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
+#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
+#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
+#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
+#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
+#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
+#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
+#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
+#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
+#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
+#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
+#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
+#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
+#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
+#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
+#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
+#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
+#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
+#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
+#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
+#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
+#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
+#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
+#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
+#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
+#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
+#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
+#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
+#define MX28_ENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_FEC_BASE_ADDR		MX28_ENET_BASE_ADDR
+
+#define MX28_IO_P2V(x)			IMX_IO_P2V(x)
+#define MX28_IO_ADDRESS(x)		IOMEM(MX27_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX28_INT_BATT_BRNOUT		0
+#define MX28_INT_VDDD_BRNOUT		1
+#define MX28_INT_VDDIO_BRNOUT		2
+#define MX28_INT_VDDA_BRNOUT		3
+#define MX28_INT_VDD5V_DROOP		4
+#define MX28_INT_DCDC4P2_BRNOUT		5
+#define MX28_INT_VDD5V			6
+#define MX28_INT_RESV7			7
+#define MX28_INT_CAN0			8
+#define MX28_INT_CAN1			9
+#define MX28_INT_LRADC_TOUCH		10
+#define MX28_INT_RESV11			11
+#define MX28_INT_RESV12			12
+#define MX28_INT_HSADC			13
+#define MX28_INT_IRADC_THRESH0		14
+#define MX28_INT_IRADC_THRESH1		15
+#define MX28_INT_LRADC_CH0		16
+#define MX28_INT_LRADC_CH1		17
+#define MX28_INT_LRADC_CH2		18
+#define MX28_INT_LRADC_CH3		19
+#define MX28_INT_LRADC_CH4		20
+#define MX28_INT_LRADC_CH5		21
+#define MX28_INT_LRADC_CH6		22
+#define MX28_INT_LRADC_CH7		23
+#define MX28_INT_LRADC_BUTTON0		24
+#define MX28_INT_LRADC_BUTTON1		25
+#define MX28_INT_RESV26			26
+#define MX28_INT_PERFMON		27
+#define MX28_INT_RTC_1MSEC		28
+#define MX28_INT_RTC_ALARM		29
+#define MX28_INT_RESV30			30
+#define MX28_INT_COMMS			31
+#define MX28_INT_EMI_ERR		32
+#define MX28_INT_RESV33			33
+#define MX28_INT_RESV34			34
+#define MX28_INT_RESV35			35
+#define MX28_INT_RESV36			36
+#define MX28_INT_RESV37			37
+#define MX28_INT_LCDIF			38
+#define MX28_INT_PXP			39
+#define MX28_INT_RESV40			40
+#define MX28_INT_BCH			41
+#define MX28_INT_GPMI			42
+#define MX28_INT_RESV43			43
+#define MX28_INT_RESV44			44
+#define MX28_INT_SPDIF_ERROR		45
+#define MX28_INT_RESV46			46
+#define MX28_INT_DUART			47
+#define MX28_INT_TIMER0			48
+#define MX28_INT_TIMER1			49
+#define MX28_INT_TIMER2			50
+#define MX28_INT_TIMER3			51
+#define MX28_INT_DCP_VMI		52
+#define MX28_INT_DCP			53
+#define MX28_INT_DCP_SECURE		54
+#define MX28_INT_RESV55			55
+#define MX28_INT_RESV56			56
+#define MX28_INT_RESV57			57
+#define MX28_INT_SAIF1			58
+#define MX28_INT_SAIF0			59
+#define MX28_INT_RESV60			60
+#define MX28_INT_RESV61			61
+#define MX28_INT_RESV62			62
+#define MX28_INT_RESV63			63
+#define MX28_INT_RESV64			64
+#define MX28_INT_RESV65			65
+#define MX28_INT_SPDIF_DMA		66
+#define MX28_INT_RESV67			67
+#define MX28_INT_I2C0_DMA		68
+#define MX28_INT_I2C1_DMA		69
+#define MX28_INT_AUART0_RX_DMA		70
+#define MX28_INT_AUART0_TX_DMA		71
+#define MX28_INT_AUART1_RX_DMA		72
+#define MX28_INT_AUART1_TX_DMA		73
+#define MX28_INT_AUART2_RX_DMA		74
+#define MX28_INT_AUART2_TX_DMA		75
+#define MX28_INT_AUART3_RX_DMA		76
+#define MX28_INT_AUART3_TX_DMA		77
+#define MX28_INT_AUART4_RX_DMA		78
+#define MX28_INT_AUART4_TX_DMA		79
+#define MX28_INT_SAIF0_DMA		80
+#define MX28_INT_SAIF1_DMA		81
+#define MX28_INT_SSP0_DMA		82
+#define MX28_INT_SSP1_DMA		83
+#define MX28_INT_SSP2_DMA		84
+#define MX28_INT_SSP3_DMA		85
+#define MX28_INT_LCDIF_DMA		86
+#define MX28_INT_HSADC_DMA		87
+#define MX28_INT_GPMI_DMA		88
+#define MX28_INT_DIGCTL_DEBUG_TRAP	89
+#define MX28_INT_RESV90			90
+#define MX28_INT_RESV91			91
+#define MX28_INT_USB1			92
+#define MX28_INT_USB0			93
+#define MX28_INT_USB1_WAKEUP		94
+#define MX28_INT_USB0_WAKEUP		95
+#define MX28_INT_SSP0			96
+#define MX28_INT_SSP1			97
+#define MX28_INT_SSP2			98
+#define MX28_INT_SSP3			99
+#define MX28_INT_ENET_SWI		100
+#define MX28_INT_ENET_MAC0		101
+#define MX28_INT_ENET_MAC1		102
+#define MX28_INT_ENET_MAC0_1588		103
+#define MX28_INT_ENET_MAC1_1588		104
+#define MX28_INT_RESV105		105
+#define MX28_INT_RESV106		106
+#define MX28_INT_RESV107		107
+#define MX28_INT_RESV108		108
+#define MX28_INT_RESV109		109
+#define MX28_INT_I2C1_ERROR		110
+#define MX28_INT_I2C0_ERROR		111
+#define MX28_INT_AUART0			112
+#define MX28_INT_AUART1			113
+#define MX28_INT_AUART2			114
+#define MX28_INT_AUART3			115
+#define MX28_INT_AUART4			116
+#define MX28_INT_RESV117		117
+#define MX28_INT_RESV118		118
+#define MX28_INT_RESV119		119
+#define MX28_INT_RESV120		120
+#define MX28_INT_RESV121		121
+#define MX28_INT_RESV122		122
+#define MX28_INT_GPIO4			123
+#define MX28_INT_GPIO3			124
+#define MX28_INT_GPIO2			125
+#define MX28_INT_GPIO1			126
+#define MX28_INT_GPIO0			127
+#define MX28_INT_FEC			MX28_INT_ENET_MAC0
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 3432b78..563901f 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_MX21		21
 #define MXC_CPU_MX25		25
 #define MXC_CPU_MX27		27
+#define MXC_CPU_MX28		28
 #define MXC_CPU_MX31		31
 #define MXC_CPU_MX35		35
 #define MXC_CPU_MX51		51
@@ -87,6 +88,18 @@ extern unsigned int __mxc_cpu_type;
 # define cpu_is_mx27()		(0)
 #endif
 
+#ifdef CONFIG_ARCH_MX28
+# ifdef mxc_cpu_type
+#  undef mxc_cpu_type
+#  define mxc_cpu_type __mxc_cpu_type
+# else
+#  define mxc_cpu_type MXC_CPU_MX28
+# endif
+# define cpu_is_mx28()		(mxc_cpu_type == MXC_CPU_MX28)
+#else
+# define cpu_is_mx28()		(0)
+#endif
+
 #ifdef CONFIG_ARCH_MX31
 # ifdef mxc_cpu_type
 #  undef mxc_cpu_type
@@ -161,5 +174,6 @@ extern void __iomem *mxc_irq_base;
 
 #define MXC_IRQ_TYPE_AVIC	1
 #define MXC_IRQ_TYPE_TZIC	2
+#define MXC_IRQ_TYPE_ICOLL	3
 
 #endif /*  __ASM_ARCH_MXC_H__ */
-- 
1.7.1

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

* [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
  2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:33   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

MX28 uses Interrupt Collector (ICOLL) as the interrupt
controller. So ICOLL becomes the third interrupt controller
for MXC besides AVIC and TZIC.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/icoll.c                    |   79 ++++++++++++++++++++++++++
 arch/arm/plat-mxc/include/mach/entry-macro.S |   22 ++++++-
 2 files changed, 97 insertions(+), 4 deletions(-)
 create mode 100644 arch/arm/plat-mxc/icoll.c

diff --git a/arch/arm/plat-mxc/icoll.c b/arch/arm/plat-mxc/icoll.c
new file mode 100644
index 0000000..e9a9e42
--- /dev/null
+++ b/arch/arm/plat-mxc/icoll.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define HW_ICOLL_VECTOR				0x0000
+#define HW_ICOLL_LEVELACK			0x0010
+#define HW_ICOLL_CTRL				0x0020
+#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
+#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
+#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
+#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
+
+void __iomem *icoll_base;
+
+static void icoll_ack_irq(unsigned int irq)
+{
+	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
+
+	/* ACK current interrupt (level 0) */
+	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
+			icoll_base + HW_ICOLL_LEVELACK);
+}
+
+static void icoll_mask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
+}
+
+static void icoll_unmask_irq(unsigned int irq)
+{
+	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
+			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
+}
+
+static struct irq_chip mxc_icoll_chip = {
+	.ack = icoll_ack_irq,
+	.mask = icoll_mask_irq,
+	.unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void __iomem *irqbase)
+{
+	int i;
+
+	icoll_base = irqbase;
+	mxc_irq_base = irqbase;
+	mxc_irq_controller_type = MXC_IRQ_TYPE_ICOLL;
+
+	/* Reset icoll */
+	mxc_reset_block(irqbase + HW_ICOLL_CTRL);
+
+	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+		set_irq_chip(i, &mxc_icoll_chip);
+		set_irq_handler(i, handle_level_irq);
+		set_irq_flags(i, IRQF_VALID);
+	}
+}
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index a7dd008..a66e804 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-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *  Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  */
 
 /*
@@ -73,25 +73,39 @@
 #endif
 	.endm
 
+	.macro	icoll_get_irqnr_and_base, irqnr, irqstat, base, tmp
+	ldr \irqnr, [\base, #0x70]
+	cmp \irqnr, #0x7F
+	moveqs \irqnr, #0
+	.endm
+
 	.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
-#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC
+#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC && defined CONFIG_MXC_ICOLL
 	ldr	\tmp, =mxc_irq_controller_type
 	ldr	\tmp, [\tmp]
 	cmp	\tmp, #MXC_IRQ_TYPE_AVIC
 	beq	3001f
+	cmp	\tmp, #MXC_IRQ_TYPE_ICOLL
+	beq	3002f
 
 	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
-	b	3002f
+	b	3003f
 3001:
 	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+	b	3003f
 3002:
+	icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+	b	3003f
+3003:
 
 #elif defined CONFIG_MXC_TZIC
 	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
 #elif defined CONFIG_MXC_AVIC
 	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
+#elif defined CONFIG_MXC_ICOLL
+	icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
 #else
-#error no tzic and no avic?
+#error none of tzic, avic, icoll?
 #endif
 	.endm
 
-- 
1.7.1

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

* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
  2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
  2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:36   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
                   ` (8 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

1. The wdog reset is implemented in RTC block on MX28.
2. Implement the common reset routine for most blocks on MX28,
   so that the blocks can call it to get a software reset.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/system.c |  104 ++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 101 insertions(+), 3 deletions(-)

diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index c3972c5..257b426 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 1999 ARM Limited
  * Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
  * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
  *
@@ -36,6 +36,7 @@ static void __iomem *wdog_base;
 void arch_reset(char mode, const char *cmd)
 {
 	unsigned int wcr_enable;
+	struct clk *clk;
 
 #ifdef CONFIG_ARCH_MXC91231
 	if (cpu_is_mxc91231()) {
@@ -52,9 +53,18 @@ void arch_reset(char mode, const char *cmd)
 
 	if (cpu_is_mx1()) {
 		wcr_enable = (1 << 0);
-	} else {
-		struct clk *clk;
+	} else if (cpu_is_mx28()) {
+		clk = clk_get_sys("rtc", NULL);
+		if (!IS_ERR(clk))
+			clk_enable(clk);
 
+		/* set wdog count */
+		__raw_writel(1, wdog_base + 0x50);
+		/* wdog enbable bit */
+		wcr_enable = (1 << 4);
+		/* shift to SET address */
+		wdog_base += 0x4;
+	} else {
 		clk = clk_get_sys("imx-wdt.0", NULL);
 		if (!IS_ERR(clk))
 			clk_enable(clk);
@@ -80,3 +90,91 @@ void mxc_arch_reset_init(void __iomem *base)
 {
 	wdog_base = base;
 }
+
+#ifdef CONFIG_ARCH_MX28
+int mxc_reset_block(void __iomem *reg_addr)
+{
+	u32 reg;
+	int timeout;
+
+	/*
+	 * The process of software reset of IP block is done
+	 * in several steps:
+	 *
+	 * 1) clear SFTRST and wait it cleared;
+	 * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
+	 * 3) clear SFTRST and wait it cleared;
+	 * 4) clear CLKGATE and wait it cleared.
+	 */
+
+	/* Clear SFTRST */
+	reg = __raw_readl(reg_addr);
+	reg &= ~(1 << 31);
+	__raw_writel(reg, reg_addr);
+	/* Wait SFTRST cleared */
+	timeout = 1000;
+	do {
+		mdelay(1);
+		if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
+			break;
+	} while (--timeout > 0);
+	if (timeout <= 0) {
+		pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
+		return -ETIMEDOUT;
+	}
+
+	/* Clear CLKGATE */
+	reg = __raw_readl(reg_addr);
+	reg &= ~(1 << 30);
+	__raw_writel(reg, reg_addr);
+	/* Set SFTRST to reset the block */
+	reg = __raw_readl(reg_addr);
+	reg |= (1 << 31);
+	__raw_writel(reg, reg_addr);
+	/* Poll CLKGATE set */
+	timeout = 1000;
+	do {
+		mdelay(1);
+		if (__raw_readl(reg_addr) & (1 << 30))
+			break;
+	} while (--timeout > 0);
+	if (timeout <= 0) {
+		pr_err("%s(%p): poll CLKGATE timeout\n", __func__, reg_addr);
+		return -ETIMEDOUT;
+	}
+
+	/* Clear SFTRST */
+	reg = __raw_readl(reg_addr);
+	reg &= ~(1 << 31);
+	__raw_writel(reg, reg_addr);
+	/* Wait SFTRST cleared */
+	timeout = 1000;
+	do {
+		mdelay(1);
+		if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
+			break;
+	} while (--timeout > 0);
+	if (timeout <= 0) {
+		pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
+		return -ETIMEDOUT;
+	}
+
+	/* Clear CLKGATE */
+	reg = __raw_readl(reg_addr);
+	reg &= ~(1 << 30);
+	__raw_writel(reg, reg_addr);
+	/* Wait CLKGATE cleared */
+	timeout = 1000;
+	do {
+		mdelay(1);
+		if ((__raw_readl(reg_addr) & (1 << 30)) == 0)
+			break;
+	} while (--timeout > 0);
+	if (timeout <= 0) {
+		pr_err("%s(%p): clear CLKGATE timeout\n", __func__, reg_addr);
+		return -ETIMEDOUT;
+	}
+
+	return 0;
+}
+#endif
-- 
1.7.1

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

* [PATCH 04/11] ARM: imx: Add timer support for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (2 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:40   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

SoC i.MX28 implements the timer in block TIMROT. It adds the
support in the same file with GPT, and uses timer_is_timrot()
to distinguish the IP block.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/time.c |  120 ++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 100 insertions(+), 20 deletions(-)

diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
index f9a1b05..3e1f09d 100644
--- a/arch/arm/plat-mxc/time.c
+++ b/arch/arm/plat-mxc/time.c
@@ -5,6 +5,7 @@
  *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
  *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
  *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
+ *  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -63,8 +64,22 @@
 #define V2_TCN			0x24
 #define V2_TCMP			0x10
 
-#define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
-#define timer_is_v2()	(!timer_is_v1())
+/* TIMROT */
+#define HW_TIMROT_ROTCTRL			0x00
+#define HW_TIMROT_TIMCTRL0			0x20
+#define HW_TIMROT_TIMCTRL0_SET			0x24
+#define HW_TIMROT_TIMCTRL0_CLR			0x28
+#define HW_TIMROT_RUNNING_COUNT0		0x30
+#define HW_TIMROT_MATCH_COUNT0			0x50
+#define BM_TIMROT_TIMCTRL0_IRQ_EN		0x00004000
+#define BM_TIMROT_TIMCTRL0_IRQ			0x00008000
+#define BM_TIMROT_TIMCTRL0_MATCH_MODE		0x00000800
+#define BP_TIMROT_TIMCTRL0_SELECT		0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL	0xb
+
+#define timer_is_v1()		(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
+#define timer_is_v2()		(!timer_is_v1())
+#define timer_is_timrot()	(cpu_is_mx28())
 
 static struct clock_event_device clockevent_mxc;
 static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
@@ -105,6 +120,24 @@ static void gpt_irq_acknowledge(void)
 		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
 }
 
+static inline void timrot_irq_disable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRL0_CLR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
+			timer_base + HW_TIMROT_TIMCTRL0_SET);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ,
+			timer_base + HW_TIMROT_TIMCTRL0_CLR);
+}
+
 static cycle_t mx1_2_get_cycles(struct clocksource *cs)
 {
 	return __raw_readl(timer_base + MX1_2_TCN);
@@ -115,6 +148,11 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
 	return __raw_readl(timer_base + V2_TCN);
 }
 
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+	return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNT0);
+}
+
 static struct clocksource clocksource_mxc = {
 	.name 		= "mxc_timer1",
 	.rating		= 200,
@@ -128,8 +166,12 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (timer_is_v2())
+	if (timer_is_timrot()) {
+		clocksource_mxc.read = timrot_get_cycles;
+		clocksource_mxc.shift = 10;
+	} else if (timer_is_v2()) {
 		clocksource_mxc.read = v2_get_cycles;
+	}
 
 	clocksource_mxc.mult = clocksource_hz2mult(c,
 					clocksource_mxc.shift);
@@ -166,6 +208,18 @@ static int v2_set_next_event(unsigned long evt,
 				-ETIME : 0;
 }
 
+static int timrot_set_next_event(unsigned long evt,
+					struct clock_event_device *dev)
+{
+	unsigned long match;
+
+	match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNT0) - evt;
+	__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNT0);
+
+	return (int)(match - __raw_readl(timer_base +
+			HW_TIMROT_RUNNING_COUNT0)) > 0 ? -ETIME : 0;
+}
+
 #ifdef DEBUG
 static const char *clock_event_mode_label[] = {
 	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
@@ -186,12 +240,19 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	 */
 	local_irq_save(flags);
 
-	/* Disable interrupt in GPT module */
-	gpt_irq_disable();
+	/* Disable interrupt in timer module */
+	if (timer_is_timrot())
+		timrot_irq_disable();
+	else
+		gpt_irq_disable();
 
 	if (mode != clockevent_mode) {
 		/* Set event time into far-far future */
-		if (timer_is_v2())
+		if (timer_is_timrot())
+			__raw_writel(__raw_readl(timer_base +
+					HW_TIMROT_RUNNING_COUNT0) + 3,
+					timer_base + HW_TIMROT_MATCH_COUNT0);
+		else if (timer_is_v2())
 			__raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
 					timer_base + V2_TCMP);
 		else
@@ -199,7 +260,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
 					timer_base + MX1_2_TCMP);
 
 		/* Clear pending interrupt */
-		gpt_irq_acknowledge();
+		if (timer_is_timrot())
+			timrot_irq_acknowledge();
+		else
+			gpt_irq_acknowledge();
 	}
 
 #ifdef DEBUG
@@ -225,7 +289,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
 	 * mode switching
 	 */
 		local_irq_save(flags);
-		gpt_irq_enable();
+		if (timer_is_timrot())
+			timrot_irq_enable();
+		else
+			gpt_irq_enable();
 		local_irq_restore(flags);
 		break;
 	case CLOCK_EVT_MODE_SHUTDOWN:
@@ -249,7 +316,10 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
 	else
 		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
 
-	gpt_irq_acknowledge();
+	if (timer_is_timrot())
+		timrot_irq_acknowledge();
+	else
+		gpt_irq_acknowledge();
 
 	evt->event_handler(evt);
 
@@ -275,7 +345,9 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
 {
 	unsigned int c = clk_get_rate(timer_clk);
 
-	if (timer_is_v2())
+	if (timer_is_timrot())
+		clockevent_mxc.set_next_event = timrot_set_next_event;
+	else if (timer_is_v2())
 		clockevent_mxc.set_next_event = v2_set_next_event;
 
 	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
@@ -303,16 +375,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
 	/*
 	 * Initialise to a known state (all timers off, and timing reset)
 	 */
-
-	__raw_writel(0, timer_base + MXC_TCTL);
-	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
-
-	if (timer_is_v2())
-		tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
-	else
-		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
-
-	__raw_writel(tctl_val, timer_base + MXC_TCTL);
+	if (timer_is_timrot()) {
+		mxc_reset_block(base + HW_TIMROT_ROTCTRL);
+		__raw_writel(
+			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+			BM_TIMROT_TIMCTRL0_IRQ_EN |
+			BM_TIMROT_TIMCTRL0_MATCH_MODE,
+			timer_base + HW_TIMROT_TIMCTRL0); /* timer0*/
+	} else {
+		__raw_writel(0, timer_base + MXC_TCTL);
+		__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
+		if (timer_is_v2())
+			tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR |
+					V2_TCTL_WAITEN | MXC_TCTL_TEN;
+		else
+			tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 |
+					MXC_TCTL_TEN;
+		__raw_writel(tctl_val, timer_base + MXC_TCTL);
+	}
 
 	/* init and register the timer to the framework */
 	mxc_clocksource_init(timer_clk);
-- 
1.7.1

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

* [PATCH 05/11] ARM: imx: Add GPIO support for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (3 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:43   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

SoC i.MX28 implements GPIO functions in block PINCTRL. It adds
the support in the same file used by other i.MX SoCs, and uses
cpu_is_mx28() to distinguish the PINCTRL from GPIO used by other
i.MX SoCs.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/gpio.c |  186 +++++++++++++++++++++++++++++++++++++--------
 1 files changed, 153 insertions(+), 33 deletions(-)

diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 9c3e362..f0d94af 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -30,6 +30,17 @@
 static struct mxc_gpio_port *mxc_gpio_ports;
 static int gpio_table_size;
 
+/* PINCTRL */
+#define GPIO_PORT_ID(p)	(((void *)p - (void *)mxc_gpio_ports) / sizeof(p))
+#define GPIO_DOUT(p)		(0x0700 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_DIN(p)		(0x0900 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_DOE(p)		(0x0b00 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_PIN2IRQ(p)		(0x1000 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_IRQEN(p)		(0x1100 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_LEV(p)		(0x1200 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_POL(p)		(0x1300 + GPIO_PORT_ID(p) * 0x10)
+#define GPIO_IRQSTAT(p)		(0x1400 + GPIO_PORT_ID(p) * 0x10)
+
 #define cpu_is_mx1_mx2()	(cpu_is_mx1() || cpu_is_mx2())
 
 #define GPIO_DR		(cpu_is_mx1_mx2() ? 0x1c : 0x00)
@@ -40,17 +51,25 @@ static int gpio_table_size;
 #define GPIO_IMR	(cpu_is_mx1_mx2() ? 0x30 : 0x14)
 #define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
 
-#define GPIO_INT_LOW_LEV	(cpu_is_mx1_mx2() ? 0x3 : 0x0)
-#define GPIO_INT_HIGH_LEV	(cpu_is_mx1_mx2() ? 0x2 : 0x1)
-#define GPIO_INT_RISE_EDGE	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
-#define GPIO_INT_FALL_EDGE	(cpu_is_mx1_mx2() ? 0x1 : 0x3)
+#define GPIO_INT_LOW_LEV \
+	(cpu_is_mx28() ? 0x1 : (cpu_is_mx1_mx2() ? 0x3 : 0x0))
+#define GPIO_INT_HIGH_LEV \
+	(cpu_is_mx28() ? 0x3 : (cpu_is_mx1_mx2() ? 0x2 : 0x1))
+#define GPIO_INT_RISE_EDGE \
+	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
+#define GPIO_INT_FALL_EDGE \
+	(cpu_is_mx28() ? 0x0 : (cpu_is_mx1_mx2() ? 0x1 : 0x3))
 #define GPIO_INT_NONE		0x4
 
 /* Note: This driver assumes 32 GPIOs are handled in one register */
 
 static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
 {
-	__raw_writel(1 << index, port->base + GPIO_ISR);
+	if (cpu_is_mx28())
+		__raw_writel(1 << index,
+				port->base + GPIO_IRQSTAT(port) + CLR_ADDR);
+	else
+		__raw_writel(1 << index, port->base + GPIO_ISR);
 }
 
 static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
@@ -58,9 +77,23 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
 {
 	u32 l;
 
-	l = __raw_readl(port->base + GPIO_IMR);
-	l = (l & (~(1 << index))) | (!!enable << index);
-	__raw_writel(l, port->base + GPIO_IMR);
+	if (cpu_is_mx28()) {
+		if (enable == 0) {
+			__raw_writel(1 << index,
+				port->base + GPIO_PIN2IRQ(port) + CLR_ADDR);
+			__raw_writel(1 << index,
+				port->base + GPIO_IRQEN(port) + CLR_ADDR);
+		} else {
+			__raw_writel(1 << index,
+				port->base + GPIO_PIN2IRQ(port) + SET_ADDR);
+			__raw_writel(1 << index,
+				port->base + GPIO_IRQEN(port) + SET_ADDR);
+		}
+	} else {
+		l = __raw_readl(port->base + GPIO_IMR);
+		l = (l & (~(1 << index))) | (!!enable << index);
+		__raw_writel(l, port->base + GPIO_IMR);
+	}
 }
 
 static void gpio_ack_irq(u32 irq)
@@ -120,10 +153,28 @@ static int gpio_set_irq_type(u32 irq, u32 type)
 		return -EINVAL;
 	}
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = __raw_readl(reg) & ~(0x3 << (bit << 1));
-	__raw_writel(val | (edge << (bit << 1)), reg);
+	if (cpu_is_mx28()) {
+		/* set level or edge */
+		if (edge & 0x1)
+			__raw_writel(1 << (gpio & 31),
+					port->base + GPIO_LEV(port) + SET_ADDR);
+		else
+			__raw_writel(1 << (gpio & 31),
+					port->base + GPIO_LEV(port) + CLR_ADDR);
+		/* set polarity */
+		if ((edge >> 1) & 0x1)
+			__raw_writel(1 << (gpio & 31),
+					port->base + GPIO_POL(port) + SET_ADDR);
+		else
+			__raw_writel(1 << (gpio & 31),
+					port->base + GPIO_POL(port) + CLR_ADDR);
+	} else {
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
+		bit = gpio & 0xf;
+		val = __raw_readl(reg) & ~(0x3 << (bit << 1));
+		__raw_writel(val | (edge << (bit << 1)), reg);
+	}
+
 	_clear_gpio_irqstatus(port, gpio & 0x1f);
 
 	return 0;
@@ -135,23 +186,36 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
 	u32 bit, val;
 	int edge;
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = __raw_readl(reg);
-	edge = (val >> (bit << 1)) & 3;
-	val &= ~(0x3 << (bit << 1));
-	if (edge == GPIO_INT_HIGH_LEV) {
-		edge = GPIO_INT_LOW_LEV;
-		pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
-	} else if (edge == GPIO_INT_LOW_LEV) {
-		edge = GPIO_INT_HIGH_LEV;
-		pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+	if (cpu_is_mx28()) {
+		edge = 1 << (gpio & 31);
+		val = __raw_readl(port->base + GPIO_LEV(port));
+		if (val & edge) {
+			/* level is invalid for this function */
+			pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+				gpio, edge);
+			return;
+		}
+		__raw_writel(1 << (gpio & 31),
+				port->base + GPIO_POL(port) + TOG_ADDR);
 	} else {
-		pr_err("mxc: invalid configuration for GPIO %d: %x\n",
-		       gpio, edge);
-		return;
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
+		bit = gpio & 0xf;
+		val = __raw_readl(reg);
+		edge = (val >> (bit << 1)) & 3;
+		val &= ~(0x3 << (bit << 1));
+		if (edge == GPIO_INT_HIGH_LEV) {
+			edge = GPIO_INT_LOW_LEV;
+			pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
+		} else if (edge == GPIO_INT_LOW_LEV) {
+			edge = GPIO_INT_HIGH_LEV;
+			pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
+		} else {
+			pr_err("mxc: invalid configuration for GPIO %d: %x\n",
+			       gpio, edge);
+			return;
+		}
+		__raw_writel(val | (edge << (bit << 1)), reg);
 	}
-	__raw_writel(val | (edge << (bit << 1)), reg);
 }
 
 /* handle 32 interrupts in one status register */
@@ -183,6 +247,29 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 	mxc_gpio_irq_handler(port, irq_stat);
 }
 
+/* MX28 has one interrupt *per* gpio port */
+static void mx28_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+	u32 irq_stat;
+	struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
+	u32 gpio_irq_no_base = port->virtual_irq_start;
+
+	irq_stat = __raw_readl(port->base + GPIO_IRQSTAT(port)) &
+			__raw_readl(port->base + GPIO_IRQEN(port)) &
+			__raw_readl(port->base + GPIO_PIN2IRQ(port));
+
+	while (irq_stat != 0) {
+		int irqoffset = fls(irq_stat) - 1;
+
+		if (port->both_edges & (1 << irqoffset))
+			mxc_flip_edge(port, irqoffset);
+
+		generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+		irq_stat &= ~(1 << irqoffset);
+	}
+}
+
 /* MX2 has one interrupt *for all* gpio ports */
 static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 {
@@ -247,14 +334,20 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
 		container_of(chip, struct mxc_gpio_port, chip);
 	u32 l;
 	unsigned long flags;
+	void __iomem *reg;
+
+	if (cpu_is_mx28())
+		reg = port->base + GPIO_DOE(port);
+	else
+		reg = port->base + GPIO_GDIR;
 
 	spin_lock_irqsave(&port->lock, flags);
-	l = __raw_readl(port->base + GPIO_GDIR);
+	l = __raw_readl(reg);
 	if (dir)
 		l |= 1 << offset;
 	else
 		l &= ~(1 << offset);
-	__raw_writel(l, port->base + GPIO_GDIR);
+	__raw_writel(l, reg);
 	spin_unlock_irqrestore(&port->lock, flags);
 }
 
@@ -262,9 +355,14 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
 {
 	struct mxc_gpio_port *port =
 		container_of(chip, struct mxc_gpio_port, chip);
-	void __iomem *reg = port->base + GPIO_DR;
 	u32 l;
 	unsigned long flags;
+	void __iomem *reg;
+
+	if (cpu_is_mx28())
+		reg = port->base + GPIO_DOUT(port);
+	else
+		reg = port->base + GPIO_DR;
 
 	spin_lock_irqsave(&port->lock, flags);
 	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
@@ -276,8 +374,14 @@ static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
 {
 	struct mxc_gpio_port *port =
 		container_of(chip, struct mxc_gpio_port, chip);
+	void __iomem *reg;
+
+	if (cpu_is_mx28())
+		reg = port->base + GPIO_DIN(port);
+	else
+		reg = port->base + GPIO_PSR;
 
-	return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
+	return (__raw_readl(reg) >> offset) & 1;
 }
 
 static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
@@ -306,8 +410,19 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 
 	for (i = 0; i < cnt; i++) {
 		/* disable the interrupt and clear the status */
-		__raw_writel(0, port[i].base + GPIO_IMR);
-		__raw_writel(~0, port[i].base + GPIO_ISR);
+		if (cpu_is_mx28()) {
+			__raw_writel(0, port[i].base +
+						GPIO_PIN2IRQ(&port[i]));
+			__raw_writel(0, port[i].base +
+						GPIO_IRQEN(&port[i]));
+			__raw_writel(~0, port[i].base +
+						GPIO_IRQSTAT(&port[i]) +
+						CLR_ADDR);
+		} else {
+			__raw_writel(0, port[i].base + GPIO_IMR);
+			__raw_writel(~0, port[i].base + GPIO_ISR);
+		}
+
 		for (j = port[i].virtual_irq_start;
 			j < port[i].virtual_irq_start + 32; j++) {
 			set_irq_chip(j, &gpio_irq_chip);
@@ -338,6 +453,11 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 						mx3_gpio_irq_handler);
 				set_irq_data(port[i].irq_high, &port[i]);
 			}
+		} else if (cpu_is_mx28()) {
+			/* setup one handler for each entry */
+			set_irq_chained_handler(port[i].irq,
+						mx28_gpio_irq_handler);
+			set_irq_data(port[i].irq, &port[i]);
 		}
 	}
 
-- 
1.7.1

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

* [PATCH 06/11] ARM: imx: Add IOMUX support for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (4 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:46   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
                   ` (5 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Soc i.MX28 supports IOMUX function in block PINCTRL. Comparing
to the naming of iomux-v1 and iomux-v3, it uses iomux-pinctrl,
since PINCTRL is a totally different IP block from IOMUX and it's
not reasonable to name it iomux-v2 or iomux-v4, which is used to
distinguish the different revision of same IP block.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/include/mach/iomux-mx28.h    |   50 +++++++++++++
 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h |   91 +++++++++++++++++++++++
 arch/arm/plat-mxc/iomux-pinctrl.c              |   94 ++++++++++++++++++++++++
 3 files changed, 235 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx28.h
 create mode 100644 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
 create mode 100644 arch/arm/plat-mxc/iomux-pinctrl.c

diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx28.h b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..8c68bd6
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux-pinctrl.h>
+
+/*
+ * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux-pinctrl.h
+ *
+ *					 		BANK PIN     MUX            VOL          MA            PULL
+ */
+/* DUART */
+#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX28_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
new file mode 100644
index 0000000..c2fdb33
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *			<armlinux@phytec.de>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+
+#ifndef __MACH_IOMUX_PINCTRL_H__
+#define __MACH_IOMUX_PINCTRL_H__
+
+typedef struct deprecated_pad_desc {
+	unsigned bank:3;
+	unsigned pin:5;
+	unsigned muxsel:2;
+	unsigned ma:3;
+	unsigned vol:2;
+	unsigned pull:1;
+} iomux_pinctrl_cfg_t;
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)	\
+		{						\
+			.bank	= _bank,			\
+			.pin	= _pin,				\
+			.muxsel	= _muxsel,			\
+			.vol	= _vol,				\
+			.ma	= _ma,				\
+			.pull	= _pull,			\
+		}
+
+#define PAD_MUXSEL_0		0
+#define PAD_MUXSEL_1		1
+#define PAD_MUXSEL_2		2
+#define PAD_MUXSEL_GPIO		3
+
+#define PAD_1V8			0
+#define PAD_3V3			1
+#define PAD_VOL_NONE		2
+
+#define PAD_4MA			0
+#define PAD_8MA			1
+#define PAD_12MA		2
+#define PAD_16MA		3
+#define PAD_MA_NONE		4
+
+#define PAD_NOPULL		0
+#define PAD_PULL		1
+
+#define MX51_NUM_GPIO_PORT	4
+
+#define GPIO_PIN_MASK 0x1f
+
+#define GPIO_PORT_SHIFT 5
+#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
+
+#define GPIO_PORTA	(0 << GPIO_PORT_SHIFT)
+#define GPIO_PORTB	(1 << GPIO_PORT_SHIFT)
+#define GPIO_PORTC	(2 << GPIO_PORT_SHIFT)
+#define GPIO_PORTD	(3 << GPIO_PORT_SHIFT)
+#define GPIO_PORTE	(4 << GPIO_PORT_SHIFT)
+#define GPIO_PORTF	(5 << GPIO_PORT_SHIFT)
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad);
+
+/*
+ * setups mutliple pads
+ * convenient way to call the above function with tables
+ */
+int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base);
+
+#endif /* __MACH_IOMUX_PINCTRL_H__*/
diff --git a/arch/arm/plat-mxc/iomux-pinctrl.c b/arch/arm/plat-mxc/iomux-pinctrl.c
new file mode 100644
index 0000000..5f5b5ac
--- /dev/null
+++ b/arch/arm/plat-mxc/iomux-pinctrl.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
+ *                       <armlinux@phytec.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ */
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/gpio.h>
+#include <asm/mach/map.h>
+#include <mach/hardware.h>
+#include <mach/iomux-pinctrl.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad)
+{
+	u32 reg, ofs, bp, bm;
+
+	/* MUXSEL */
+	ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
+	bp = pad->pin % 16 * 2;
+	bm = 0x3 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->muxsel << bp;
+	__raw_writel(reg, base + ofs);
+
+	/* DRIVE */
+	if (pad->ma != PAD_MA_NONE && pad->vol != PAD_VOL_NONE)
+	{
+		ofs = 0x300 + pad->bank * 0x40 + pad->pin / 8 * 0x10;
+		bp = pad->pin % 8 * 4;
+		bm = 0x7 << bp;
+		reg = __raw_readl(base + ofs);
+		reg &= ~bm;
+		reg |= pad->ma << bp | pad->vol << (bp + 2);
+		__raw_writel(reg, base + ofs);
+	}
+
+	/* PULL */
+	ofs = 0x600 + pad->bank * 0x10;
+	bp = pad->pin;
+	bm = 0x1 << bp;
+	reg = __raw_readl(base + ofs);
+	reg &= ~bm;
+	reg |= pad->pull << bp;
+	__raw_writel(reg, base + ofs);
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_pad);
+
+int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count)
+{
+	iomux_pinctrl_cfg_t *p = pad_list;
+	int i;
+	int ret;
+
+	for (i = 0; i < count; i++) {
+		ret = mxc_iomux_pinctrl_setup_pad(p);
+		if (ret)
+			return ret;
+		p++;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_multiple_pads);
+
+void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base)
+{
+	base = iomux_pinctrl_base;
+}
-- 
1.7.1

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

* [PATCH 07/11] ARM: imx: Add support of uncompress print for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (5 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:47   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

SoC i.MX28 uses DUART IP block as the debug serial. It adds the
support in the same file used by other i.MX SoC UART, and uses
variable is_duart to distinguish.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/plat-mxc/include/mach/uncompress.h |   20 ++++++++++++++------
 1 files changed, 14 insertions(+), 6 deletions(-)

diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index 9dd9c20..adb617f 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -1,8 +1,9 @@
 /*
- *  arch/arm/plat-mxc/include/mach/uncompress.h
+ *  rch/arm/plat-mxc/include/mach/uncompress.h
  *
  *  Copyright (C) 1999 ARM Limited
  *  Copyright (C) Shane Nay (shane at minirl.com)
+ *  Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -22,14 +23,16 @@
 #include <asm/mach-types.h>
 
 static unsigned long uart_base;
+static unsigned short is_duart = 0;
 
 #define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
 
-#define USR2 0x98
-#define USR2_TXFE (1<<14)
-#define TXR  0x40
-#define UCR1 0x80
-#define UCR1_UARTEN 1
+#define USR2		(is_duart ? 0x18 : 0x98)
+#define USR2_TXFE	(is_duart ? 1<<7 : 1<<14)
+#define USR2_BUSY	(1 << 3)
+#define TXR		(is_duart ? 0x00 : 0x40)
+#define UCR1		(is_duart ? 0x30 : 0x80)
+#define UCR1_UARTEN	1
 
 /*
  * The following code assumes the serial port has already been
@@ -59,6 +62,7 @@ static inline void flush(void)
 
 #define MX1_UART1_BASE_ADDR	0x00206000
 #define MX25_UART1_BASE_ADDR	0x43f90000
+#define MX28_DUART_BASE_ADDR	0x80074000
 #define MX2X_UART1_BASE_ADDR	0x1000a000
 #define MX3X_UART1_BASE_ADDR	0x43F90000
 #define MX3X_UART2_BASE_ADDR	0x43F94000
@@ -83,6 +87,10 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
 	case MACH_TYPE_MXT_TD60:
 		uart_base = MX2X_UART1_BASE_ADDR;
 		break;
+	case MACH_TYPE_MX28EVK:
+		uart_base = MX28_DUART_BASE_ADDR;
+		is_duart = 1;
+		break;
 	case MACH_TYPE_MX31LITE:
 	case MACH_TYPE_ARMADILLO5X0:
 	case MACH_TYPE_MX31MOBOARD:
-- 
1.7.1

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

* [PATCH 08/11] ARM: imx: Add clock support for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (6 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/clock-imx28.c       |  733 +++++++++++++++++++++++++++++++++
 arch/arm/mach-imx/regs-clkctrl-mx28.h |  662 +++++++++++++++++++++++++++++
 2 files changed, 1395 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/clock-imx28.c
 create mode 100644 arch/arm/mach-imx/regs-clkctrl-mx28.h

diff --git a/arch/arm/mach-imx/clock-imx28.c b/arch/arm/mach-imx/clock-imx28.c
new file mode 100644
index 0000000..104f95e
--- /dev/null
+++ b/arch/arm/mach-imx/clock-imx28.c
@@ -0,0 +1,733 @@
+/*
+ * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/mm.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx28.h"
+
+#define CLKCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR	MX28_IO_ADDRESS(MX28_DIGCTL_BASE_ADDR)
+
+static struct clk pll2_clk;
+static struct clk cpu_clk;
+static struct clk emi_clk;
+static struct clk saif0_clk;
+static struct clk saif1_clk;
+static struct clk clk32k_clk;
+
+static int _raw_clk_enable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg &= ~(1 << clk->enable_shift);
+		__raw_writel(reg, clk->enable_reg);
+	}
+
+	return 0;
+}
+
+static void _raw_clk_disable(struct clk *clk)
+{
+	u32 reg;
+
+	if (clk->enable_reg) {
+		reg = __raw_readl(clk->enable_reg);
+		reg |= 1 << clk->enable_shift;
+		__raw_writel(reg, clk->enable_reg);
+	}
+}
+
+/*
+ * ref_xtal_clk
+ */
+static unsigned long ref_xtal_clk_get_rate(struct clk *clk)
+{
+	return 24000000;
+}
+
+static struct clk ref_xtal_clk = {
+	.get_rate = ref_xtal_clk_get_rate,
+};
+
+/*
+ * pll_clk
+ */
+static unsigned long pll0_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll1_clk_get_rate(struct clk *clk)
+{
+	return 480000000;
+}
+
+static unsigned long pll2_clk_get_rate(struct clk *clk)
+{
+	return 50000000;
+}
+
+#define _CLK_ENABLE_PLL(name, r, g)					\
+static int name##_enable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	udelay(10);							\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+									\
+	return 0;							\
+}
+
+_CLK_ENABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_ENABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _CLK_DISABLE_PLL(name, r, g)					\
+static void name##_disable(struct clk *clk)				\
+{									\
+	__raw_writel(BM_CLKCTRL_##r##CTRL0_POWER,			\
+		     CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+	if (clk == &pll2_clk)						\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_SET);	\
+	else								\
+		__raw_writel(BM_CLKCTRL_##r##CTRL0_##g,			\
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_##r##CTRL0_CLR);	\
+									\
+}
+
+_CLK_DISABLE_PLL(pll0_clk, PLL0, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll1_clk, PLL1, EN_USB_CLKS)
+_CLK_DISABLE_PLL(pll2_clk, PLL2, CLKGATE)
+
+#define _DEFINE_CLOCK_PLL(name)						\
+	static struct clk name = {					\
+		.get_rate	= name##_get_rate,			\
+		.enable		= name##_enable,			\
+		.disable	= name##_disable,			\
+		.parent		= &ref_xtal_clk,			\
+	}
+
+_DEFINE_CLOCK_PLL(pll0_clk);
+_DEFINE_CLOCK_PLL(pll1_clk);
+_DEFINE_CLOCK_PLL(pll2_clk);
+
+/*
+ * ref_clk
+ */
+#define _CLK_GET_RATE_REF(name, sr, ss)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	unsigned long parent_rate;					\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##sr);		\
+	div = (reg >> BP_CLKCTRL_##sr##_##ss##FRAC) & 0x3f;		\
+	parent_rate = clk_get_rate(clk->parent);			\
+									\
+	return parent_rate * 18 / div;					\
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC0, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC0, EMI)
+_CLK_GET_RATE_REF(ref_io0_clk, FRAC0, IO0)
+_CLK_GET_RATE_REF(ref_io1_clk, FRAC0, IO1)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC1, PIX)
+_CLK_GET_RATE_REF(ref_gpmi_clk, FRAC1, GPMI)
+
+#define _DEFINE_CLOCK_REF(name, er, es)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_CLKGATE##es,	\
+		.get_rate	= name##_get_rate,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= &pll0_clk,				\
+	}
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC0, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC0, EMI);
+_DEFINE_CLOCK_REF(ref_io0_clk, FRAC0, IO0);
+_DEFINE_CLOCK_REF(ref_io1_clk, FRAC0, IO1);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC1, PIX);
+_DEFINE_CLOCK_REF(ref_gpmi_clk, FRAC1, GPMI);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+static unsigned long lradc_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 16;
+}
+
+static unsigned long rtc_clk_get_rate(struct clk *clk)
+{
+	/* ref_xtal_clk is implemented as the only parent */
+	return clk_get_rate(clk->parent) / 768;
+}
+
+static unsigned long clk32k_clk_get_rate(struct clk *clk)
+{
+	return clk->parent->get_rate(clk->parent) / 750;
+}
+
+static unsigned long spdif_clk_get_rate(struct clk *clk)
+{
+	return clk_get_rate(clk->parent) / 4;
+}
+
+#define _CLK_GET_RATE(name, rs)						\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	if (clk->parent == &ref_xtal_clk)				\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_XTAL) >>		\
+			BP_CLKCTRL_##rs##_DIV_XTAL;			\
+	else								\
+		div = (reg & BM_CLKCTRL_##rs##_DIV_##rs) >>		\
+			BP_CLKCTRL_##rs##_DIV_##rs;			\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	return clk_get_rate(clk->parent) / div;				\
+}
+
+_CLK_GET_RATE(cpu_clk, CPU)
+_CLK_GET_RATE(emi_clk, EMI)
+
+#define _CLK_GET_RATE1(name, rs)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	u32 reg, div;							\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	div = (reg & BM_CLKCTRL_##rs##_DIV) >> BP_CLKCTRL_##rs##_DIV;	\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	if (clk == &saif0_clk || clk == &saif1_clk)			\
+		return (clk_get_rate(clk->parent) >> 16 * div);		\
+	else								\
+		return clk_get_rate(clk->parent) / div;			\
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp0_clk, SSP0)
+_CLK_GET_RATE1(ssp1_clk, SSP1)
+_CLK_GET_RATE1(ssp2_clk, SSP2)
+_CLK_GET_RATE1(ssp3_clk, SSP3)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, DIS_LCDIF)
+_CLK_GET_RATE1(saif0_clk, SAIF0)
+_CLK_GET_RATE1(saif1_clk, SAIF1)
+_CLK_GET_RATE1(fec_clk, ENET)
+
+#define _CLK_GET_RATE_STUB(name)					\
+static unsigned long name##_get_rate(struct clk *clk)			\
+{									\
+	return clk_get_rate(clk->parent);				\
+}
+
+_CLK_GET_RATE_STUB(uart_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+_CLK_GET_RATE_STUB(can0_clk)
+_CLK_GET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_rate
+ */
+/* fool compiler */
+#define BM_CLKCTRL_CPU_DIV	0
+#define BP_CLKCTRL_CPU_DIV	0
+#define BM_CLKCTRL_CPU_BUSY	0
+
+#define _CLK_SET_RATE(name, dr, fr, fs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, bm_busy, div_max, d, f, div, frac;			\
+	unsigned long diff, parent_rate, calc_rate;			\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+	bm_busy = BM_CLKCTRL_##dr##_BUSY;				\
+									\
+	if (clk->parent == &ref_xtal_clk) {				\
+		div = DIV_ROUND_UP(parent_rate, rate);			\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_XTAL >>		\
+				BP_CLKCTRL_CPU_DIV_XTAL;		\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;		\
+		}							\
+		if (div == 0 || div > div_max)				\
+			return -EINVAL;					\
+	} else {							\
+		div = frac = 1;						\
+		diff = parent_rate;					\
+		if (clk == &cpu_clk) {					\
+			div_max = BM_CLKCTRL_CPU_DIV_CPU >>		\
+				BP_CLKCTRL_CPU_DIV_CPU;			\
+			bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;		\
+		}							\
+		for (d = 1; d <= div_max; d++) {			\
+			f = parent_rate * 18 / d / rate;		\
+			if ((parent_rate * 18 / d) % rate)		\
+				f++;					\
+			if (f < 18 || f > 35)				\
+				continue;				\
+									\
+			calc_rate = parent_rate * 18 / f / d;		\
+			if (calc_rate > rate)				\
+				continue;				\
+									\
+			if (rate - calc_rate < diff) {			\
+				frac = f;				\
+				div = d;				\
+				diff = rate - calc_rate;		\
+			}						\
+									\
+			if (diff == 0)					\
+				break;					\
+		}							\
+									\
+		if (diff == parent_rate)				\
+			return -EINVAL;					\
+									\
+		reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+		reg &= ~BM_CLKCTRL_##fr##_##fs##FRAC;			\
+		reg |= frac;						\
+		__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##fr);	\
+	}								\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	if (clk == &cpu_clk) {						\
+		reg &= ~BM_CLKCTRL_CPU_DIV_CPU;				\
+		reg |= div << BP_CLKCTRL_CPU_DIV_CPU;			\
+	} else {							\
+		reg &= ~BM_CLKCTRL_##dr##_DIV;				\
+		reg |= div << BP_CLKCTRL_##dr##_DIV;			\
+		if (reg | (1 << clk->enable_shift)) {			\
+			pr_err("%s: clock is gated\n", __func__);	\
+			return -EINVAL;					\
+		}							\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & bm_busy))			\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE(cpu_clk, CPU, FRAC0, CPU)
+_CLK_SET_RATE(ssp0_clk, SSP0, FRAC0, IO0)
+_CLK_SET_RATE(ssp1_clk, SSP1, FRAC0, IO0)
+_CLK_SET_RATE(ssp2_clk, SSP2, FRAC0, IO1)
+_CLK_SET_RATE(ssp3_clk, SSP3, FRAC0, IO1)
+_CLK_SET_RATE(lcdif_clk, DIS_LCDIF, FRAC1, PIX)
+_CLK_SET_RATE(gpmi_clk, GPMI, FRAC1, GPMI)
+
+#define _CLK_SET_RATE1(name, dr)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u32 reg, div_max, div;						\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;	\
+									\
+	div = DIV_ROUND_UP(parent_rate, rate);				\
+	if (div == 0 || div > div_max)					\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+	reg &= ~BM_CLKCTRL_##dr##_DIV;					\
+	reg |= div << BP_CLKCTRL_##dr##_DIV;				\
+	if (reg | (1 << clk->enable_shift)) {				\
+		pr_err("%s: clock is gated\n", __func__);		\
+		return -EINVAL;						\
+	}								\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##dr);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##dr) & BM_CLKCTRL_##dr##_BUSY))	\
+			break;						\
+	if (!i)	{							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE1(xbus_clk, XBUS)
+_CLK_SET_RATE1(fec_clk, ENET)
+
+/* saif clock uses 16 bits frac div */
+#define _CLK_SET_RATE_SAIF(name, rs)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	u16 div;							\
+	u32 reg;							\
+	u64 lrate;							\
+	unsigned long parent_rate;					\
+	int i;								\
+									\
+	parent_rate = clk_get_rate(clk->parent);			\
+	if (rate > parent_rate)						\
+		return -EINVAL;						\
+									\
+	lrate = (u64)rate << 16;					\
+	do_div(lrate, parent_rate);					\
+	div = (u16)lrate;						\
+									\
+	if (!div)							\
+		return -EINVAL;						\
+									\
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+	reg &= ~BM_CLKCTRL_##rs##_DIV;					\
+	reg |= div << BP_CLKCTRL_##rs##_DIV;				\
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_##rs);		\
+									\
+	for (i = 10000; i; i--)						\
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +			\
+			HW_CLKCTRL_##rs) & BM_CLKCTRL_##rs##_BUSY))	\
+			break;						\
+	if (!i) {							\
+		pr_err("%s: divider writing timeout\n", __func__);	\
+		return -ETIMEDOUT;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_RATE_SAIF(saif0_clk, SAIF0)
+_CLK_SET_RATE_SAIF(saif1_clk, SAIF1)
+
+#define _CLK_SET_RATE_STUB(name)					\
+static int name##_set_rate(struct clk *clk, unsigned long rate)		\
+{									\
+	return -EINVAL;							\
+}
+
+_CLK_SET_RATE_STUB(emi_clk)	
+_CLK_SET_RATE_STUB(uart_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(spdif_clk)
+_CLK_SET_RATE_STUB(clk32k_clk)
+_CLK_SET_RATE_STUB(can0_clk)
+_CLK_SET_RATE_STUB(can1_clk)
+
+/*
+ * clk_set_parent
+ */
+#define _CLK_SET_PARENT(name, bit)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent) {					\
+		__raw_writel(BM_CLKCTRL_CLKSEQ_BYPASS_##bit,		\
+			 HW_CLKCTRL_CLKSEQ_TOG);			\
+		clk->parent = parent;					\
+	}								\
+									\
+	return 0;							\
+}
+
+_CLK_SET_PARENT(cpu_clk, CPU)
+_CLK_SET_PARENT(emi_clk, EMI)
+_CLK_SET_PARENT(ssp0_clk, SSP0)
+_CLK_SET_PARENT(ssp1_clk, SSP1)
+_CLK_SET_PARENT(ssp2_clk, SSP2)
+_CLK_SET_PARENT(ssp3_clk, SSP3)
+_CLK_SET_PARENT(lcdif_clk, DIS_LCDIF)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(saif0_clk, SAIF0)
+_CLK_SET_PARENT(saif1_clk, SAIF1)
+
+#define _CLK_SET_PARENT_STUB(name)					\
+static int name##_set_parent(struct clk *clk, struct clk *parent)	\
+{									\
+	if (parent != clk->parent)					\
+		return -EINVAL;						\
+	else								\
+		return 0;						\
+}
+
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(uart_clk)
+_CLK_SET_PARENT_STUB(clk32k_clk)
+_CLK_SET_PARENT_STUB(spdif_clk)
+_CLK_SET_PARENT_STUB(fec_clk)
+_CLK_SET_PARENT_STUB(can0_clk)
+_CLK_SET_PARENT_STUB(can1_clk)
+
+/*
+ * clk definition
+ */
+static struct clk cpu_clk = {
+	.get_rate = cpu_clk_get_rate,
+	.set_rate = cpu_clk_set_rate,
+	.set_parent = cpu_clk_set_parent,
+	.parent = &ref_cpu_clk,
+};
+
+static struct clk hbus_clk = {
+	.get_rate = hbus_clk_get_rate,
+	.parent = &cpu_clk,
+};
+
+static struct clk xbus_clk = {
+	.get_rate = xbus_clk_get_rate,
+	.set_rate = xbus_clk_set_rate,
+	.parent = &ref_xtal_clk,
+};
+
+static struct clk lradc_clk = {
+	.get_rate = lradc_clk_get_rate,
+	.parent = &clk32k_clk,
+};
+
+static struct clk rtc_clk = {
+	.get_rate = rtc_clk_get_rate,
+	.parent = &ref_xtal_clk,
+};
+
+/* usb_clk is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb0_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 2,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll0_clk,
+};
+
+static struct clk usb1_clk = {
+	.enable_reg = DIGCTRL_BASE_ADDR,
+	.enable_shift = 16,
+	.enable = _raw_clk_enable,
+	.disable = _raw_clk_disable,
+	.parent = &pll1_clk,
+};
+
+#define _DEFINE_CLOCK(name, er, es, p)					\
+	static struct clk name = {					\
+		.enable_reg	= CLKCTRL_BASE_ADDR + HW_CLKCTRL_##er,	\
+		.enable_shift	= BP_CLKCTRL_##er##_##es,		\
+		.get_rate	= name##_get_rate,			\
+		.set_rate	= name##_set_rate,			\
+		.set_parent	= name##_set_parent,			\
+		.enable		= _raw_clk_enable,			\
+		.disable	= _raw_clk_disable,			\
+		.parent		= p,					\
+	}
+
+_DEFINE_CLOCK(emi_clk, EMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp0_clk, SSP0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp1_clk, SSP1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp2_clk, SSP2, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(ssp3_clk, SSP3, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, DIS_LCDIF, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif0_clk, SAIF0, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(saif1_clk, SAIF1, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(can0_clk, FLEXCAN, STOP_CAN0, &ref_xtal_clk);
+_DEFINE_CLOCK(can1_clk, FLEXCAN, STOP_CAN1, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(spdif_clk, SPDIF, CLKGATE, &pll0_clk);
+/* fec 1588 clock */
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &pll0_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+	{ \
+		.dev_id = d, \
+		.con_id = n, \
+		.clk = &c, \
+	},
+
+static struct clk_lookup lookups[] = {
+	_REGISTER_CLOCK("imx-duart.0", NULL, uart_clk)
+	_REGISTER_CLOCK("fec.0", NULL, fec_clk)
+
+	_REGISTER_CLOCK("hclk", NULL, hbus_clk)
+	_REGISTER_CLOCK("xclk", NULL, xbus_clk)
+	_REGISTER_CLOCK("can.0", NULL, can0_clk)
+	_REGISTER_CLOCK("can.1", NULL, can1_clk)
+	_REGISTER_CLOCK("usb.0", NULL, usb0_clk)
+	_REGISTER_CLOCK("usb.1", NULL, usb1_clk)
+	_REGISTER_CLOCK("rtc", NULL, rtc_clk)
+	_REGISTER_CLOCK("pwm", NULL, pwm_clk)
+	_REGISTER_CLOCK("lradc", NULL, lradc_clk)
+	_REGISTER_CLOCK("spdif", NULL, spdif_clk)
+};
+
+static int clk_misc_init(void)
+{
+	u32 reg;
+	int i;
+
+	/* Fix up parent per register setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CLKSEQ);
+	cpu_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_CPU) ?
+			&ref_xtal_clk : &ref_cpu_clk;
+	emi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_EMI) ?
+			&ref_xtal_clk : &ref_emi_clk;
+	ssp0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP0) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP1) ?
+			&ref_xtal_clk : &ref_io0_clk;
+	ssp2_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP2) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	ssp3_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP3) ?
+			&ref_xtal_clk : &ref_io1_clk;
+	lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF) ?
+			&ref_xtal_clk : &ref_pix_clk;
+	gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+			&ref_xtal_clk : &ref_gpmi_clk;
+	saif0_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0) ?
+			&ref_xtal_clk : &pll0_clk;
+	saif1_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1) ?
+			&ref_xtal_clk : &pll0_clk;
+
+	/* Use int div over frac when both are available */
+	__raw_writel(BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_CLR);
+	__raw_writel(BM_CLKCTRL_HBUS_DIV_FRAC_EN,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS_CLR);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+	reg &= ~BM_CLKCTRL_XBUS_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_XBUS);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+	reg &= ~BM_CLKCTRL_SSP0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+	reg &= ~BM_CLKCTRL_SSP1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP1);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+	reg &= ~BM_CLKCTRL_SSP2_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP2);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+	reg &= ~BM_CLKCTRL_SSP3_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP3);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+	reg &= ~BM_CLKCTRL_GPMI_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_GPMI);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+	reg &= ~BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_DIS_LCDIF);
+
+	/* SAIF has to use frac div for functional operation */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+	reg &= ~BM_CLKCTRL_SAIF0_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF0);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+	reg &= ~BM_CLKCTRL_SAIF1_DIV_FRAC_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SAIF1);
+
+	/*
+	 * Set safe hbus clock divider. A divider of 3 ensure that
+	 * the Vddd voltage required for the cpu clock is sufficiently
+	 * high for the hbus clock.
+	 */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+	reg &= BM_CLKCTRL_HBUS_DIV;
+	reg |= 3 << BP_CLKCTRL_HBUS_DIV;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_HBUS);
+
+	for (i = 10000; i; i--)
+		if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+			HW_CLKCTRL_HBUS) & BM_CLKCTRL_HBUS_ASM_BUSY))
+			break;
+	if (!i) {
+		pr_err("%s: divider writing timeout\n", __func__);
+		return -ETIMEDOUT;
+	}
+
+	/* Gate off cpu clock in WFI for power saving */
+	__raw_writel(BM_CLKCTRL_CPU_INTERRUPT_WAIT,
+			CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU_SET);
+
+	/* Extra fec clock setting */
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg &= ~BM_CLKCTRL_ENET_SLEEP;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+	reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
+	__raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
+
+	return 0;
+}
+
+int __init mx28_clocks_init(void)
+{
+	clk_misc_init();
+
+	clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+	mxc_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+			MX28_INT_TIMER0);
+
+	return 0;
+}
diff --git a/arch/arm/mach-imx/regs-clkctrl-mx28.h b/arch/arm/mach-imx/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..e2d84a8
--- /dev/null
+++ b/arch/arm/mach-imx/regs-clkctrl-mx28.h
@@ -0,0 +1,662 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.48
+ * Template revision: 26195
+ */
+
+#ifndef __ARCH_ARM___CLKCTRL_IMX28_H
+#define __ARCH_ARM___CLKCTRL_IMX28_H
+
+#define HW_CLKCTRL_PLL0CTRL0	(0x00000000)
+#define HW_CLKCTRL_PLL0CTRL0_SET	(0x00000004)
+#define HW_CLKCTRL_PLL0CTRL0_CLR	(0x00000008)
+#define HW_CLKCTRL_PLL0CTRL0_TOG	(0x0000000c)
+
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD6	30
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD6	0xC0000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD6(v) \
+		(((v) << 30) & BM_CLKCTRL_PLL0CTRL0_RSRVD6)
+#define BP_CLKCTRL_PLL0CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL0CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL0CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL0CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL0CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL0CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL0CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL0CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL0CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL0CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL0CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL0CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL0CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL0CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL0CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL0CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL0CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL0CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL0CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL0CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL0CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL0CTRL1	(0x00000010)
+
+#define BM_CLKCTRL_PLL0CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL0CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL0CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL0CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL0CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL0CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL0CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL0CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL1CTRL0	(0x00000020)
+#define HW_CLKCTRL_PLL1CTRL0_SET	(0x00000024)
+#define HW_CLKCTRL_PLL1CTRL0_CLR	(0x00000028)
+#define HW_CLKCTRL_PLL1CTRL0_TOG	(0x0000002c)
+
+#define BM_CLKCTRL_PLL1CTRL0_CLKGATEEMI	0x80000000
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD6	0x40000000
+#define BP_CLKCTRL_PLL1CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL1CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL1CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL1CTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD5	26
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD5	0x0C000000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD5(v)  \
+		(((v) << 26) & BM_CLKCTRL_PLL1CTRL0_RSRVD5)
+#define BP_CLKCTRL_PLL1CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL1CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL1CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL1CTRL0_CP_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_2   0x1
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__TIMES_05  0x2
+#define BV_CLKCTRL_PLL1CTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD4	22
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD4	0x00C00000
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD4(v)  \
+		(((v) << 22) & BM_CLKCTRL_PLL1CTRL0_RSRVD4)
+#define BP_CLKCTRL_PLL1CTRL0_DIV_SEL	20
+#define BM_CLKCTRL_PLL1CTRL0_DIV_SEL	0x00300000
+#define BF_CLKCTRL_PLL1CTRL0_DIV_SEL(v)  \
+		(((v) << 20) & BM_CLKCTRL_PLL1CTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__DEFAULT   0x0
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWER     0x1
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__LOWEST    0x2
+#define BV_CLKCTRL_PLL1CTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD3	0x00080000
+#define BM_CLKCTRL_PLL1CTRL0_EN_USB_CLKS	0x00040000
+#define BM_CLKCTRL_PLL1CTRL0_POWER	0x00020000
+#define BP_CLKCTRL_PLL1CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL1CTRL0_RSRVD1	0x0001FFFF
+#define BF_CLKCTRL_PLL1CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLL1CTRL1	(0x00000030)
+
+#define BM_CLKCTRL_PLL1CTRL1_LOCK	0x80000000
+#define BM_CLKCTRL_PLL1CTRL1_FORCE_LOCK	0x40000000
+#define BP_CLKCTRL_PLL1CTRL1_RSRVD1	16
+#define BM_CLKCTRL_PLL1CTRL1_RSRVD1	0x3FFF0000
+#define BF_CLKCTRL_PLL1CTRL1_RSRVD1(v)  \
+		(((v) << 16) & BM_CLKCTRL_PLL1CTRL1_RSRVD1)
+#define BP_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0
+#define BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT	0x0000FFFF
+#define BF_CLKCTRL_PLL1CTRL1_LOCK_COUNT(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL1CTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_PLL2CTRL0	(0x00000040)
+#define HW_CLKCTRL_PLL2CTRL0_SET	(0x00000044)
+#define HW_CLKCTRL_PLL2CTRL0_CLR	(0x00000048)
+#define HW_CLKCTRL_PLL2CTRL0_TOG	(0x0000004c)
+
+#define BM_CLKCTRL_PLL2CTRL0_CLKGATE	0x80000000
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD3	0x40000000
+#define BP_CLKCTRL_PLL2CTRL0_LFR_SEL	28
+#define BM_CLKCTRL_PLL2CTRL0_LFR_SEL	0x30000000
+#define BF_CLKCTRL_PLL2CTRL0_LFR_SEL(v)  \
+		(((v) << 28) & BM_CLKCTRL_PLL2CTRL0_LFR_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD2	0x08000000
+#define BM_CLKCTRL_PLL2CTRL0_HOLD_RING_OFF_B	0x04000000
+#define BP_CLKCTRL_PLL2CTRL0_CP_SEL	24
+#define BM_CLKCTRL_PLL2CTRL0_CP_SEL	0x03000000
+#define BF_CLKCTRL_PLL2CTRL0_CP_SEL(v)  \
+		(((v) << 24) & BM_CLKCTRL_PLL2CTRL0_CP_SEL)
+#define BM_CLKCTRL_PLL2CTRL0_POWER	0x00800000
+#define BP_CLKCTRL_PLL2CTRL0_RSRVD1	0
+#define BM_CLKCTRL_PLL2CTRL0_RSRVD1	0x007FFFFF
+#define BF_CLKCTRL_PLL2CTRL0_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_PLL2CTRL0_RSRVD1)
+
+#define HW_CLKCTRL_CPU	(0x00000050)
+#define HW_CLKCTRL_CPU_SET	(0x00000054)
+#define HW_CLKCTRL_CPU_CLR	(0x00000058)
+#define HW_CLKCTRL_CPU_TOG	(0x0000005c)
+
+#define BP_CLKCTRL_CPU_RSRVD5	30
+#define BM_CLKCTRL_CPU_RSRVD5	0xC0000000
+#define BF_CLKCTRL_CPU_RSRVD5(v) \
+		(((v) << 30) & BM_CLKCTRL_CPU_RSRVD5)
+#define BM_CLKCTRL_CPU_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_CPU_BUSY_REF_CPU	0x10000000
+#define BM_CLKCTRL_CPU_RSRVD4	0x08000000
+#define BM_CLKCTRL_CPU_DIV_XTAL_FRAC_EN	0x04000000
+#define BP_CLKCTRL_CPU_DIV_XTAL	16
+#define BM_CLKCTRL_CPU_DIV_XTAL	0x03FF0000
+#define BF_CLKCTRL_CPU_DIV_XTAL(v)  \
+		(((v) << 16) & BM_CLKCTRL_CPU_DIV_XTAL)
+#define BP_CLKCTRL_CPU_RSRVD3	13
+#define BM_CLKCTRL_CPU_RSRVD3	0x0000E000
+#define BF_CLKCTRL_CPU_RSRVD3(v)  \
+		(((v) << 13) & BM_CLKCTRL_CPU_RSRVD3)
+#define BM_CLKCTRL_CPU_INTERRUPT_WAIT	0x00001000
+#define BM_CLKCTRL_CPU_RSRVD2	0x00000800
+#define BM_CLKCTRL_CPU_DIV_CPU_FRAC_EN	0x00000400
+#define BP_CLKCTRL_CPU_RSRVD1	6
+#define BM_CLKCTRL_CPU_RSRVD1	0x000003C0
+#define BF_CLKCTRL_CPU_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_CPU_RSRVD1)
+#define BP_CLKCTRL_CPU_DIV_CPU	0
+#define BM_CLKCTRL_CPU_DIV_CPU	0x0000003F
+#define BF_CLKCTRL_CPU_DIV_CPU(v)  \
+		(((v) << 0) & BM_CLKCTRL_CPU_DIV_CPU)
+
+#define HW_CLKCTRL_HBUS	(0x00000060)
+#define HW_CLKCTRL_HBUS_SET	(0x00000064)
+#define HW_CLKCTRL_HBUS_CLR	(0x00000068)
+#define HW_CLKCTRL_HBUS_TOG	(0x0000006c)
+
+#define BM_CLKCTRL_HBUS_ASM_BUSY	0x80000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE	0x40000000
+#define BM_CLKCTRL_HBUS_PXP_AS_ENABLE	0x20000000
+#define BM_CLKCTRL_HBUS_RSRVD2	0x10000000
+#define BM_CLKCTRL_HBUS_ASM_EMIPORT_AS_ENABLE	0x08000000
+#define BM_CLKCTRL_HBUS_APBHDMA_AS_ENABLE	0x04000000
+#define BM_CLKCTRL_HBUS_APBXDMA_AS_ENABLE	0x02000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_JAM_AS_ENABLE	0x01000000
+#define BM_CLKCTRL_HBUS_TRAFFIC_AS_ENABLE	0x00800000
+#define BM_CLKCTRL_HBUS_CPU_DATA_AS_ENABLE	0x00400000
+#define BM_CLKCTRL_HBUS_CPU_INSTR_AS_ENABLE	0x00200000
+#define BM_CLKCTRL_HBUS_ASM_ENABLE	0x00100000
+#define BM_CLKCTRL_HBUS_AUTO_CLEAR_DIV_ENABLE	0x00080000
+#define BP_CLKCTRL_HBUS_SLOW_DIV	16
+#define BM_CLKCTRL_HBUS_SLOW_DIV	0x00070000
+#define BF_CLKCTRL_HBUS_SLOW_DIV(v)  \
+		(((v) << 16) & BM_CLKCTRL_HBUS_SLOW_DIV)
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY1  0x0
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY2  0x1
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY4  0x2
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY8  0x3
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY16 0x4
+#define BV_CLKCTRL_HBUS_SLOW_DIV__BY32 0x5
+#define BP_CLKCTRL_HBUS_RSRVD1	6
+#define BM_CLKCTRL_HBUS_RSRVD1	0x0000FFC0
+#define BF_CLKCTRL_HBUS_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_HBUS_RSRVD1)
+#define BM_CLKCTRL_HBUS_DIV_FRAC_EN	0x00000020
+#define BP_CLKCTRL_HBUS_DIV	0
+#define BM_CLKCTRL_HBUS_DIV	0x0000001F
+#define BF_CLKCTRL_HBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_HBUS_DIV)
+
+#define HW_CLKCTRL_XBUS	(0x00000070)
+
+#define BM_CLKCTRL_XBUS_BUSY	0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1	12
+#define BM_CLKCTRL_XBUS_RSRVD1	0x7FFFF000
+#define BF_CLKCTRL_XBUS_RSRVD1(v)  \
+		(((v) << 12) & BM_CLKCTRL_XBUS_RSRVD1)
+#define BM_CLKCTRL_XBUS_AUTO_CLEAR_DIV_ENABLE	0x00000800
+#define BM_CLKCTRL_XBUS_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_XBUS_DIV	0
+#define BM_CLKCTRL_XBUS_DIV	0x000003FF
+#define BF_CLKCTRL_XBUS_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_XBUS_DIV)
+
+#define HW_CLKCTRL_XTAL	(0x00000080)
+#define HW_CLKCTRL_XTAL_SET	(0x00000084)
+#define HW_CLKCTRL_XTAL_CLR	(0x00000088)
+#define HW_CLKCTRL_XTAL_TOG	(0x0000008c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE	31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE	0x80000000
+#define BM_CLKCTRL_XTAL_RSRVD3	0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE	29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE	0x20000000
+#define BP_CLKCTRL_XTAL_RSRVD2	27
+#define BM_CLKCTRL_XTAL_RSRVD2	0x18000000
+#define BF_CLKCTRL_XTAL_RSRVD2(v)  \
+		(((v) << 27) & BM_CLKCTRL_XTAL_RSRVD2)
+#define BP_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	26
+#define BM_CLKCTRL_XTAL_TIMROT_CLK32K_GATE	0x04000000
+#define BP_CLKCTRL_XTAL_RSRVD1	2
+#define BM_CLKCTRL_XTAL_RSRVD1	0x03FFFFFC
+#define BF_CLKCTRL_XTAL_RSRVD1(v)  \
+		(((v) << 2) & BM_CLKCTRL_XTAL_RSRVD1)
+#define BP_CLKCTRL_XTAL_DIV_UART	0
+#define BM_CLKCTRL_XTAL_DIV_UART	0x00000003
+#define BF_CLKCTRL_XTAL_DIV_UART(v)  \
+		(((v) << 0) & BM_CLKCTRL_XTAL_DIV_UART)
+
+#define HW_CLKCTRL_SSP0	(0x00000090)
+
+#define BP_CLKCTRL_SSP0_CLKGATE	31
+#define BM_CLKCTRL_SSP0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP0_BUSY	0x20000000
+#define BP_CLKCTRL_SSP0_RSRVD1	10
+#define BM_CLKCTRL_SSP0_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP0_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP0_RSRVD1)
+#define BM_CLKCTRL_SSP0_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP0_DIV	0
+#define BM_CLKCTRL_SSP0_DIV	0x000001FF
+#define BF_CLKCTRL_SSP0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP0_DIV)
+
+#define HW_CLKCTRL_SSP1	(0x000000a0)
+
+#define BP_CLKCTRL_SSP1_CLKGATE	31
+#define BM_CLKCTRL_SSP1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP1_BUSY	0x20000000
+#define BP_CLKCTRL_SSP1_RSRVD1	10
+#define BM_CLKCTRL_SSP1_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP1_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP1_RSRVD1)
+#define BM_CLKCTRL_SSP1_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP1_DIV	0
+#define BM_CLKCTRL_SSP1_DIV	0x000001FF
+#define BF_CLKCTRL_SSP1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP1_DIV)
+
+#define HW_CLKCTRL_SSP2	(0x000000b0)
+
+#define BP_CLKCTRL_SSP2_CLKGATE	31
+#define BM_CLKCTRL_SSP2_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP2_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP2_BUSY	0x20000000
+#define BP_CLKCTRL_SSP2_RSRVD1	10
+#define BM_CLKCTRL_SSP2_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP2_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP2_RSRVD1)
+#define BM_CLKCTRL_SSP2_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP2_DIV	0
+#define BM_CLKCTRL_SSP2_DIV	0x000001FF
+#define BF_CLKCTRL_SSP2_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP2_DIV)
+
+#define HW_CLKCTRL_SSP3	(0x000000c0)
+
+#define BP_CLKCTRL_SSP3_CLKGATE	31
+#define BM_CLKCTRL_SSP3_CLKGATE	0x80000000
+#define BM_CLKCTRL_SSP3_RSRVD2	0x40000000
+#define BM_CLKCTRL_SSP3_BUSY	0x20000000
+#define BP_CLKCTRL_SSP3_RSRVD1	10
+#define BM_CLKCTRL_SSP3_RSRVD1	0x1FFFFC00
+#define BF_CLKCTRL_SSP3_RSRVD1(v)  \
+		(((v) << 10) & BM_CLKCTRL_SSP3_RSRVD1)
+#define BM_CLKCTRL_SSP3_DIV_FRAC_EN	0x00000200
+#define BP_CLKCTRL_SSP3_DIV	0
+#define BM_CLKCTRL_SSP3_DIV	0x000001FF
+#define BF_CLKCTRL_SSP3_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SSP3_DIV)
+
+#define HW_CLKCTRL_GPMI	(0x000000d0)
+
+#define BP_CLKCTRL_GPMI_CLKGATE	31
+#define BM_CLKCTRL_GPMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_GPMI_RSRVD2	0x40000000
+#define BM_CLKCTRL_GPMI_BUSY	0x20000000
+#define BP_CLKCTRL_GPMI_RSRVD1	11
+#define BM_CLKCTRL_GPMI_RSRVD1	0x1FFFF800
+#define BF_CLKCTRL_GPMI_RSRVD1(v)  \
+		(((v) << 11) & BM_CLKCTRL_GPMI_RSRVD1)
+#define BM_CLKCTRL_GPMI_DIV_FRAC_EN	0x00000400
+#define BP_CLKCTRL_GPMI_DIV	0
+#define BM_CLKCTRL_GPMI_DIV	0x000003FF
+#define BF_CLKCTRL_GPMI_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_GPMI_DIV)
+
+#define HW_CLKCTRL_SPDIF	(0x000000e0)
+
+#define BP_CLKCTRL_SPDIF_CLKGATE	31
+#define BM_CLKCTRL_SPDIF_CLKGATE	0x80000000
+#define BP_CLKCTRL_SPDIF_RSRVD	0
+#define BM_CLKCTRL_SPDIF_RSRVD	0x7FFFFFFF
+#define BF_CLKCTRL_SPDIF_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_SPDIF_RSRVD)
+
+#define HW_CLKCTRL_EMI	(0x000000f0)
+
+#define BP_CLKCTRL_EMI_CLKGATE	31
+#define BM_CLKCTRL_EMI_CLKGATE	0x80000000
+#define BM_CLKCTRL_EMI_SYNC_MODE_EN	0x40000000
+#define BM_CLKCTRL_EMI_BUSY_REF_XTAL	0x20000000
+#define BM_CLKCTRL_EMI_BUSY_REF_EMI	0x10000000
+#define BM_CLKCTRL_EMI_BUSY_REF_CPU	0x08000000
+#define BM_CLKCTRL_EMI_BUSY_SYNC_MODE	0x04000000
+#define BP_CLKCTRL_EMI_RSRVD3	18
+#define BM_CLKCTRL_EMI_RSRVD3	0x03FC0000
+#define BF_CLKCTRL_EMI_RSRVD3(v)  \
+		(((v) << 18) & BM_CLKCTRL_EMI_RSRVD3)
+#define BM_CLKCTRL_EMI_BUSY_DCC_RESYNC	0x00020000
+#define BM_CLKCTRL_EMI_DCC_RESYNC_ENABLE	0x00010000
+#define BP_CLKCTRL_EMI_RSRVD2	12
+#define BM_CLKCTRL_EMI_RSRVD2	0x0000F000
+#define BF_CLKCTRL_EMI_RSRVD2(v)  \
+		(((v) << 12) & BM_CLKCTRL_EMI_RSRVD2)
+#define BP_CLKCTRL_EMI_DIV_XTAL	8
+#define BM_CLKCTRL_EMI_DIV_XTAL	0x00000F00
+#define BF_CLKCTRL_EMI_DIV_XTAL(v)  \
+		(((v) << 8) & BM_CLKCTRL_EMI_DIV_XTAL)
+#define BP_CLKCTRL_EMI_RSRVD1	6
+#define BM_CLKCTRL_EMI_RSRVD1	0x000000C0
+#define BF_CLKCTRL_EMI_RSRVD1(v)  \
+		(((v) << 6) & BM_CLKCTRL_EMI_RSRVD1)
+#define BP_CLKCTRL_EMI_DIV_EMI	0
+#define BM_CLKCTRL_EMI_DIV_EMI	0x0000003F
+#define BF_CLKCTRL_EMI_DIV_EMI(v)  \
+		(((v) << 0) & BM_CLKCTRL_EMI_DIV_EMI)
+
+#define HW_CLKCTRL_SAIF0	(0x00000100)
+
+#define BP_CLKCTRL_SAIF0_CLKGATE	31
+#define BM_CLKCTRL_SAIF0_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF0_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF0_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF0_RSRVD1	17
+#define BM_CLKCTRL_SAIF0_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF0_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF0_RSRVD1)
+#define BM_CLKCTRL_SAIF0_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF0_DIV	0
+#define BM_CLKCTRL_SAIF0_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF0_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF0_DIV)
+
+#define HW_CLKCTRL_SAIF1	(0x00000110)
+
+#define BP_CLKCTRL_SAIF1_CLKGATE	31
+#define BM_CLKCTRL_SAIF1_CLKGATE	0x80000000
+#define BM_CLKCTRL_SAIF1_RSRVD2	0x40000000
+#define BM_CLKCTRL_SAIF1_BUSY	0x20000000
+#define BP_CLKCTRL_SAIF1_RSRVD1	17
+#define BM_CLKCTRL_SAIF1_RSRVD1	0x1FFE0000
+#define BF_CLKCTRL_SAIF1_RSRVD1(v)  \
+		(((v) << 17) & BM_CLKCTRL_SAIF1_RSRVD1)
+#define BM_CLKCTRL_SAIF1_DIV_FRAC_EN	0x00010000
+#define BP_CLKCTRL_SAIF1_DIV	0
+#define BM_CLKCTRL_SAIF1_DIV	0x0000FFFF
+#define BF_CLKCTRL_SAIF1_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_SAIF1_DIV)
+
+#define HW_CLKCTRL_DIS_LCDIF	(0x00000120)
+
+#define BP_CLKCTRL_DIS_LCDIF_CLKGATE	31
+#define BM_CLKCTRL_DIS_LCDIF_CLKGATE	0x80000000
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD2	0x40000000
+#define BM_CLKCTRL_DIS_LCDIF_BUSY	0x20000000
+#define BP_CLKCTRL_DIS_LCDIF_RSRVD1	14
+#define BM_CLKCTRL_DIS_LCDIF_RSRVD1	0x1FFFC000
+#define BF_CLKCTRL_DIS_LCDIF_RSRVD1(v)  \
+		(((v) << 14) & BM_CLKCTRL_DIS_LCDIF_RSRVD1)
+#define BM_CLKCTRL_DIS_LCDIF_DIV_FRAC_EN	0x00002000
+#define BP_CLKCTRL_DIS_LCDIF_DIV	0
+#define BM_CLKCTRL_DIS_LCDIF_DIV	0x00001FFF
+#define BF_CLKCTRL_DIS_LCDIF_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_DIS_LCDIF_DIV)
+
+#define HW_CLKCTRL_ETM	(0x00000130)
+
+#define BM_CLKCTRL_ETM_CLKGATE	0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2	0x40000000
+#define BM_CLKCTRL_ETM_BUSY	0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1	8
+#define BM_CLKCTRL_ETM_RSRVD1	0x1FFFFF00
+#define BF_CLKCTRL_ETM_RSRVD1(v)  \
+		(((v) << 8) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN	0x00000080
+#define BP_CLKCTRL_ETM_DIV	0
+#define BM_CLKCTRL_ETM_DIV	0x0000007F
+#define BF_CLKCTRL_ETM_DIV(v)  \
+		(((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_ENET	(0x00000140)
+
+#define BM_CLKCTRL_ENET_SLEEP	0x80000000
+#define BP_CLKCTRL_ENET_DISABLE	30
+#define BM_CLKCTRL_ENET_DISABLE	0x40000000
+#define BM_CLKCTRL_ENET_STATUS	0x20000000
+#define BM_CLKCTRL_ENET_RSRVD1	0x10000000
+#define BM_CLKCTRL_ENET_BUSY_TIME	0x08000000
+#define BP_CLKCTRL_ENET_DIV_TIME	21
+#define BM_CLKCTRL_ENET_DIV_TIME	0x07E00000
+#define BF_CLKCTRL_ENET_DIV_TIME(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV_TIME)
+#define BM_CLKCTRL_ENET_BUSY	0x08000000
+#define BP_CLKCTRL_ENET_DIV	21
+#define BM_CLKCTRL_ENET_DIV	0x07E00000
+#define BF_CLKCTRL_ENET_DIV(v)  \
+		(((v) << 21) & BM_CLKCTRL_ENET_DIV)
+#define BP_CLKCTRL_ENET_TIME_SEL	19
+#define BM_CLKCTRL_ENET_TIME_SEL	0x00180000
+#define BF_CLKCTRL_ENET_TIME_SEL(v)  \
+		(((v) << 19) & BM_CLKCTRL_ENET_TIME_SEL)
+#define BV_CLKCTRL_ENET_TIME_SEL__XTAL      0x0
+#define BV_CLKCTRL_ENET_TIME_SEL__PLL       0x1
+#define BV_CLKCTRL_ENET_TIME_SEL__RMII_CLK  0x2
+#define BV_CLKCTRL_ENET_TIME_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_ENET_CLK_OUT_EN	0x00040000
+#define BM_CLKCTRL_ENET_RESET_BY_SW_CHIP	0x00020000
+#define BM_CLKCTRL_ENET_RESET_BY_SW	0x00010000
+#define BP_CLKCTRL_ENET_RSRVD0	0
+#define BM_CLKCTRL_ENET_RSRVD0	0x0000FFFF
+#define BF_CLKCTRL_ENET_RSRVD0(v)  \
+		(((v) << 0) & BM_CLKCTRL_ENET_RSRVD0)
+
+#define HW_CLKCTRL_HSADC	(0x00000150)
+
+#define BM_CLKCTRL_HSADC_RSRVD2	0x80000000
+#define BM_CLKCTRL_HSADC_RESETB	0x40000000
+#define BP_CLKCTRL_HSADC_FREQDIV	28
+#define BM_CLKCTRL_HSADC_FREQDIV	0x30000000
+#define BF_CLKCTRL_HSADC_FREQDIV(v)  \
+		(((v) << 28) & BM_CLKCTRL_HSADC_FREQDIV)
+#define BP_CLKCTRL_HSADC_RSRVD1	0
+#define BM_CLKCTRL_HSADC_RSRVD1	0x0FFFFFFF
+#define BF_CLKCTRL_HSADC_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_HSADC_RSRVD1)
+
+#define HW_CLKCTRL_FLEXCAN	(0x00000160)
+
+#define BM_CLKCTRL_FLEXCAN_RSRVD2	0x80000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN0	30
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN0	0x40000000
+#define BM_CLKCTRL_FLEXCAN_CAN0_STATUS	0x20000000
+#define BP_CLKCTRL_FLEXCAN_STOP_CAN1	28
+#define BM_CLKCTRL_FLEXCAN_STOP_CAN1	0x10000000
+#define BM_CLKCTRL_FLEXCAN_CAN1_STATUS	0x08000000
+#define BP_CLKCTRL_FLEXCAN_RSRVD1	0
+#define BM_CLKCTRL_FLEXCAN_RSRVD1	0x07FFFFFF
+#define BF_CLKCTRL_FLEXCAN_RSRVD1(v)  \
+		(((v) << 0) & BM_CLKCTRL_FLEXCAN_RSRVD1)
+
+#define HW_CLKCTRL_FRAC0	(0x000001b0)
+#define HW_CLKCTRL_FRAC0_SET	(0x000001b4)
+#define HW_CLKCTRL_FRAC0_CLR	(0x000001b8)
+#define HW_CLKCTRL_FRAC0_TOG	(0x000001bc)
+
+#define BP_CLKCTRL_FRAC0_CLKGATEIO0	31
+#define BM_CLKCTRL_FRAC0_CLKGATEIO0	0x80000000
+#define BM_CLKCTRL_FRAC0_IO0_STABLE	0x40000000
+#define BP_CLKCTRL_FRAC0_IO0FRAC	24
+#define BM_CLKCTRL_FRAC0_IO0FRAC	0x3F000000
+#define BF_CLKCTRL_FRAC0_IO0FRAC(v)  \
+		(((v) << 24) & BM_CLKCTRL_FRAC0_IO0FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEIO1	23
+#define BM_CLKCTRL_FRAC0_CLKGATEIO1	0x00800000
+#define BM_CLKCTRL_FRAC0_IO1_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC0_IO1FRAC	16
+#define BM_CLKCTRL_FRAC0_IO1FRAC	0x003F0000
+#define BF_CLKCTRL_FRAC0_IO1FRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC0_IO1FRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATEEMI	15
+#define BM_CLKCTRL_FRAC0_CLKGATEEMI	0x00008000
+#define BM_CLKCTRL_FRAC0_EMI_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC0_EMIFRAC	8
+#define BM_CLKCTRL_FRAC0_EMIFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC0_EMIFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC0_EMIFRAC)
+#define BP_CLKCTRL_FRAC0_CLKGATECPU	7
+#define BM_CLKCTRL_FRAC0_CLKGATECPU	0x00000080
+#define BM_CLKCTRL_FRAC0_CPU_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC0_CPUFRAC	0
+#define BM_CLKCTRL_FRAC0_CPUFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC0_CPUFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC0_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1	(0x000001c0)
+#define HW_CLKCTRL_FRAC1_SET	(0x000001c4)
+#define HW_CLKCTRL_FRAC1_CLR	(0x000001c8)
+#define HW_CLKCTRL_FRAC1_TOG	(0x000001cc)
+
+#define BP_CLKCTRL_FRAC1_RSRVD2	24
+#define BM_CLKCTRL_FRAC1_RSRVD2	0xFF000000
+#define BF_CLKCTRL_FRAC1_RSRVD2(v) \
+		(((v) << 24) & BM_CLKCTRL_FRAC1_RSRVD2)
+#define BP_CLKCTRL_FRAC1_CLKGATEGPMI	23
+#define BM_CLKCTRL_FRAC1_CLKGATEGPMI	0x00800000
+#define BM_CLKCTRL_FRAC1_GPMI_STABLE	0x00400000
+#define BP_CLKCTRL_FRAC1_GPMIFRAC	16
+#define BM_CLKCTRL_FRAC1_GPMIFRAC	0x003F0000
+#define BF_CLKCTRL_FRAC1_GPMIFRAC(v)  \
+		(((v) << 16) & BM_CLKCTRL_FRAC1_GPMIFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEHSADC	15
+#define BM_CLKCTRL_FRAC1_CLKGATEHSADC	0x00008000
+#define BM_CLKCTRL_FRAC1_HSADC_STABLE	0x00004000
+#define BP_CLKCTRL_FRAC1_HSADCFRAC	8
+#define BM_CLKCTRL_FRAC1_HSADCFRAC	0x00003F00
+#define BF_CLKCTRL_FRAC1_HSADCFRAC(v)  \
+		(((v) << 8) & BM_CLKCTRL_FRAC1_HSADCFRAC)
+#define BP_CLKCTRL_FRAC1_CLKGATEPIX	7
+#define BM_CLKCTRL_FRAC1_CLKGATEPIX	0x00000080
+#define BM_CLKCTRL_FRAC1_PIX_STABLE	0x00000040
+#define BP_CLKCTRL_FRAC1_PIXFRAC	0
+#define BM_CLKCTRL_FRAC1_PIXFRAC	0x0000003F
+#define BF_CLKCTRL_FRAC1_PIXFRAC(v)  \
+		(((v) << 0) & BM_CLKCTRL_FRAC1_PIXFRAC)
+
+#define HW_CLKCTRL_CLKSEQ	(0x000001d0)
+#define HW_CLKCTRL_CLKSEQ_SET	(0x000001d4)
+#define HW_CLKCTRL_CLKSEQ_CLR	(0x000001d8)
+#define HW_CLKCTRL_CLKSEQ_TOG	(0x000001dc)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD0	19
+#define BM_CLKCTRL_CLKSEQ_RSRVD0	0xFFF80000
+#define BF_CLKCTRL_CLKSEQ_RSRVD0(v) \
+		(((v) << 19) & BM_CLKCTRL_CLKSEQ_RSRVD0)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU	0x00040000
+#define BP_CLKCTRL_CLKSEQ_RSRVD1	15
+#define BM_CLKCTRL_CLKSEQ_RSRVD1	0x00038000
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v)  \
+		(((v) << 15) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF	0x00004000
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__BYPASS 0x1
+#define BV_CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF__PFD    0x0
+#define BP_CLKCTRL_CLKSEQ_RSRVD2	9
+#define BM_CLKCTRL_CLKSEQ_RSRVD2	0x00003E00
+#define BF_CLKCTRL_CLKSEQ_RSRVD2(v)  \
+		(((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD2)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM	0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI	0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP3	0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP2	0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP1	0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP0	0x00000008
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI	0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF1	0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF0	0x00000001
+
+#define HW_CLKCTRL_RESET	(0x000001e0)
+
+#define BP_CLKCTRL_RESET_RSRVD	6
+#define BM_CLKCTRL_RESET_RSRVD	0xFFFFFFC0
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+		(((v) << 6) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_WDOG_POR_DISABLE	0x00000020
+#define BM_CLKCTRL_RESET_EXTERNAL_RESET_ENABLE	0x00000010
+#define BM_CLKCTRL_RESET_THERMAL_RESET_ENABLE	0x00000008
+#define BM_CLKCTRL_RESET_THERMAL_RESET_DEFAULT	0x00000004
+#define BM_CLKCTRL_RESET_CHIP	0x00000002
+#define BM_CLKCTRL_RESET_DIG	0x00000001
+
+#define HW_CLKCTRL_STATUS	(0x000001f0)
+
+#define BP_CLKCTRL_STATUS_CPU_LIMIT	30
+#define BM_CLKCTRL_STATUS_CPU_LIMIT	0xC0000000
+#define BF_CLKCTRL_STATUS_CPU_LIMIT(v) \
+		(((v) << 30) & BM_CLKCTRL_STATUS_CPU_LIMIT)
+#define BP_CLKCTRL_STATUS_RSRVD	0
+#define BM_CLKCTRL_STATUS_RSRVD	0x3FFFFFFF
+#define BF_CLKCTRL_STATUS_RSRVD(v)  \
+		(((v) << 0) & BM_CLKCTRL_STATUS_RSRVD)
+
+#define HW_CLKCTRL_VERSION	(0x00000200)
+
+#define BP_CLKCTRL_VERSION_MAJOR	24
+#define BM_CLKCTRL_VERSION_MAJOR	0xFF000000
+#define BF_CLKCTRL_VERSION_MAJOR(v) \
+		(((v) << 24) & BM_CLKCTRL_VERSION_MAJOR)
+#define BP_CLKCTRL_VERSION_MINOR	16
+#define BM_CLKCTRL_VERSION_MINOR	0x00FF0000
+#define BF_CLKCTRL_VERSION_MINOR(v)  \
+		(((v) << 16) & BM_CLKCTRL_VERSION_MINOR)
+#define BP_CLKCTRL_VERSION_STEP	0
+#define BM_CLKCTRL_VERSION_STEP	0x0000FFFF
+#define BF_CLKCTRL_VERSION_STEP(v)  \
+		(((v) << 0) & BM_CLKCTRL_VERSION_STEP)
+#endif /* __ARCH_ARM___CLKCTRL_IMX28_H */
-- 
1.7.1

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

* [PATCH 09/11] ARM: imx: Add memory map support for i.MX28
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (7 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/mm-imx28.c |   50 ++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 50 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/mach-imx/mm-imx28.c

diff --git a/arch/arm/mach-imx/mm-imx28.c b/arch/arm/mach-imx/mm-imx28.c
new file mode 100644
index 0000000..358f2d2
--- /dev/null
+++ b/arch/arm/mach-imx/mm-imx28.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License.  You may obtain a copy of the GNU General Public License
+ * 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-pinctrl.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+	imx_map_entry(MX28, OCRAM, MT_DEVICE),
+	imx_map_entry(MX28, IO, 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 mx28_map_io(void)
+{
+	mxc_set_cpu_type(MXC_CPU_MX28);
+	mxc_iomux_pinctrl_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+	mxc_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+	iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+int imx28_register_gpios(void);
+
+void __init mx28_init_irq(void)
+{
+	icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+	imx28_register_gpios();
+}
-- 
1.7.1

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

* [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (8 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 16:54   ` Uwe Kleine-König
  2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
  2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

It adds machine mx28evk with initial duart and fec
device registration.

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/devices-imx28.h               |   20 ++++
 arch/arm/mach-imx/devices.c                     |   27 ++++++-
 arch/arm/mach-imx/mach-mx28evk.c                |  109 +++++++++++++++++++++++
 arch/arm/plat-mxc/devices/platform-duart.c      |   42 +++++++++
 arch/arm/plat-mxc/devices/platform-fec.c        |    5 +
 arch/arm/plat-mxc/include/mach/common.h         |    5 +
 arch/arm/plat-mxc/include/mach/devices-common.h |   11 +++
 7 files changed, 218 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/mach-imx/devices-imx28.h
 create mode 100644 arch/arm/mach-imx/mach-mx28evk.c
 create mode 100644 arch/arm/plat-mxc/devices/platform-duart.c

diff --git a/arch/arm/mach-imx/devices-imx28.h b/arch/arm/mach-imx/devices-imx28.h
new file mode 100644
index 0000000..f35c910
--- /dev/null
+++ b/arch/arm/mach-imx/devices-imx28.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+extern const struct imx_duart_data imx28_duart_data __initconst;
+#define imx28_add_duart()	\
+	imx_add_duart(&imx28_duart_data)
+
+extern const struct imx_fec_data imx28_fec_data __initconst;
+#define imx28_add_fec(pdata)	\
+	imx_add_fec(&imx28_fec_data, pdata)
diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
index e69e46e..946db32 100644
--- a/arch/arm/mach-imx/devices.c
+++ b/arch/arm/mach-imx/devices.c
@@ -9,7 +9,7 @@
  * licensed "as is" without any warranty of any kind, whether express
  * or implied.
  *
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
  * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
  * Copyright 2008 Sascha Hauer, kernel at pengutronix.de
  * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
@@ -551,3 +551,28 @@ struct platform_device imx_kpp_device = {
 };
 
 #endif
+
+#ifdef CONFIG_ARCH_MX28
+/* gpio */
+#define DEFINE_MXC_PINCTRL_GPIO_PORT(n)					\
+	{								\
+		.chip.label = "gpio-" #n,				\
+		.irq = MX28_INT_GPIO##n,				\
+		.base = MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR),	\
+		.virtual_irq_start = MXC_GPIO_IRQ_START + n * 32,	\
+	}
+
+static struct mxc_gpio_port imx28_gpio_ports[] = {
+	DEFINE_MXC_PINCTRL_GPIO_PORT(0),
+	DEFINE_MXC_PINCTRL_GPIO_PORT(1),
+	DEFINE_MXC_PINCTRL_GPIO_PORT(2),
+	DEFINE_MXC_PINCTRL_GPIO_PORT(3),
+	DEFINE_MXC_PINCTRL_GPIO_PORT(4),
+};
+
+int __init imx28_register_gpios(void)
+{
+	return mxc_gpio_init(imx28_gpio_ports,
+			ARRAY_SIZE(imx28_gpio_ports));
+}
+#endif
diff --git a/arch/arm/mach-imx/mach-mx28evk.c b/arch/arm/mach-imx/mach-mx28evk.c
new file mode 100644
index 0000000..d5dd940
--- /dev/null
+++ b/arch/arm/mach-imx/mach-mx28evk.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/gpio.h>
+#include <linux/irq.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-imx28.h"
+#include "devices.h"
+
+#define MX28EVK_FEC_PHY_POWER	(2*32 + 15)	/* GPIO_2_15 */
+#define MX28EVK_FEC_PHY_RESET	(4*32 + 13)	/* GPIO_4_13 */
+
+static iomux_pinctrl_cfg_t mx28evk_pads[] = {
+	/* DUART */
+	MX28_PAD_PWM0__DUART_RX,
+	MX28_PAD_PWM1__DUART_TX,
+
+	/* FEC */
+	MX28_PAD_ENET0_MDC__ENET0_MDC,
+	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
+	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
+	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
+	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
+	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
+	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
+	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
+	MX28_PAD_ENET_CLK__ENET_CLK,
+	/* PHY power line */
+	MX28_PAD_SSP1_DATA3__GPIO_2_15,
+	/* PHY reset line */
+	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
+};
+
+/* FEC */
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+        .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static inline void mx28evk_fec_reset(void)
+{
+	int ret;
+
+	/* Power up FEC PHY */
+	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+	if (ret) {
+		pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
+		return;
+	}
+	gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+
+	/* Reset FEC PHY */
+	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+	if (ret) {
+		pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
+		return;
+	}
+	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+	mdelay(1);
+	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static void __init mx28evk_init(void)
+{
+	mxc_iomux_pinctrl_setup_multiple_pads(mx28evk_pads,
+						ARRAY_SIZE(mx28evk_pads));
+	imx28_add_duart();
+
+	mx28evk_fec_reset();
+	imx28_add_fec(&mx28_fec_pdata);
+}
+
+static void __init mx28evk_timer_init(void)
+{
+	mx28_clocks_init();
+}
+
+static struct sys_timer mx28evk_timer = {
+	.init	= mx28evk_timer_init,
+};
+
+MACHINE_START(MX28EVK, "Freescale MX28 EVK")
+	/* Maintainer: Freescale Semiconductor, Inc. */
+	.boot_params    = MX28_PHYS_OFFSET + 0x100,
+	.map_io         = mx28_map_io,
+	.init_irq       = mx28_init_irq,
+	.init_machine   = mx28evk_init,
+	.timer          = &mx28evk_timer,
+MACHINE_END
diff --git a/arch/arm/plat-mxc/devices/platform-duart.c b/arch/arm/plat-mxc/devices/platform-duart.c
new file mode 100644
index 0000000..2dbf199
--- /dev/null
+++ b/arch/arm/plat-mxc/devices/platform-duart.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License version 2 as published by the
+ * Free Software Foundation.
+ */
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define imx_duart_data_entry_single(soc)				\
+	{								\
+		.iobase = soc ## _DUART_BASE_ADDR,			\
+		.irq = soc ## _INT_DUART,				\
+	}
+
+#ifdef CONFIG_ARCH_MX28
+const struct imx_duart_data imx28_duart_data __initconst =
+	imx_duart_data_entry_single(MX28);
+#endif
+
+struct platform_device *__init imx_add_duart(
+		const struct imx_duart_data *data)
+{
+	struct resource res[] = {
+		{
+			.start = data->iobase,
+			.end = data->iobase + SZ_8K - 1,
+			.flags = IORESOURCE_MEM,
+		}, {
+			.start = data->irq,
+			.end = data->irq,
+			.flags = IORESOURCE_IRQ,
+		},
+	};
+
+	return imx_add_platform_device("imx-duart", 0, res, ARRAY_SIZE(res),
+					NULL, 0);
+}
diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
index 11d087f..bd5a84b 100644
--- a/arch/arm/plat-mxc/devices/platform-fec.c
+++ b/arch/arm/plat-mxc/devices/platform-fec.c
@@ -26,6 +26,11 @@ const struct imx_fec_data imx27_fec_data __initconst =
 	imx_fec_data_entry_single(MX27);
 #endif /* ifdef CONFIG_SOC_IMX27 */
 
+#ifdef CONFIG_ARCH_MX28
+const struct imx_fec_data imx28_fec_data __initconst =
+	imx_fec_data_entry_single(MX28);
+#endif
+
 #ifdef CONFIG_ARCH_MX35
 const struct imx_fec_data imx35_fec_data __initconst =
 	imx_fec_data_entry_single(MX35);
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 05676fb..6a5dea7 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -18,16 +18,19 @@ extern void mx1_map_io(void);
 extern void mx21_map_io(void);
 extern void mx25_map_io(void);
 extern void mx27_map_io(void);
+extern void mx28_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 icoll_init_irq(void __iomem *);
 extern void mx1_init_irq(void);
 extern void mx21_init_irq(void);
 extern void mx25_init_irq(void);
 extern void mx27_init_irq(void);
+extern void mx28_init_irq(void);
 extern void mx31_init_irq(void);
 extern void mx35_init_irq(void);
 extern void mx51_init_irq(void);
@@ -38,6 +41,7 @@ extern int mx1_clocks_init(unsigned long fref);
 extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
 extern int mx25_clocks_init(void);
 extern int mx27_clocks_init(unsigned long fref);
+extern int mx28_clocks_init(void);
 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,
@@ -51,4 +55,5 @@ extern void mxc91231_power_off(void);
 extern void mxc91231_arch_reset(int, const char *);
 extern void mxc91231_prepare_idle(void);
 extern void mx51_efikamx_reset(void);
+extern int mxc_reset_block(void __iomem *);
 #endif
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8c6896f..501329d 100644
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -2,6 +2,8 @@
  * Copyright (C) 2009-2010 Pengutronix
  * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
  *
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
  * This program is free software; you can redistribute it and/or modify it under
  * the terms of the GNU General Public License version 2 as published by the
  * Free Software Foundation.
@@ -82,6 +84,15 @@ struct platform_device *__init imx_add_imx_uart_1irq(
 		const struct imx_imx_uart_1irq_data *data,
 		const struct imxuart_platform_data *pdata);
 
+struct imx_duart_data {
+	int id;
+	resource_size_t iobase;
+	resource_size_t iosize;
+	resource_size_t irq;
+};
+struct platform_device *__init imx_add_duart(
+		const struct imx_duart_data *data);
+
 #include <mach/mxc_nand.h>
 struct imx_mxc_nand_data {
 	/*
-- 
1.7.1

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

* [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (9 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
@ 2010-11-15 14:36 ` Shawn Guo
  2010-11-15 17:01   ` Uwe Kleine-König
  2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
  11 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-15 14:36 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
 arch/arm/mach-imx/Kconfig          |   20 ++++++++++++++++++++
 arch/arm/mach-imx/Makefile         |    4 ++++
 arch/arm/mach-imx/Makefile.boot    |    4 ++++
 arch/arm/plat-mxc/Kconfig          |   12 ++++++++++++
 arch/arm/plat-mxc/Makefile         |    4 +++-
 arch/arm/plat-mxc/devices/Kconfig  |    3 +++
 arch/arm/plat-mxc/devices/Makefile |    1 +
 7 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index d6e998f..8accd5c 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -199,3 +199,23 @@ config MACH_MXT_TD60
 	  includes specific configurations for the module and its peripherals.
 
 endif
+
+if ARCH_MX28
+
+config SOC_IMX28
+	select CPU_ARM926T
+	select ARCH_MXC_IOMUX_PINCTRL
+	select MXC_ICOLL
+	bool
+
+comment "MX28 platforms:"
+
+config MACH_MX28EVK
+	bool "MX28 EVK platform"
+	select IMX_HAVE_PLATFORM_DUART
+	help
+	  Include support for MX28 EVK platform. This includes specific
+	  configurations for the board and its peripherals.
+
+endif
+
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
index 5582692..3b12218 100644
--- a/arch/arm/mach-imx/Makefile
+++ b/arch/arm/mach-imx/Makefile
@@ -14,6 +14,8 @@ obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
 obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
 obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
 
+obj-$(CONFIG_ARCH_MX28) += clock-imx28.o mm-imx28.o
+
 # Support for CMOS sensor interface
 obj-$(CONFIG_MX1_VIDEO)	+= mx1-camera-fiq.o mx1-camera-fiq-ksym.o
 
@@ -32,3 +34,5 @@ obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
 obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
 obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
 obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
+
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
index 7988a85..fd451d0 100644
--- a/arch/arm/mach-imx/Makefile.boot
+++ b/arch/arm/mach-imx/Makefile.boot
@@ -9,3 +9,7 @@ initrd_phys-$(CONFIG_MACH_MX21)	:= 0xC0800000
 zreladdr-$(CONFIG_MACH_MX27)	:= 0xA0008000
 params_phys-$(CONFIG_MACH_MX27)	:= 0xA0000100
 initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
+
+zreladdr-$(CONFIG_ARCH_MX28)	:= 0x40008000
+params_phys-$(CONFIG_ARCH_MX28)	:= 0x40000100
+initrd_phys-$(CONFIG_ARCH_MX28)	:= 0x40800000
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index 680aeba..fd7ec19 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -25,6 +25,12 @@ config ARCH_MX25
 	help
 	  This enables support for systems based on the Freescale i.MX25 family
 
+config ARCH_MX28
+	bool "MX28-based"
+	select SOC_IMX28
+	help
+	  This enables support for systems based on the Freescale i.MX28 family
+
 config ARCH_MX3
 	bool "MX3-based"
 	select CPU_V6
@@ -68,6 +74,9 @@ config MXC_TZIC
 config MXC_AVIC
 	bool
 
+config MXC_ICOLL
+	bool
+
 config MXC_PWM
 	tristate "Enable PWM driver"
 	select HAVE_PWM
@@ -109,6 +118,9 @@ config IMX_HAVE_IOMUX_V1
 config ARCH_MXC_IOMUX_V3
 	bool
 
+config ARCH_MXC_IOMUX_PINCTRL
+	bool
+
 config ARCH_MXC_AUDMUX_V1
 	bool
 
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 0e12591..e194468 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -5,12 +5,14 @@
 # Common support
 obj-y := 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_MXC_AVIC) += avic.o
+obj-$(CONFIG_MXC_ICOLL) += icoll.o
 
 obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
 obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
+obj-$(CONFIG_ARCH_MXC_IOMUX_PINCTRL) += iomux-pinctrl.o
+
 obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
 obj-$(CONFIG_MXC_PWM)  += pwm.o
 obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
index 9aa6f3e..e8860d9 100644
--- a/arch/arm/plat-mxc/devices/Kconfig
+++ b/arch/arm/plat-mxc/devices/Kconfig
@@ -1,3 +1,6 @@
+config IMX_HAVE_PLATFORM_DUART
+	bool
+
 config IMX_HAVE_PLATFORM_ESDHC
 	bool
 
diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
index 45aefeb..11e2fcf 100644
--- a/arch/arm/plat-mxc/devices/Makefile
+++ b/arch/arm/plat-mxc/devices/Makefile
@@ -1,3 +1,4 @@
+obj-$(CONFIG_IMX_HAVE_PLATFORM_DUART) += platform-duart.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
 obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
-- 
1.7.1

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

* [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28
  2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
@ 2010-11-15 16:25   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:25 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:25PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/include/mach/hardware.h |    9 +-
>  arch/arm/plat-mxc/include/mach/irqs.h     |   11 +-
>  arch/arm/plat-mxc/include/mach/memory.h   |    5 +-
>  arch/arm/plat-mxc/include/mach/mx28.h     |  232 +++++++++++++++++++++++++++++
>  arch/arm/plat-mxc/include/mach/mxc.h      |   14 ++
>  5 files changed, 264 insertions(+), 7 deletions(-)
>  create mode 100644 arch/arm/plat-mxc/include/mach/mx28.h
> 
> diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
> index 2f59b63..499b14c 100644
> --- a/arch/arm/plat-mxc/include/mach/hardware.h
> +++ b/arch/arm/plat-mxc/include/mach/hardware.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>   *
>   * This program is free software; you can redistribute it and/or
> @@ -63,6 +63,9 @@
>   *	AIPI	0x10000000+0x100000	->	0xf4400000+0x100000
>   *	SAHB1	0x80000000+0x100000	->	0xf4000000+0x100000
>   *	X_MEMC	0xd8000000+0x100000	->	0xf5c00000+0x100000
> + * mx28:
> + *	OCRAM	0x00000000+0x020000	->	0xf4000000+0x020000
> + *	IO	0x80000000+0x100000	->	0xf4400000+0x100000
>   * mx31:
>   *	AIPS1	0x43f00000+0x100000	->	0xf5300000+0x100000
>   *	AIPS2	0x53f00000+0x100000	->	0xf5700000+0x100000
> @@ -127,6 +130,10 @@
>  # include <mach/mx25.h>
>  #endif
>  
> +#ifdef CONFIG_ARCH_MX28
> +# include <mach/mx28.h>
> +#endif
> +
>  #ifdef CONFIG_ARCH_MXC91231
>  # include <mach/mxc91231.h>
>  #endif
> diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
> index 86781f7..2f810c5 100644
> --- a/arch/arm/plat-mxc/include/mach/irqs.h
> +++ b/arch/arm/plat-mxc/include/mach/irqs.h
> @@ -1,5 +1,5 @@
>  /*
> - *  Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + *  Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   */
>  
>  /*
> @@ -12,12 +12,13 @@
>  #define __ASM_ARCH_MXC_IRQS_H__
>  
>  /*
> - * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
> + * SoCs with AVIC interrupt controller have 64 IRQs,
> + * those with TZIC and ICOLL have 128.
>   */
> -#ifdef CONFIG_MXC_TZIC
> -#define MXC_INTERNAL_IRQS	128
> -#else
> +#ifdef CONFIG_MXC_AVIC
>  #define MXC_INTERNAL_IRQS	64
> +#else
> +#define MXC_INTERNAL_IRQS	128
>  #endif
I like the more explicit approach that was used before.  When using
#elif it doesn't look that ugly.

>  #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
> diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
> index 564ec9d..af090e3 100644
> --- a/arch/arm/plat-mxc/include/mach/memory.h
> +++ b/arch/arm/plat-mxc/include/mach/memory.h
> @@ -1,5 +1,5 @@
>  /*
> - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
INAL but I wonder if your change to the file is worth 3 years of
copyright assignment.  *I* don't care much though.  The same applies to
some other files touched by this patch.

>   */
>  
>  /*
> @@ -15,6 +15,7 @@
>  #define MX21_PHYS_OFFSET	UL(0xc0000000)
>  #define MX25_PHYS_OFFSET	UL(0x80000000)
>  #define MX27_PHYS_OFFSET	UL(0xa0000000)
> +#define MX28_PHYS_OFFSET	UL(0x40000000)
>  #define MX3x_PHYS_OFFSET	UL(0x80000000)
>  #define MX51_PHYS_OFFSET	UL(0x90000000)
>  #define MXC91231_PHYS_OFFSET	UL(0x90000000)
> @@ -28,6 +29,8 @@
>  #  define PHYS_OFFSET		MX25_PHYS_OFFSET
>  # elif defined CONFIG_MACH_MX27
>  #  define PHYS_OFFSET		MX27_PHYS_OFFSET
> +# elif defined CONFIG_ARCH_MX28
> +#  define PHYS_OFFSET		MX28_PHYS_OFFSET
>  # elif defined CONFIG_ARCH_MX3
>  #  define PHYS_OFFSET		MX3x_PHYS_OFFSET
>  # elif defined CONFIG_ARCH_MXC91231
> diff --git a/arch/arm/plat-mxc/include/mach/mx28.h b/arch/arm/plat-mxc/include/mach/mx28.h
> new file mode 100644
> index 0000000..6f73888
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/mx28.h
> @@ -0,0 +1,232 @@
> +/*
> + * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_MX28_H__
> +#define __MACH_MX28_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
Is this needed?

> +
> +#define SET_ADDR			0x4
> +#define CLR_ADDR			0x8
> +#define TOG_ADDR			0xc
Please don't pollute the namespace but use MX28 prefixes.  Are these
used?

> +
> +/*
> + * OCRAM
> + */
> +#define MX28_OCRAM_BASE_ADDR		0x00000000
> +#define MX28_OCRAM_SIZE			SZ_128K
> +
> +/*
> + * IO
> + */
> +#define MX28_IO_BASE_ADDR		0x80000000
> +#define MX28_IO_SIZE			SZ_1M
> +
> +#define MX28_ICOLL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x000000)
> +#define MX28_HSADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x002000)
> +#define MX28_APBH_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x004000)
> +#define MX28_PERFMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x006000)
> +#define MX28_BCH_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00a000)
> +#define MX28_GPMI_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x00c000)
> +#define MX28_SSP0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x010000)
> +#define MX28_SSP1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x012000)
> +#define MX28_SSP2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x014000)
> +#define MX28_SSP3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x016000)
> +#define MX28_PINCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x018000)
> +#define MX28_DIGCTL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x01c000)
> +#define MX28_ETM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x022000)
> +#define MX28_APBX_DMA_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x024000)
> +#define MX28_DCP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x028000)
> +#define MX28_PXP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02a000)
> +#define MX28_OCOTP_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02c000)
> +#define MX28_AXI_AHB0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x02e000)
> +#define MX28_LCDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x030000)
> +#define MX28_CAN0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x032000)
> +#define MX28_CAN1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x034000)
> +#define MX28_SIMDBG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c000)
> +#define MX28_SIMGPMISEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c200)
> +#define MX28_SIMSSPSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c300)
> +#define MX28_SIMMEMSEL_BASE_ADDR	(MX28_IO_BASE_ADDR + 0x03c400)
> +#define MX28_GPIOMON_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c500)
> +#define MX28_SIMENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c700)
> +#define MX28_ARMJTAG_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x03c800)
> +#define MX28_CLKCTRL_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x040000)
> +#define MX28_SAIF0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x042000)
> +#define MX28_POWER_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x044000)
> +#define MX28_SAIF1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x046000)
> +#define MX28_LRADC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x050000)
> +#define MX28_SPDIF_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x054000)
> +#define MX28_RTC_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x056000)
> +#define MX28_I2C0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x058000)
> +#define MX28_I2C1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x05a000)
> +#define MX28_PWM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x064000)
> +#define MX28_TIMROT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x068000)
> +#define MX28_AUART0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06a000)
> +#define MX28_AUART1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06c000)
> +#define MX28_AUART2_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x06e000)
> +#define MX28_AUART3_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x070000)
> +#define MX28_AUART4_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x072000)
> +#define MX28_DUART_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x074000)
> +#define MX28_USBPHY0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07C000)
> +#define MX28_USBPHY1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x07e000)
> +#define MX28_USBCTRL0_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x080000)
> +#define MX28_USBCTRL1_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x090000)
> +#define MX28_DFLPT_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0c0000)
> +#define MX28_DRAM_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0e0000)
> +#define MX28_ENET_BASE_ADDR		(MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_FEC_BASE_ADDR		MX28_ENET_BASE_ADDR
> +
> +#define MX28_IO_P2V(x)			IMX_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x)		IOMEM(MX27_IO_P2V(x))
s/27/28/ I suppose

> +
> +/*
> + * IRQ
> + */
> +#define MX28_INT_BATT_BRNOUT		0
> +#define MX28_INT_VDDD_BRNOUT		1
> +#define MX28_INT_VDDIO_BRNOUT		2
> +#define MX28_INT_VDDA_BRNOUT		3
> +#define MX28_INT_VDD5V_DROOP		4
> +#define MX28_INT_DCDC4P2_BRNOUT		5
> +#define MX28_INT_VDD5V			6
> +#define MX28_INT_RESV7			7
> +#define MX28_INT_CAN0			8
> +#define MX28_INT_CAN1			9
> +#define MX28_INT_LRADC_TOUCH		10
> +#define MX28_INT_RESV11			11
> +#define MX28_INT_RESV12			12
> +#define MX28_INT_HSADC			13
> +#define MX28_INT_IRADC_THRESH0		14
> +#define MX28_INT_IRADC_THRESH1		15
> +#define MX28_INT_LRADC_CH0		16
> +#define MX28_INT_LRADC_CH1		17
> +#define MX28_INT_LRADC_CH2		18
> +#define MX28_INT_LRADC_CH3		19
> +#define MX28_INT_LRADC_CH4		20
> +#define MX28_INT_LRADC_CH5		21
> +#define MX28_INT_LRADC_CH6		22
> +#define MX28_INT_LRADC_CH7		23
> +#define MX28_INT_LRADC_BUTTON0		24
> +#define MX28_INT_LRADC_BUTTON1		25
> +#define MX28_INT_RESV26			26
> +#define MX28_INT_PERFMON		27
> +#define MX28_INT_RTC_1MSEC		28
> +#define MX28_INT_RTC_ALARM		29
> +#define MX28_INT_RESV30			30
> +#define MX28_INT_COMMS			31
> +#define MX28_INT_EMI_ERR		32
> +#define MX28_INT_RESV33			33
> +#define MX28_INT_RESV34			34
> +#define MX28_INT_RESV35			35
> +#define MX28_INT_RESV36			36
> +#define MX28_INT_RESV37			37
> +#define MX28_INT_LCDIF			38
> +#define MX28_INT_PXP			39
> +#define MX28_INT_RESV40			40
> +#define MX28_INT_BCH			41
> +#define MX28_INT_GPMI			42
> +#define MX28_INT_RESV43			43
> +#define MX28_INT_RESV44			44
> +#define MX28_INT_SPDIF_ERROR		45
> +#define MX28_INT_RESV46			46
> +#define MX28_INT_DUART			47
> +#define MX28_INT_TIMER0			48
> +#define MX28_INT_TIMER1			49
> +#define MX28_INT_TIMER2			50
> +#define MX28_INT_TIMER3			51
> +#define MX28_INT_DCP_VMI		52
> +#define MX28_INT_DCP			53
> +#define MX28_INT_DCP_SECURE		54
> +#define MX28_INT_RESV55			55
> +#define MX28_INT_RESV56			56
> +#define MX28_INT_RESV57			57
> +#define MX28_INT_SAIF1			58
> +#define MX28_INT_SAIF0			59
> +#define MX28_INT_RESV60			60
> +#define MX28_INT_RESV61			61
> +#define MX28_INT_RESV62			62
> +#define MX28_INT_RESV63			63
> +#define MX28_INT_RESV64			64
> +#define MX28_INT_RESV65			65
> +#define MX28_INT_SPDIF_DMA		66
> +#define MX28_INT_RESV67			67
> +#define MX28_INT_I2C0_DMA		68
> +#define MX28_INT_I2C1_DMA		69
> +#define MX28_INT_AUART0_RX_DMA		70
> +#define MX28_INT_AUART0_TX_DMA		71
> +#define MX28_INT_AUART1_RX_DMA		72
> +#define MX28_INT_AUART1_TX_DMA		73
> +#define MX28_INT_AUART2_RX_DMA		74
> +#define MX28_INT_AUART2_TX_DMA		75
> +#define MX28_INT_AUART3_RX_DMA		76
> +#define MX28_INT_AUART3_TX_DMA		77
> +#define MX28_INT_AUART4_RX_DMA		78
> +#define MX28_INT_AUART4_TX_DMA		79
> +#define MX28_INT_SAIF0_DMA		80
> +#define MX28_INT_SAIF1_DMA		81
> +#define MX28_INT_SSP0_DMA		82
> +#define MX28_INT_SSP1_DMA		83
> +#define MX28_INT_SSP2_DMA		84
> +#define MX28_INT_SSP3_DMA		85
> +#define MX28_INT_LCDIF_DMA		86
> +#define MX28_INT_HSADC_DMA		87
> +#define MX28_INT_GPMI_DMA		88
> +#define MX28_INT_DIGCTL_DEBUG_TRAP	89
> +#define MX28_INT_RESV90			90
> +#define MX28_INT_RESV91			91
> +#define MX28_INT_USB1			92
> +#define MX28_INT_USB0			93
> +#define MX28_INT_USB1_WAKEUP		94
> +#define MX28_INT_USB0_WAKEUP		95
> +#define MX28_INT_SSP0			96
> +#define MX28_INT_SSP1			97
> +#define MX28_INT_SSP2			98
> +#define MX28_INT_SSP3			99
> +#define MX28_INT_ENET_SWI		100
> +#define MX28_INT_ENET_MAC0		101
> +#define MX28_INT_ENET_MAC1		102
> +#define MX28_INT_ENET_MAC0_1588		103
> +#define MX28_INT_ENET_MAC1_1588		104
> +#define MX28_INT_RESV105		105
> +#define MX28_INT_RESV106		106
> +#define MX28_INT_RESV107		107
> +#define MX28_INT_RESV108		108
> +#define MX28_INT_RESV109		109
> +#define MX28_INT_I2C1_ERROR		110
> +#define MX28_INT_I2C0_ERROR		111
> +#define MX28_INT_AUART0			112
> +#define MX28_INT_AUART1			113
> +#define MX28_INT_AUART2			114
> +#define MX28_INT_AUART3			115
> +#define MX28_INT_AUART4			116
> +#define MX28_INT_RESV117		117
> +#define MX28_INT_RESV118		118
> +#define MX28_INT_RESV119		119
> +#define MX28_INT_RESV120		120
> +#define MX28_INT_RESV121		121
> +#define MX28_INT_RESV122		122
I'd just skip those RESV defines (assuming they mean "reserved").
> +#define MX28_INT_GPIO4			123
> +#define MX28_INT_GPIO3			124
> +#define MX28_INT_GPIO2			125
> +#define MX28_INT_GPIO1			126
> +#define MX28_INT_GPIO0			127
> +#define MX28_INT_FEC			MX28_INT_ENET_MAC0
This looks strage.  What is MX28_INT_ENET_MAC1 used for?

> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
> index 3432b78..563901f 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_MX21		21
>  #define MXC_CPU_MX25		25
>  #define MXC_CPU_MX27		27
> +#define MXC_CPU_MX28		28
>  #define MXC_CPU_MX31		31
>  #define MXC_CPU_MX35		35
>  #define MXC_CPU_MX51		51
> @@ -87,6 +88,18 @@ extern unsigned int __mxc_cpu_type;
>  # define cpu_is_mx27()		(0)
>  #endif
>  
> +#ifdef CONFIG_ARCH_MX28
> +# ifdef mxc_cpu_type
> +#  undef mxc_cpu_type
> +#  define mxc_cpu_type __mxc_cpu_type
> +# else
> +#  define mxc_cpu_type MXC_CPU_MX28
> +# endif
> +# define cpu_is_mx28()		(mxc_cpu_type == MXC_CPU_MX28)
> +#else
> +# define cpu_is_mx28()		(0)
> +#endif
> +
>  #ifdef CONFIG_ARCH_MX31
>  # ifdef mxc_cpu_type
>  #  undef mxc_cpu_type
> @@ -161,5 +174,6 @@ extern void __iomem *mxc_irq_base;
>  
>  #define MXC_IRQ_TYPE_AVIC	1
>  #define MXC_IRQ_TYPE_TZIC	2
> +#define MXC_IRQ_TYPE_ICOLL	3
>  
>  #endif /*  __ASM_ARCH_MXC_H__ */

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL
  2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
@ 2010-11-15 16:33   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:33 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:26PM +0800, Shawn Guo wrote:
> MX28 uses Interrupt Collector (ICOLL) as the interrupt
> controller. So ICOLL becomes the third interrupt controller
> for MXC besides AVIC and TZIC.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/icoll.c                    |   79 ++++++++++++++++++++++++++
>  arch/arm/plat-mxc/include/mach/entry-macro.S |   22 ++++++-
>  2 files changed, 97 insertions(+), 4 deletions(-)
>  create mode 100644 arch/arm/plat-mxc/icoll.c
> 
> diff --git a/arch/arm/plat-mxc/icoll.c b/arch/arm/plat-mxc/icoll.c
> new file mode 100644
> index 0000000..e9a9e42
> --- /dev/null
> +++ b/arch/arm/plat-mxc/icoll.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/init.h>
> +#include <linux/irq.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define HW_ICOLL_VECTOR				0x0000
> +#define HW_ICOLL_LEVELACK			0x0010
> +#define HW_ICOLL_CTRL				0x0020
> +#define HW_ICOLL_INTERRUPTn_SET(n)		(0x0124 + (n) * 0x10)
> +#define HW_ICOLL_INTERRUPTn_CLR(n)		(0x0128 + (n) * 0x10)
> +#define BM_ICOLL_INTERRUPTn_ENABLE		0x00000004
> +#define BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0	0x1
> +
> +void __iomem *icoll_base;
> +
> +static void icoll_ack_irq(unsigned int irq)
> +{
> +	__raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> +
> +	/* ACK current interrupt (level 0) */
> +	__raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
> +			icoll_base + HW_ICOLL_LEVELACK);
> +}
> +
> +static void icoll_mask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_CLR(irq));
> +}
> +
> +static void icoll_unmask_irq(unsigned int irq)
> +{
> +	__raw_writel(BM_ICOLL_INTERRUPTn_ENABLE,
> +			icoll_base + HW_ICOLL_INTERRUPTn_SET(irq));
> +}
> +
> +static struct irq_chip mxc_icoll_chip = {
> +	.ack = icoll_ack_irq,
> +	.mask = icoll_mask_irq,
> +	.unmask = icoll_unmask_irq,
> +};
> +
> +void __init icoll_init_irq(void __iomem *irqbase)
> +{
> +	int i;
> +
> +	icoll_base = irqbase;
> +	mxc_irq_base = irqbase;
> +	mxc_irq_controller_type = MXC_IRQ_TYPE_ICOLL;
> +
> +	/* Reset icoll */
> +	mxc_reset_block(irqbase + HW_ICOLL_CTRL);
mxc_reset_block is only defined in patch 3, so you must not use it in
patch 2.

> +
> +	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
> +		set_irq_chip(i, &mxc_icoll_chip);
> +		set_irq_handler(i, handle_level_irq);
> +		set_irq_flags(i, IRQF_VALID);
> +	}
> +}
> diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
> index a7dd008..a66e804 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-2009 Freescale Semiconductor, Inc. All Rights Reserved.
> + *  Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   */
>  
>  /*
> @@ -73,25 +73,39 @@
>  #endif
>  	.endm
>  
> +	.macro	icoll_get_irqnr_and_base, irqnr, irqstat, base, tmp
> +	ldr \irqnr, [\base, #0x70]
> +	cmp \irqnr, #0x7F
> +	moveqs \irqnr, #0
> +	.endm
> +
>  	.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> -#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC
> +#if defined CONFIG_MXC_TZIC && defined CONFIG_MXC_AVIC && defined CONFIG_MXC_ICOLL
>  	ldr	\tmp, =mxc_irq_controller_type
>  	ldr	\tmp, [\tmp]
>  	cmp	\tmp, #MXC_IRQ_TYPE_AVIC
>  	beq	3001f
> +	cmp	\tmp, #MXC_IRQ_TYPE_ICOLL
> +	beq	3002f
>  
>  	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> -	b	3002f
> +	b	3003f
>  3001:
>  	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +	b	3003f
>  3002:
> +	icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +	b	3003f
> +3003:
>  
>  #elif defined CONFIG_MXC_TZIC
>  	tzic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
>  #elif defined CONFIG_MXC_AVIC
>  	avic_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
> +#elif defined CONFIG_MXC_ICOLL
> +	icoll_get_irqnr_and_base \irqnr, \irqstat, \base, \tmp
>  #else
> -#error no tzic and no avic?
> +#error none of tzic, avic, icoll?
>  #endif
>  	.endm
I wonder if it's sensible to integrate mx28 (and mx23) support into
mach-imx/plat-mxc.  They seem to better fit into mach-stmp378x?!

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
  2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
@ 2010-11-15 16:36   ` Uwe Kleine-König
  2010-11-17 11:17     ` Shawn Guo
  0 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
> 1. The wdog reset is implemented in RTC block on MX28.
> 2. Implement the common reset routine for most blocks on MX28,
>    so that the blocks can call it to get a software reset.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/system.c |  104 ++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 101 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
> index c3972c5..257b426 100644
> --- a/arch/arm/plat-mxc/system.c
> +++ b/arch/arm/plat-mxc/system.c
> @@ -1,7 +1,7 @@
>  /*
>   * Copyright (C) 1999 ARM Limited
>   * Copyright (C) 2000 Deep Blue Solutions Ltd
> - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>   * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok at emcraft.com
>   *
> @@ -36,6 +36,7 @@ static void __iomem *wdog_base;
>  void arch_reset(char mode, const char *cmd)
>  {
>  	unsigned int wcr_enable;
> +	struct clk *clk;
>  
>  #ifdef CONFIG_ARCH_MXC91231
>  	if (cpu_is_mxc91231()) {
> @@ -52,9 +53,18 @@ void arch_reset(char mode, const char *cmd)
>  
>  	if (cpu_is_mx1()) {
>  		wcr_enable = (1 << 0);
> -	} else {
> -		struct clk *clk;
> +	} else if (cpu_is_mx28()) {
> +		clk = clk_get_sys("rtc", NULL);
> +		if (!IS_ERR(clk))
> +			clk_enable(clk);
>  
> +		/* set wdog count */
> +		__raw_writel(1, wdog_base + 0x50);
> +		/* wdog enbable bit */
s/enbable/enable/

> +		wcr_enable = (1 << 4);
> +		/* shift to SET address */
> +		wdog_base += 0x4;
> +	} else {
>  		clk = clk_get_sys("imx-wdt.0", NULL);
>  		if (!IS_ERR(clk))
>  			clk_enable(clk);
> @@ -80,3 +90,91 @@ void mxc_arch_reset_init(void __iomem *base)
>  {
>  	wdog_base = base;
>  }
> +
> +#ifdef CONFIG_ARCH_MX28
> +int mxc_reset_block(void __iomem *reg_addr)
> +{
> +	u32 reg;
> +	int timeout;
> +
> +	/*
> +	 * The process of software reset of IP block is done
> +	 * in several steps:
> +	 *
> +	 * 1) clear SFTRST and wait it cleared;
> +	 * 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
> +	 * 3) clear SFTRST and wait it cleared;
> +	 * 4) clear CLKGATE and wait it cleared.
> +	 */
> +
> +	/* Clear SFTRST */
> +	reg = __raw_readl(reg_addr);
> +	reg &= ~(1 << 31);
> +	__raw_writel(reg, reg_addr);
> +	/* Wait SFTRST cleared */
> +	timeout = 1000;
> +	do {
> +		mdelay(1);
> +		if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> +			break;
> +	} while (--timeout > 0);
Does the mdelay make sence here?

> +	if (timeout <= 0) {
> +		pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
> +		return -ETIMEDOUT;
> +	}
> +
> +	/* Clear CLKGATE */
> +	reg = __raw_readl(reg_addr);
> +	reg &= ~(1 << 30);
> +	__raw_writel(reg, reg_addr);
> +	/* Set SFTRST to reset the block */
> +	reg = __raw_readl(reg_addr);
> +	reg |= (1 << 31);
Can we have #defines here instead of constants?

> +	__raw_writel(reg, reg_addr);
> +	/* Poll CLKGATE set */
> +	timeout = 1000;
> +	do {
> +		mdelay(1);
> +		if (__raw_readl(reg_addr) & (1 << 30))
> +			break;
> +	} while (--timeout > 0);
> +	if (timeout <= 0) {
> +		pr_err("%s(%p): poll CLKGATE timeout\n", __func__, reg_addr);
> +		return -ETIMEDOUT;
> +	}
> +
> +	/* Clear SFTRST */
> +	reg = __raw_readl(reg_addr);
> +	reg &= ~(1 << 31);
> +	__raw_writel(reg, reg_addr);
> +	/* Wait SFTRST cleared */
> +	timeout = 1000;
> +	do {
> +		mdelay(1);
> +		if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> +			break;
> +	} while (--timeout > 0);
> +	if (timeout <= 0) {
> +		pr_err("%s(%p): clear SFTRST timeout\n", __func__, reg_addr);
> +		return -ETIMEDOUT;
> +	}
> +
> +	/* Clear CLKGATE */
> +	reg = __raw_readl(reg_addr);
> +	reg &= ~(1 << 30);
> +	__raw_writel(reg, reg_addr);
> +	/* Wait CLKGATE cleared */
> +	timeout = 1000;
> +	do {
> +		mdelay(1);
> +		if ((__raw_readl(reg_addr) & (1 << 30)) == 0)
> +			break;
> +	} while (--timeout > 0);
> +	if (timeout <= 0) {
> +		pr_err("%s(%p): clear CLKGATE timeout\n", __func__, reg_addr);
> +		return -ETIMEDOUT;
> +	}
> +
> +	return 0;
> +}
> +#endif
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 04/11] ARM: imx: Add timer support for i.MX28
  2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
@ 2010-11-15 16:40   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:40 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:28PM +0800, Shawn Guo wrote:
> SoC i.MX28 implements the timer in block TIMROT. It adds the
> support in the same file with GPT, and uses timer_is_timrot()
> to distinguish the IP block.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/time.c |  120 ++++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 100 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c
> index f9a1b05..3e1f09d 100644
> --- a/arch/arm/plat-mxc/time.c
> +++ b/arch/arm/plat-mxc/time.c
> @@ -5,6 +5,7 @@
>   *  Copyright (C) 2002 Shane Nay (shane at minirl.com)
>   *  Copyright (C) 2006-2007 Pavel Pisa (ppisa at pikron.com)
>   *  Copyright (C) 2008 Juergen Beisert (kernel at pengutronix.de)
> + *  Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   *
>   * This program is free software; you can redistribute it and/or
>   * modify it under the terms of the GNU General Public License
> @@ -63,8 +64,22 @@
>  #define V2_TCN			0x24
>  #define V2_TCMP			0x10
>  
> -#define timer_is_v1()	(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
> -#define timer_is_v2()	(!timer_is_v1())
> +/* TIMROT */
> +#define HW_TIMROT_ROTCTRL			0x00
> +#define HW_TIMROT_TIMCTRL0			0x20
> +#define HW_TIMROT_TIMCTRL0_SET			0x24
> +#define HW_TIMROT_TIMCTRL0_CLR			0x28
> +#define HW_TIMROT_RUNNING_COUNT0		0x30
> +#define HW_TIMROT_MATCH_COUNT0			0x50
> +#define BM_TIMROT_TIMCTRL0_IRQ_EN		0x00004000
> +#define BM_TIMROT_TIMCTRL0_IRQ			0x00008000
> +#define BM_TIMROT_TIMCTRL0_MATCH_MODE		0x00000800
> +#define BP_TIMROT_TIMCTRL0_SELECT		0
> +#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL	0xb
> +
> +#define timer_is_v1()		(cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
> +#define timer_is_v2()		(!timer_is_v1())
> +#define timer_is_timrot()	(cpu_is_mx28())
Did you notice that timer_is_v2() evaluates to true on mx28?

>  static struct clock_event_device clockevent_mxc;
>  static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> @@ -105,6 +120,24 @@ static void gpt_irq_acknowledge(void)
>  		__raw_writel(V2_TSTAT_OF1, timer_base + V2_TSTAT);
>  }
>  
> +static inline void timrot_irq_disable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRL0_CLR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ_EN,
> +			timer_base + HW_TIMROT_TIMCTRL0_SET);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> +	__raw_writel(BM_TIMROT_TIMCTRL0_IRQ,
> +			timer_base + HW_TIMROT_TIMCTRL0_CLR);
> +}
> +
>  static cycle_t mx1_2_get_cycles(struct clocksource *cs)
>  {
>  	return __raw_readl(timer_base + MX1_2_TCN);
> @@ -115,6 +148,11 @@ static cycle_t v2_get_cycles(struct clocksource *cs)
>  	return __raw_readl(timer_base + V2_TCN);
>  }
>  
> +static cycle_t timrot_get_cycles(struct clocksource *cs)
> +{
> +	return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNT0);
> +}
> +
>  static struct clocksource clocksource_mxc = {
>  	.name 		= "mxc_timer1",
>  	.rating		= 200,
> @@ -128,8 +166,12 @@ static int __init mxc_clocksource_init(struct clk *timer_clk)
>  {
>  	unsigned int c = clk_get_rate(timer_clk);
>  
> -	if (timer_is_v2())
> +	if (timer_is_timrot()) {
> +		clocksource_mxc.read = timrot_get_cycles;
> +		clocksource_mxc.shift = 10;
> +	} else if (timer_is_v2()) {
>  		clocksource_mxc.read = v2_get_cycles;
> +	}
>  
>  	clocksource_mxc.mult = clocksource_hz2mult(c,
>  					clocksource_mxc.shift);
> @@ -166,6 +208,18 @@ static int v2_set_next_event(unsigned long evt,
>  				-ETIME : 0;
>  }
>  
> +static int timrot_set_next_event(unsigned long evt,
> +					struct clock_event_device *dev)
> +{
> +	unsigned long match;
> +
> +	match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNT0) - evt;
> +	__raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNT0);
> +
> +	return (int)(match - __raw_readl(timer_base +
> +			HW_TIMROT_RUNNING_COUNT0)) > 0 ? -ETIME : 0;
> +}
> +
>  #ifdef DEBUG
>  static const char *clock_event_mode_label[] = {
>  	[CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> @@ -186,12 +240,19 @@ static void mxc_set_mode(enum clock_event_mode mode,
>  	 */
>  	local_irq_save(flags);
>  
> -	/* Disable interrupt in GPT module */
> -	gpt_irq_disable();
> +	/* Disable interrupt in timer module */
> +	if (timer_is_timrot())
> +		timrot_irq_disable();
> +	else
> +		gpt_irq_disable();
can we have timrot_set_mode() please.  Having several cpu_is_... in hot
paths isn't nice.

>  	if (mode != clockevent_mode) {
>  		/* Set event time into far-far future */
> -		if (timer_is_v2())
> +		if (timer_is_timrot())
> +			__raw_writel(__raw_readl(timer_base +
> +					HW_TIMROT_RUNNING_COUNT0) + 3,
> +					timer_base + HW_TIMROT_MATCH_COUNT0);
> +		else if (timer_is_v2())
>  			__raw_writel(__raw_readl(timer_base + V2_TCN) - 3,
>  					timer_base + V2_TCMP);
>  		else
> @@ -199,7 +260,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
>  					timer_base + MX1_2_TCMP);
>  
>  		/* Clear pending interrupt */
> -		gpt_irq_acknowledge();
> +		if (timer_is_timrot())
> +			timrot_irq_acknowledge();
> +		else
> +			gpt_irq_acknowledge();
>  	}
>  
>  #ifdef DEBUG
> @@ -225,7 +289,10 @@ static void mxc_set_mode(enum clock_event_mode mode,
>  	 * mode switching
>  	 */
>  		local_irq_save(flags);
> -		gpt_irq_enable();
> +		if (timer_is_timrot())
> +			timrot_irq_enable();
> +		else
> +			gpt_irq_enable();
>  		local_irq_restore(flags);
>  		break;
>  	case CLOCK_EVT_MODE_SHUTDOWN:
> @@ -249,7 +316,10 @@ static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
>  	else
>  		tstat = __raw_readl(timer_base + MX1_2_TSTAT);
>  
> -	gpt_irq_acknowledge();
> +	if (timer_is_timrot())
> +		timrot_irq_acknowledge();
> +	else
> +		gpt_irq_acknowledge();
>  
>  	evt->event_handler(evt);
>  
> @@ -275,7 +345,9 @@ static int __init mxc_clockevent_init(struct clk *timer_clk)
>  {
>  	unsigned int c = clk_get_rate(timer_clk);
>  
> -	if (timer_is_v2())
> +	if (timer_is_timrot())
> +		clockevent_mxc.set_next_event = timrot_set_next_event;
> +	else if (timer_is_v2())
>  		clockevent_mxc.set_next_event = v2_set_next_event;
>  
>  	clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC,
> @@ -303,16 +375,24 @@ void __init mxc_timer_init(struct clk *timer_clk, void __iomem *base, int irq)
>  	/*
>  	 * Initialise to a known state (all timers off, and timing reset)
>  	 */
> -
> -	__raw_writel(0, timer_base + MXC_TCTL);
> -	__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> -
> -	if (timer_is_v2())
> -		tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR | V2_TCTL_WAITEN | MXC_TCTL_TEN;
> -	else
> -		tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 | MXC_TCTL_TEN;
> -
> -	__raw_writel(tctl_val, timer_base + MXC_TCTL);
> +	if (timer_is_timrot()) {
> +		mxc_reset_block(base + HW_TIMROT_ROTCTRL);
> +		__raw_writel(
> +			BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> +			BM_TIMROT_TIMCTRL0_IRQ_EN |
> +			BM_TIMROT_TIMCTRL0_MATCH_MODE,
> +			timer_base + HW_TIMROT_TIMCTRL0); /* timer0*/
> +	} else {
> +		__raw_writel(0, timer_base + MXC_TCTL);
> +		__raw_writel(0, timer_base + MXC_TPRER); /* see datasheet note */
> +		if (timer_is_v2())
> +			tctl_val = V2_TCTL_CLK_IPG | V2_TCTL_FRR |
> +					V2_TCTL_WAITEN | MXC_TCTL_TEN;
> +		else
> +			tctl_val = MX1_2_TCTL_FRR | MX1_2_TCTL_CLK_PCLK1 |
> +					MXC_TCTL_TEN;
> +		__raw_writel(tctl_val, timer_base + MXC_TCTL);
> +	}
>  
>  	/* init and register the timer to the framework */
>  	mxc_clocksource_init(timer_clk);
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 05/11] ARM: imx: Add GPIO support for i.MX28
  2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
@ 2010-11-15 16:43   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:29PM +0800, Shawn Guo wrote:
> SoC i.MX28 implements GPIO functions in block PINCTRL. It adds
> the support in the same file used by other i.MX SoCs, and uses
> cpu_is_mx28() to distinguish the PINCTRL from GPIO used by other
> i.MX SoCs.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/gpio.c |  186 +++++++++++++++++++++++++++++++++++++--------
>  1 files changed, 153 insertions(+), 33 deletions(-)
> 
> diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
> index 9c3e362..f0d94af 100644
> --- a/arch/arm/plat-mxc/gpio.c
> +++ b/arch/arm/plat-mxc/gpio.c
> @@ -30,6 +30,17 @@
>  static struct mxc_gpio_port *mxc_gpio_ports;
>  static int gpio_table_size;
>  
> +/* PINCTRL */
> +#define GPIO_PORT_ID(p)	(((void *)p - (void *)mxc_gpio_ports) / sizeof(p))
> +#define GPIO_DOUT(p)		(0x0700 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_DIN(p)		(0x0900 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_DOE(p)		(0x0b00 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_PIN2IRQ(p)		(0x1000 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_IRQEN(p)		(0x1100 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_LEV(p)		(0x1200 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_POL(p)		(0x1300 + GPIO_PORT_ID(p) * 0x10)
> +#define GPIO_IRQSTAT(p)		(0x1400 + GPIO_PORT_ID(p) * 0x10)
> +
>  #define cpu_is_mx1_mx2()	(cpu_is_mx1() || cpu_is_mx2())
>  
>  #define GPIO_DR		(cpu_is_mx1_mx2() ? 0x1c : 0x00)
> @@ -40,17 +51,25 @@ static int gpio_table_size;
>  #define GPIO_IMR	(cpu_is_mx1_mx2() ? 0x30 : 0x14)
>  #define GPIO_ISR	(cpu_is_mx1_mx2() ? 0x34 : 0x18)
>  
> -#define GPIO_INT_LOW_LEV	(cpu_is_mx1_mx2() ? 0x3 : 0x0)
> -#define GPIO_INT_HIGH_LEV	(cpu_is_mx1_mx2() ? 0x2 : 0x1)
> -#define GPIO_INT_RISE_EDGE	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
> -#define GPIO_INT_FALL_EDGE	(cpu_is_mx1_mx2() ? 0x1 : 0x3)
> +#define GPIO_INT_LOW_LEV \
> +	(cpu_is_mx28() ? 0x1 : (cpu_is_mx1_mx2() ? 0x3 : 0x0))

I'm more and more conviced that it doesn't make sense to fold mx28 into
the existing mxc code.
> +#define GPIO_INT_HIGH_LEV \
> +	(cpu_is_mx28() ? 0x3 : (cpu_is_mx1_mx2() ? 0x2 : 0x1))
> +#define GPIO_INT_RISE_EDGE \
> +	(cpu_is_mx1_mx2() ? 0x0 : 0x2)
> +#define GPIO_INT_FALL_EDGE \
> +	(cpu_is_mx28() ? 0x0 : (cpu_is_mx1_mx2() ? 0x1 : 0x3))
>  #define GPIO_INT_NONE		0x4
>  
>  /* Note: This driver assumes 32 GPIOs are handled in one register */
>  
>  static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
>  {
> -	__raw_writel(1 << index, port->base + GPIO_ISR);
> +	if (cpu_is_mx28())
> +		__raw_writel(1 << index,
> +				port->base + GPIO_IRQSTAT(port) + CLR_ADDR);
> +	else
> +		__raw_writel(1 << index, port->base + GPIO_ISR);
>  }
>  
>  static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
> @@ -58,9 +77,23 @@ static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
>  {
>  	u32 l;
>  
> -	l = __raw_readl(port->base + GPIO_IMR);
> -	l = (l & (~(1 << index))) | (!!enable << index);
> -	__raw_writel(l, port->base + GPIO_IMR);
> +	if (cpu_is_mx28()) {
> +		if (enable == 0) {
> +			__raw_writel(1 << index,
> +				port->base + GPIO_PIN2IRQ(port) + CLR_ADDR);
> +			__raw_writel(1 << index,
> +				port->base + GPIO_IRQEN(port) + CLR_ADDR);
> +		} else {
> +			__raw_writel(1 << index,
> +				port->base + GPIO_PIN2IRQ(port) + SET_ADDR);
> +			__raw_writel(1 << index,
> +				port->base + GPIO_IRQEN(port) + SET_ADDR);
> +		}
> +	} else {
> +		l = __raw_readl(port->base + GPIO_IMR);
> +		l = (l & (~(1 << index))) | (!!enable << index);
> +		__raw_writel(l, port->base + GPIO_IMR);
> +	}
>  }
>  
>  static void gpio_ack_irq(u32 irq)
> @@ -120,10 +153,28 @@ static int gpio_set_irq_type(u32 irq, u32 type)
>  		return -EINVAL;
>  	}
>  
> -	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> -	bit = gpio & 0xf;
> -	val = __raw_readl(reg) & ~(0x3 << (bit << 1));
> -	__raw_writel(val | (edge << (bit << 1)), reg);
> +	if (cpu_is_mx28()) {
> +		/* set level or edge */
> +		if (edge & 0x1)
> +			__raw_writel(1 << (gpio & 31),
> +					port->base + GPIO_LEV(port) + SET_ADDR);
> +		else
> +			__raw_writel(1 << (gpio & 31),
> +					port->base + GPIO_LEV(port) + CLR_ADDR);
> +		/* set polarity */
> +		if ((edge >> 1) & 0x1)
> +			__raw_writel(1 << (gpio & 31),
> +					port->base + GPIO_POL(port) + SET_ADDR);
> +		else
> +			__raw_writel(1 << (gpio & 31),
> +					port->base + GPIO_POL(port) + CLR_ADDR);
> +	} else {
> +		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
> +		bit = gpio & 0xf;
> +		val = __raw_readl(reg) & ~(0x3 << (bit << 1));
> +		__raw_writel(val | (edge << (bit << 1)), reg);
> +	}
> +
>  	_clear_gpio_irqstatus(port, gpio & 0x1f);
>  
>  	return 0;
> @@ -135,23 +186,36 @@ static void mxc_flip_edge(struct mxc_gpio_port *port, u32 gpio)
>  	u32 bit, val;
>  	int edge;
>  
> -	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> -	bit = gpio & 0xf;
> -	val = __raw_readl(reg);
> -	edge = (val >> (bit << 1)) & 3;
> -	val &= ~(0x3 << (bit << 1));
> -	if (edge == GPIO_INT_HIGH_LEV) {
> -		edge = GPIO_INT_LOW_LEV;
> -		pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
> -	} else if (edge == GPIO_INT_LOW_LEV) {
> -		edge = GPIO_INT_HIGH_LEV;
> -		pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
> +	if (cpu_is_mx28()) {
> +		edge = 1 << (gpio & 31);
> +		val = __raw_readl(port->base + GPIO_LEV(port));
> +		if (val & edge) {
> +			/* level is invalid for this function */
> +			pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> +				gpio, edge);
> +			return;
> +		}
> +		__raw_writel(1 << (gpio & 31),
> +				port->base + GPIO_POL(port) + TOG_ADDR);
>  	} else {
> -		pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> -		       gpio, edge);
> -		return;
> +		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2);
> +		bit = gpio & 0xf;
> +		val = __raw_readl(reg);
> +		edge = (val >> (bit << 1)) & 3;
> +		val &= ~(0x3 << (bit << 1));
> +		if (edge == GPIO_INT_HIGH_LEV) {
> +			edge = GPIO_INT_LOW_LEV;
> +			pr_debug("mxc: switch GPIO %d to low trigger\n", gpio);
> +		} else if (edge == GPIO_INT_LOW_LEV) {
> +			edge = GPIO_INT_HIGH_LEV;
> +			pr_debug("mxc: switch GPIO %d to high trigger\n", gpio);
> +		} else {
> +			pr_err("mxc: invalid configuration for GPIO %d: %x\n",
> +			       gpio, edge);
> +			return;
> +		}
> +		__raw_writel(val | (edge << (bit << 1)), reg);
>  	}
> -	__raw_writel(val | (edge << (bit << 1)), reg);
>  }
>  
>  /* handle 32 interrupts in one status register */
> @@ -183,6 +247,29 @@ static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
>  	mxc_gpio_irq_handler(port, irq_stat);
>  }
>  
> +/* MX28 has one interrupt *per* gpio port */
> +static void mx28_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> +	u32 irq_stat;
> +	struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
> +	u32 gpio_irq_no_base = port->virtual_irq_start;
> +
> +	irq_stat = __raw_readl(port->base + GPIO_IRQSTAT(port)) &
> +			__raw_readl(port->base + GPIO_IRQEN(port)) &
> +			__raw_readl(port->base + GPIO_PIN2IRQ(port));
> +
> +	while (irq_stat != 0) {
> +		int irqoffset = fls(irq_stat) - 1;
> +
> +		if (port->both_edges & (1 << irqoffset))
> +			mxc_flip_edge(port, irqoffset);
> +
> +		generic_handle_irq(gpio_irq_no_base + irqoffset);
> +
> +		irq_stat &= ~(1 << irqoffset);
> +	}
> +}
> +
>  /* MX2 has one interrupt *for all* gpio ports */
>  static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
>  {
> @@ -247,14 +334,20 @@ static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
>  		container_of(chip, struct mxc_gpio_port, chip);
>  	u32 l;
>  	unsigned long flags;
> +	void __iomem *reg;
> +
> +	if (cpu_is_mx28())
> +		reg = port->base + GPIO_DOE(port);
> +	else
> +		reg = port->base + GPIO_GDIR;
>  
>  	spin_lock_irqsave(&port->lock, flags);
> -	l = __raw_readl(port->base + GPIO_GDIR);
> +	l = __raw_readl(reg);
>  	if (dir)
>  		l |= 1 << offset;
>  	else
>  		l &= ~(1 << offset);
> -	__raw_writel(l, port->base + GPIO_GDIR);
> +	__raw_writel(l, reg);
>  	spin_unlock_irqrestore(&port->lock, flags);
>  }
>  
> @@ -262,9 +355,14 @@ static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
>  {
>  	struct mxc_gpio_port *port =
>  		container_of(chip, struct mxc_gpio_port, chip);
> -	void __iomem *reg = port->base + GPIO_DR;
>  	u32 l;
>  	unsigned long flags;
> +	void __iomem *reg;
> +
> +	if (cpu_is_mx28())
> +		reg = port->base + GPIO_DOUT(port);
> +	else
> +		reg = port->base + GPIO_DR;
Here again, you clutter several hot paths with if(cpu_is_...()) tests.

gpiolib is generic enough not to need this.
>  
>  	spin_lock_irqsave(&port->lock, flags);
>  	l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> @@ -276,8 +374,14 @@ static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
>  {
>  	struct mxc_gpio_port *port =
>  		container_of(chip, struct mxc_gpio_port, chip);
> +	void __iomem *reg;
> +
> +	if (cpu_is_mx28())
> +		reg = port->base + GPIO_DIN(port);
> +	else
> +		reg = port->base + GPIO_PSR;
>  
> -	return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
> +	return (__raw_readl(reg) >> offset) & 1;
>  }
>  
>  static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> @@ -306,8 +410,19 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
>  
>  	for (i = 0; i < cnt; i++) {
>  		/* disable the interrupt and clear the status */
> -		__raw_writel(0, port[i].base + GPIO_IMR);
> -		__raw_writel(~0, port[i].base + GPIO_ISR);
> +		if (cpu_is_mx28()) {
> +			__raw_writel(0, port[i].base +
> +						GPIO_PIN2IRQ(&port[i]));
> +			__raw_writel(0, port[i].base +
> +						GPIO_IRQEN(&port[i]));
> +			__raw_writel(~0, port[i].base +
> +						GPIO_IRQSTAT(&port[i]) +
> +						CLR_ADDR);
> +		} else {
> +			__raw_writel(0, port[i].base + GPIO_IMR);
> +			__raw_writel(~0, port[i].base + GPIO_ISR);
> +		}
> +
>  		for (j = port[i].virtual_irq_start;
>  			j < port[i].virtual_irq_start + 32; j++) {
>  			set_irq_chip(j, &gpio_irq_chip);
> @@ -338,6 +453,11 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
>  						mx3_gpio_irq_handler);
>  				set_irq_data(port[i].irq_high, &port[i]);
>  			}
> +		} else if (cpu_is_mx28()) {
> +			/* setup one handler for each entry */
> +			set_irq_chained_handler(port[i].irq,
> +						mx28_gpio_irq_handler);
> +			set_irq_data(port[i].irq, &port[i]);
>  		}
>  	}
>  
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 06/11] ARM: imx: Add IOMUX support for i.MX28
  2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
@ 2010-11-15 16:46   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:30PM +0800, Shawn Guo wrote:
> Soc i.MX28 supports IOMUX function in block PINCTRL. Comparing
> to the naming of iomux-v1 and iomux-v3, it uses iomux-pinctrl,
> since PINCTRL is a totally different IP block from IOMUX and it's
> not reasonable to name it iomux-v2 or iomux-v4, which is used to
iomux v2 is already taken (by mx31) it just doesn't have this name (yet)
in the code.

> distinguish the different revision of same IP block.
Sounds more like something complet
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/include/mach/iomux-mx28.h    |   50 +++++++++++++
>  arch/arm/plat-mxc/include/mach/iomux-pinctrl.h |   91 +++++++++++++++++++++++
>  arch/arm/plat-mxc/iomux-pinctrl.c              |   94 ++++++++++++++++++++++++
>  3 files changed, 235 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx28.h
>  create mode 100644 arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
>  create mode 100644 arch/arm/plat-mxc/iomux-pinctrl.c
> 
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx28.h b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..8c68bd6
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/iomux-mx28.h
> @@ -0,0 +1,50 @@
> +/*
> + * Copyright (C) 2009-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License along
> + * with this program; if not, write to the Free Software Foundation, Inc.,
> + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
> + */
> +
> +#ifndef __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux-pinctrl.h>
> +
> +/*
> + * The naming convention for the pad modes is MX28_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux-pinctrl.h
> + *
> + *					 		BANK PIN     MUX            VOL          MA            PULL
> + */
> +/* DUART */
> +#define MX28_PAD_PWM0__DUART_RX			IOMUX_PAD(3, 16, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_PWM1__DUART_TX			IOMUX_PAD(3, 17, PAD_MUXSEL_2,    PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +/* FEC */
> +#define MX28_PAD_ENET0_MDC__ENET0_MDC		IOMUX_PAD(4, 0,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO		IOMUX_PAD(4, 1,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN	IOMUX_PAD(4, 2,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0		IOMUX_PAD(4, 3,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1		IOMUX_PAD(4, 4,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN	IOMUX_PAD(4, 6,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0		IOMUX_PAD(4, 7,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1		IOMUX_PAD(4, 8,  PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +#define MX28_PAD_ENET_CLK__ENET_CLK		IOMUX_PAD(4, 16, PAD_MUXSEL_0,    PAD_3V3,     PAD_8MA,      PAD_PULL)
> +
> +/* GPIO */
> +#define MX28_PAD_SSP1_DATA3__GPIO_2_15		IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13	IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3,     PAD_4MA,      PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX28_H__ */
> diff --git a/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
> new file mode 100644
> index 0000000..c2fdb33
> --- /dev/null
> +++ b/arch/arm/plat-mxc/include/mach/iomux-pinctrl.h
> @@ -0,0 +1,91 @@
> +/*
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *			<armlinux@phytec.de>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +
> +#ifndef __MACH_IOMUX_PINCTRL_H__
> +#define __MACH_IOMUX_PINCTRL_H__
> +
> +typedef struct deprecated_pad_desc {
> +	unsigned bank:3;
> +	unsigned pin:5;
> +	unsigned muxsel:2;
> +	unsigned ma:3;
> +	unsigned vol:2;
> +	unsigned pull:1;
> +} iomux_pinctrl_cfg_t;
Oh, you start with things that are already now deprecated?

> +
> +#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull)	\
> +		{						\
> +			.bank	= _bank,			\
> +			.pin	= _pin,				\
> +			.muxsel	= _muxsel,			\
> +			.vol	= _vol,				\
> +			.ma	= _ma,				\
> +			.pull	= _pull,			\
> +		}
> +
> +#define PAD_MUXSEL_0		0
> +#define PAD_MUXSEL_1		1
> +#define PAD_MUXSEL_2		2
> +#define PAD_MUXSEL_GPIO		3
> +
> +#define PAD_1V8			0
> +#define PAD_3V3			1
> +#define PAD_VOL_NONE		2
> +
> +#define PAD_4MA			0
> +#define PAD_8MA			1
> +#define PAD_12MA		2
> +#define PAD_16MA		3
> +#define PAD_MA_NONE		4
> +
> +#define PAD_NOPULL		0
> +#define PAD_PULL		1
> +
> +#define MX51_NUM_GPIO_PORT	4
> +
> +#define GPIO_PIN_MASK 0x1f
> +
> +#define GPIO_PORT_SHIFT 5
> +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT)
> +
> +#define GPIO_PORTA	(0 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTB	(1 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTC	(2 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTD	(3 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTE	(4 << GPIO_PORT_SHIFT)
> +#define GPIO_PORTF	(5 << GPIO_PORT_SHIFT)
> +
> +/*
> + * setups a single pad in the iomuxer
> + */
> +int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad);
> +
> +/*
> + * setups mutliple pads
s/mutliple/multiple/

> + * convenient way to call the above function with tables
> + */
> +int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count);
> +
> +/*
> + * Initialise the iomux controller
> + */
> +void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base);
> +
> +#endif /* __MACH_IOMUX_PINCTRL_H__*/
> diff --git a/arch/arm/plat-mxc/iomux-pinctrl.c b/arch/arm/plat-mxc/iomux-pinctrl.c
> new file mode 100644
> index 0000000..5f5b5ac
> --- /dev/null
> +++ b/arch/arm/plat-mxc/iomux-pinctrl.c
> @@ -0,0 +1,94 @@
> +/*
> + * Copyright 2004-2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
> + * Copyright (C) 2009 by Jan Weitzel Phytec Messtechnik GmbH,
> + *                       <armlinux@phytec.de>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version 2
> + * of the License, or (at your option) any later version.
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
> + * MA 02110-1301, USA.
> + */
> +#include <linux/errno.h>
> +#include <linux/init.h>
> +#include <linux/kernel.h>
> +#include <linux/module.h>
> +#include <linux/string.h>
> +#include <linux/gpio.h>
> +#include <asm/mach/map.h>
> +#include <mach/hardware.h>
> +#include <mach/iomux-pinctrl.h>
> +
> +static void __iomem *base;
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxc_iomux_pinctrl_setup_pad(iomux_pinctrl_cfg_t *pad)
> +{
> +	u32 reg, ofs, bp, bm;
> +
> +	/* MUXSEL */
> +	ofs = pad->bank * 0x20 + pad->pin / 16 * 0x10;
> +	bp = pad->pin % 16 * 2;
> +	bm = 0x3 << bp;
> +	reg = __raw_readl(base + ofs);
> +	reg &= ~bm;
> +	reg |= pad->muxsel << bp;
> +	__raw_writel(reg, base + ofs);
> +
> +	/* DRIVE */
> +	if (pad->ma != PAD_MA_NONE && pad->vol != PAD_VOL_NONE)
> +	{
> +		ofs = 0x300 + pad->bank * 0x40 + pad->pin / 8 * 0x10;
> +		bp = pad->pin % 8 * 4;
> +		bm = 0x7 << bp;
> +		reg = __raw_readl(base + ofs);
> +		reg &= ~bm;
> +		reg |= pad->ma << bp | pad->vol << (bp + 2);
> +		__raw_writel(reg, base + ofs);
> +	}
> +
> +	/* PULL */
> +	ofs = 0x600 + pad->bank * 0x10;
> +	bp = pad->pin;
> +	bm = 0x1 << bp;
> +	reg = __raw_readl(base + ofs);
> +	reg &= ~bm;
> +	reg |= pad->pull << bp;
> +	__raw_writel(reg, base + ofs);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_pad);
> +
> +int mxc_iomux_pinctrl_setup_multiple_pads(iomux_pinctrl_cfg_t *pad_list, unsigned count)
> +{
> +	iomux_pinctrl_cfg_t *p = pad_list;
> +	int i;
> +	int ret;
> +
> +	for (i = 0; i < count; i++) {
> +		ret = mxc_iomux_pinctrl_setup_pad(p);
> +		if (ret)
> +			return ret;
> +		p++;
> +	}
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL(mxc_iomux_pinctrl_setup_multiple_pads);
> +
> +void mxc_iomux_pinctrl_init(void __iomem *iomux_pinctrl_base)
> +{
> +	base = iomux_pinctrl_base;
> +}
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 07/11] ARM: imx: Add support of uncompress print for i.MX28
  2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
@ 2010-11-15 16:47   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:47 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:31PM +0800, Shawn Guo wrote:
> SoC i.MX28 uses DUART IP block as the debug serial. It adds the
> support in the same file used by other i.MX SoC UART, and uses
> variable is_duart to distinguish.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/plat-mxc/include/mach/uncompress.h |   20 ++++++++++++++------
>  1 files changed, 14 insertions(+), 6 deletions(-)
> 
> diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
> index 9dd9c20..adb617f 100644
> --- a/arch/arm/plat-mxc/include/mach/uncompress.h
> +++ b/arch/arm/plat-mxc/include/mach/uncompress.h
> @@ -1,8 +1,9 @@
>  /*
> - *  arch/arm/plat-mxc/include/mach/uncompress.h
> + *  rch/arm/plat-mxc/include/mach/uncompress.h
???

>   *
>   *  Copyright (C) 1999 ARM Limited
>   *  Copyright (C) Shane Nay (shane at minirl.com)
> + *  Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License as published by
> @@ -22,14 +23,16 @@
>  #include <asm/mach-types.h>
>  
>  static unsigned long uart_base;
> +static unsigned short is_duart = 0;
don't initialize static variables to 0.

>  
>  #define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
>  
> -#define USR2 0x98
> -#define USR2_TXFE (1<<14)
> -#define TXR  0x40
> -#define UCR1 0x80
> -#define UCR1_UARTEN 1
> +#define USR2		(is_duart ? 0x18 : 0x98)
> +#define USR2_TXFE	(is_duart ? 1<<7 : 1<<14)
> +#define USR2_BUSY	(1 << 3)
> +#define TXR		(is_duart ? 0x00 : 0x40)
> +#define UCR1		(is_duart ? 0x30 : 0x80)
> +#define UCR1_UARTEN	1
>  
>  /*
>   * The following code assumes the serial port has already been
> @@ -59,6 +62,7 @@ static inline void flush(void)
>  
>  #define MX1_UART1_BASE_ADDR	0x00206000
>  #define MX25_UART1_BASE_ADDR	0x43f90000
> +#define MX28_DUART_BASE_ADDR	0x80074000
>  #define MX2X_UART1_BASE_ADDR	0x1000a000
>  #define MX3X_UART1_BASE_ADDR	0x43F90000
>  #define MX3X_UART2_BASE_ADDR	0x43F94000
> @@ -83,6 +87,10 @@ static __inline__ void __arch_decomp_setup(unsigned long arch_id)
>  	case MACH_TYPE_MXT_TD60:
>  		uart_base = MX2X_UART1_BASE_ADDR;
>  		break;
> +	case MACH_TYPE_MX28EVK:
> +		uart_base = MX28_DUART_BASE_ADDR;
> +		is_duart = 1;
> +		break;
>  	case MACH_TYPE_MX31LITE:
>  	case MACH_TYPE_ARMADILLO5X0:
>  	case MACH_TYPE_MX31MOBOARD:
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk
  2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
@ 2010-11-15 16:54   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 16:54 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:34PM +0800, Shawn Guo wrote:
> It adds machine mx28evk with initial duart and fec
> device registration.
> 
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-imx/devices-imx28.h               |   20 ++++
>  arch/arm/mach-imx/devices.c                     |   27 ++++++-
>  arch/arm/mach-imx/mach-mx28evk.c                |  109 +++++++++++++++++++++++
>  arch/arm/plat-mxc/devices/platform-duart.c      |   42 +++++++++
>  arch/arm/plat-mxc/devices/platform-fec.c        |    5 +
>  arch/arm/plat-mxc/include/mach/common.h         |    5 +
>  arch/arm/plat-mxc/include/mach/devices-common.h |   11 +++
Can you split this up into (say):

 - mx28: dynamically allocate duart devices
 - mx28: dynamically allocate fec devices
 - mx28: add gpio port definitions
 - mx28: mx28evk support

>  7 files changed, 218 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/mach-imx/devices-imx28.h
>  create mode 100644 arch/arm/mach-imx/mach-mx28evk.c
>  create mode 100644 arch/arm/plat-mxc/devices/platform-duart.c
> 
> diff --git a/arch/arm/mach-imx/devices-imx28.h b/arch/arm/mach-imx/devices-imx28.h
> new file mode 100644
> index 0000000..f35c910
> --- /dev/null
> +++ b/arch/arm/mach-imx/devices-imx28.h
> @@ -0,0 +1,20 @@
> +/*
> + * Copyright (C) 2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <mach/mx28.h>
> +#include <mach/devices-common.h>
> +
> +extern const struct imx_duart_data imx28_duart_data __initconst;
> +#define imx28_add_duart()	\
> +	imx_add_duart(&imx28_duart_data)
> +
> +extern const struct imx_fec_data imx28_fec_data __initconst;
> +#define imx28_add_fec(pdata)	\
> +	imx_add_fec(&imx28_fec_data, pdata)
> diff --git a/arch/arm/mach-imx/devices.c b/arch/arm/mach-imx/devices.c
> index e69e46e..946db32 100644
> --- a/arch/arm/mach-imx/devices.c
> +++ b/arch/arm/mach-imx/devices.c
> @@ -9,7 +9,7 @@
>   * licensed "as is" without any warranty of any kind, whether express
>   * or implied.
>   *
> - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
> + * Copyright 2006-2010 Freescale Semiconductor, Inc. All Rights Reserved.
>   * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>   * Copyright 2008 Sascha Hauer, kernel at pengutronix.de
>   * Copyright (c) 2008 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
> @@ -551,3 +551,28 @@ struct platform_device imx_kpp_device = {
>  };
>  
>  #endif
> +
> +#ifdef CONFIG_ARCH_MX28
> +/* gpio */
> +#define DEFINE_MXC_PINCTRL_GPIO_PORT(n)					\
> +	{								\
> +		.chip.label = "gpio-" #n,				\
> +		.irq = MX28_INT_GPIO##n,				\
> +		.base = MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR),	\
> +		.virtual_irq_start = MXC_GPIO_IRQ_START + n * 32,	\
> +	}
> +
> +static struct mxc_gpio_port imx28_gpio_ports[] = {
> +	DEFINE_MXC_PINCTRL_GPIO_PORT(0),
> +	DEFINE_MXC_PINCTRL_GPIO_PORT(1),
> +	DEFINE_MXC_PINCTRL_GPIO_PORT(2),
> +	DEFINE_MXC_PINCTRL_GPIO_PORT(3),
> +	DEFINE_MXC_PINCTRL_GPIO_PORT(4),
> +};
> +
> +int __init imx28_register_gpios(void)
> +{
> +	return mxc_gpio_init(imx28_gpio_ports,
> +			ARRAY_SIZE(imx28_gpio_ports));
> +}
> +#endif
In my tree I have moved this out of devices.c to plat-mxc/gpio.c.

> diff --git a/arch/arm/mach-imx/mach-mx28evk.c b/arch/arm/mach-imx/mach-mx28evk.c
> new file mode 100644
> index 0000000..d5dd940
> --- /dev/null
> +++ b/arch/arm/mach-imx/mach-mx28evk.c
> @@ -0,0 +1,109 @@
> +/*
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/platform_device.h>
> +#include <linux/gpio.h>
> +#include <linux/irq.h>
> +
> +#include <asm/mach-types.h>
> +#include <asm/mach/arch.h>
> +#include <asm/mach/time.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +#include <mach/iomux-mx28.h>
> +
> +#include "devices-imx28.h"
> +#include "devices.h"
> +
> +#define MX28EVK_FEC_PHY_POWER	(2*32 + 15)	/* GPIO_2_15 */
> +#define MX28EVK_FEC_PHY_RESET	(4*32 + 13)	/* GPIO_4_13 */
> +
> +static iomux_pinctrl_cfg_t mx28evk_pads[] = {
> +	/* DUART */
> +	MX28_PAD_PWM0__DUART_RX,
> +	MX28_PAD_PWM1__DUART_TX,
> +
> +	/* FEC */
> +	MX28_PAD_ENET0_MDC__ENET0_MDC,
> +	MX28_PAD_ENET0_MDIO__ENET0_MDIO,
> +	MX28_PAD_ENET0_RX_EN__ENET0_RX_EN,
> +	MX28_PAD_ENET0_RXD0__ENET0_RXD0,
> +	MX28_PAD_ENET0_RXD1__ENET0_RXD1,
> +	MX28_PAD_ENET0_TX_EN__ENET0_TX_EN,
> +	MX28_PAD_ENET0_TXD0__ENET0_TXD0,
> +	MX28_PAD_ENET0_TXD1__ENET0_TXD1,
> +	MX28_PAD_ENET_CLK__ENET_CLK,
> +	/* PHY power line */
> +	MX28_PAD_SSP1_DATA3__GPIO_2_15,
> +	/* PHY reset line */
> +	MX28_PAD_ENET0_RX_CLK__GPIO_4_13,
> +};
> +
> +/* FEC */
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> +        .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static inline void mx28evk_fec_reset(void)
> +{
> +	int ret;
> +
> +	/* Power up FEC PHY */
> +	ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
> +	if (ret) {
> +		pr_err("Failed to request GPIO_FEC_PHY_POWER: %d\n", ret);
> +		return;
> +	}
> +	gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
> +
> +	/* Reset FEC PHY */
> +	ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
> +	if (ret) {
> +		pr_err("Failed to request GPIO_FEC_PHY_RESET: %d\n", ret);
> +		return;
> +	}
> +	gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> +	mdelay(1);
> +	gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static void __init mx28evk_init(void)
> +{
> +	mxc_iomux_pinctrl_setup_multiple_pads(mx28evk_pads,
> +						ARRAY_SIZE(mx28evk_pads));
> +	imx28_add_duart();
> +
> +	mx28evk_fec_reset();
> +	imx28_add_fec(&mx28_fec_pdata);
> +}
> +
> +static void __init mx28evk_timer_init(void)
> +{
> +	mx28_clocks_init();
> +}
> +
> +static struct sys_timer mx28evk_timer = {
> +	.init	= mx28evk_timer_init,
> +};
> +
> +MACHINE_START(MX28EVK, "Freescale MX28 EVK")
> +	/* Maintainer: Freescale Semiconductor, Inc. */
> +	.boot_params    = MX28_PHYS_OFFSET + 0x100,
> +	.map_io         = mx28_map_io,
> +	.init_irq       = mx28_init_irq,
> +	.init_machine   = mx28evk_init,
> +	.timer          = &mx28evk_timer,
> +MACHINE_END
> diff --git a/arch/arm/plat-mxc/devices/platform-duart.c b/arch/arm/plat-mxc/devices/platform-duart.c
> new file mode 100644
> index 0000000..2dbf199
> --- /dev/null
> +++ b/arch/arm/plat-mxc/devices/platform-duart.c
> @@ -0,0 +1,42 @@
> +/*
> + * Copyright (C) 2009-2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify it under
> + * the terms of the GNU General Public License version 2 as published by the
> + * Free Software Foundation.
> + */
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +
> +#define imx_duart_data_entry_single(soc)				\
> +	{								\
> +		.iobase = soc ## _DUART_BASE_ADDR,			\
> +		.irq = soc ## _INT_DUART,				\
> +	}
> +
> +#ifdef CONFIG_ARCH_MX28
> +const struct imx_duart_data imx28_duart_data __initconst =
> +	imx_duart_data_entry_single(MX28);
> +#endif
> +
> +struct platform_device *__init imx_add_duart(
> +		const struct imx_duart_data *data)
> +{
> +	struct resource res[] = {
> +		{
> +			.start = data->iobase,
> +			.end = data->iobase + SZ_8K - 1,
> +			.flags = IORESOURCE_MEM,
> +		}, {
> +			.start = data->irq,
> +			.end = data->irq,
> +			.flags = IORESOURCE_IRQ,
> +		},
> +	};
> +
> +	return imx_add_platform_device("imx-duart", 0, res, ARRAY_SIZE(res),
> +					NULL, 0);
> +}
> diff --git a/arch/arm/plat-mxc/devices/platform-fec.c b/arch/arm/plat-mxc/devices/platform-fec.c
> index 11d087f..bd5a84b 100644
> --- a/arch/arm/plat-mxc/devices/platform-fec.c
> +++ b/arch/arm/plat-mxc/devices/platform-fec.c
> @@ -26,6 +26,11 @@ const struct imx_fec_data imx27_fec_data __initconst =
>  	imx_fec_data_entry_single(MX27);
>  #endif /* ifdef CONFIG_SOC_IMX27 */
>  
> +#ifdef CONFIG_ARCH_MX28
I'd prefer CONFIG_SOC_MX28 to have uniform naming.  (I already switched
MX25, MX31 and MX35 to CONFIG_SOC_MX... in my tree)

> +const struct imx_fec_data imx28_fec_data __initconst =
> +	imx_fec_data_entry_single(MX28);
> +#endif
> +
>  #ifdef CONFIG_ARCH_MX35
>  const struct imx_fec_data imx35_fec_data __initconst =
>  	imx_fec_data_entry_single(MX35);
> diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
> index 05676fb..6a5dea7 100644
> --- a/arch/arm/plat-mxc/include/mach/common.h
> +++ b/arch/arm/plat-mxc/include/mach/common.h
> @@ -18,16 +18,19 @@ extern void mx1_map_io(void);
>  extern void mx21_map_io(void);
>  extern void mx25_map_io(void);
>  extern void mx27_map_io(void);
> +extern void mx28_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 icoll_init_irq(void __iomem *);
>  extern void mx1_init_irq(void);
>  extern void mx21_init_irq(void);
>  extern void mx25_init_irq(void);
>  extern void mx27_init_irq(void);
> +extern void mx28_init_irq(void);
>  extern void mx31_init_irq(void);
>  extern void mx35_init_irq(void);
>  extern void mx51_init_irq(void);
> @@ -38,6 +41,7 @@ extern int mx1_clocks_init(unsigned long fref);
>  extern int mx21_clocks_init(unsigned long lref, unsigned long fref);
>  extern int mx25_clocks_init(void);
>  extern int mx27_clocks_init(unsigned long fref);
> +extern int mx28_clocks_init(void);
>  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,
> @@ -51,4 +55,5 @@ extern void mxc91231_power_off(void);
>  extern void mxc91231_arch_reset(int, const char *);
>  extern void mxc91231_prepare_idle(void);
>  extern void mx51_efikamx_reset(void);
> +extern int mxc_reset_block(void __iomem *);
>  #endif
> diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
> index 8c6896f..501329d 100644
> --- a/arch/arm/plat-mxc/include/mach/devices-common.h
> +++ b/arch/arm/plat-mxc/include/mach/devices-common.h
> @@ -2,6 +2,8 @@
>   * Copyright (C) 2009-2010 Pengutronix
>   * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
>   *
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
>   * This program is free software; you can redistribute it and/or modify it under
>   * the terms of the GNU General Public License version 2 as published by the
>   * Free Software Foundation.
> @@ -82,6 +84,15 @@ struct platform_device *__init imx_add_imx_uart_1irq(
>  		const struct imx_imx_uart_1irq_data *data,
>  		const struct imxuart_platform_data *pdata);
>  
> +struct imx_duart_data {
> +	int id;
> +	resource_size_t iobase;
> +	resource_size_t iosize;
> +	resource_size_t irq;
> +};
> +struct platform_device *__init imx_add_duart(
> +		const struct imx_duart_data *data);
> +
Can you please keep the file sorted alphabetically?

>  #include <mach/mxc_nand.h>
>  struct imx_mxc_nand_data {
>  	/*
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile
  2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
@ 2010-11-15 17:01   ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-15 17:01 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Nov 15, 2010 at 10:36:35PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
>  arch/arm/mach-imx/Kconfig          |   20 ++++++++++++++++++++
>  arch/arm/mach-imx/Makefile         |    4 ++++
>  arch/arm/mach-imx/Makefile.boot    |    4 ++++
>  arch/arm/plat-mxc/Kconfig          |   12 ++++++++++++
>  arch/arm/plat-mxc/Makefile         |    4 +++-
>  arch/arm/plat-mxc/devices/Kconfig  |    3 +++
>  arch/arm/plat-mxc/devices/Makefile |    1 +
>  7 files changed, 47 insertions(+), 1 deletions(-)
> 
> diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
> index d6e998f..8accd5c 100644
> --- a/arch/arm/mach-imx/Kconfig
> +++ b/arch/arm/mach-imx/Kconfig
> @@ -199,3 +199,23 @@ config MACH_MXT_TD60
>  	  includes specific configurations for the module and its peripherals.
>  
>  endif
> +
> +if ARCH_MX28
> +
> +config SOC_IMX28
> +	select CPU_ARM926T
> +	select ARCH_MXC_IOMUX_PINCTRL
> +	select MXC_ICOLL
> +	bool
> +
> +comment "MX28 platforms:"
> +
> +config MACH_MX28EVK
> +	bool "MX28 EVK platform"
> +	select IMX_HAVE_PLATFORM_DUART
> +	help
> +	  Include support for MX28 EVK platform. This includes specific
> +	  configurations for the board and its peripherals.
> +
> +endif
> +
please remove the new line at EOF.

> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index 5582692..3b12218 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -14,6 +14,8 @@ obj-$(CONFIG_MACH_MX21) += clock-imx21.o mm-imx21.o
>  obj-$(CONFIG_MACH_MX27) += cpu-imx27.o pm-imx27.o
>  obj-$(CONFIG_MACH_MX27) += clock-imx27.o mm-imx27.o
>  
> +obj-$(CONFIG_ARCH_MX28) += clock-imx28.o mm-imx28.o
> +
>  # Support for CMOS sensor interface
>  obj-$(CONFIG_MX1_VIDEO)	+= mx1-camera-fiq.o mx1-camera-fiq-ksym.o
>  
> @@ -32,3 +34,5 @@ obj-$(CONFIG_MACH_CPUIMX27) += mach-cpuimx27.o
>  obj-$(CONFIG_MACH_EUKREA_MBIMX27_BASEBOARD) += eukrea_mbimx27-baseboard.o
>  obj-$(CONFIG_MACH_PCA100) += mach-pca100.o
>  obj-$(CONFIG_MACH_MXT_TD60) += mach-mxt_td60.o
> +
> +obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
> diff --git a/arch/arm/mach-imx/Makefile.boot b/arch/arm/mach-imx/Makefile.boot
> index 7988a85..fd451d0 100644
> --- a/arch/arm/mach-imx/Makefile.boot
> +++ b/arch/arm/mach-imx/Makefile.boot
> @@ -9,3 +9,7 @@ initrd_phys-$(CONFIG_MACH_MX21)	:= 0xC0800000
>  zreladdr-$(CONFIG_MACH_MX27)	:= 0xA0008000
>  params_phys-$(CONFIG_MACH_MX27)	:= 0xA0000100
>  initrd_phys-$(CONFIG_MACH_MX27)	:= 0xA0800000
> +
> +zreladdr-$(CONFIG_ARCH_MX28)	:= 0x40008000
> +params_phys-$(CONFIG_ARCH_MX28)	:= 0x40000100
> +initrd_phys-$(CONFIG_ARCH_MX28)	:= 0x40800000
> diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
> index 680aeba..fd7ec19 100644
> --- a/arch/arm/plat-mxc/Kconfig
> +++ b/arch/arm/plat-mxc/Kconfig
> @@ -25,6 +25,12 @@ config ARCH_MX25
>  	help
>  	  This enables support for systems based on the Freescale i.MX25 family
>  
> +config ARCH_MX28
> +	bool "MX28-based"
> +	select SOC_IMX28
Can you please let the machines select SOC_IMX28?

> +	help
> +	  This enables support for systems based on the Freescale i.MX28 family
> +
>  config ARCH_MX3
>  	bool "MX3-based"
>  	select CPU_V6
> @@ -68,6 +74,9 @@ config MXC_TZIC
>  config MXC_AVIC
>  	bool
>  
> +config MXC_ICOLL
> +	bool
> +
>  config MXC_PWM
>  	tristate "Enable PWM driver"
>  	select HAVE_PWM
> @@ -109,6 +118,9 @@ config IMX_HAVE_IOMUX_V1
>  config ARCH_MXC_IOMUX_V3
>  	bool
>  
> +config ARCH_MXC_IOMUX_PINCTRL
> +	bool
> +
>  config ARCH_MXC_AUDMUX_V1
>  	bool
>  
> diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
> index 0e12591..e194468 100644
> --- a/arch/arm/plat-mxc/Makefile
> +++ b/arch/arm/plat-mxc/Makefile
> @@ -5,12 +5,14 @@
>  # Common support
>  obj-y := 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_MXC_AVIC) += avic.o
> +obj-$(CONFIG_MXC_ICOLL) += icoll.o
>  
>  obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
>  obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
> +obj-$(CONFIG_ARCH_MXC_IOMUX_PINCTRL) += iomux-pinctrl.o
> +
>  obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
>  obj-$(CONFIG_MXC_PWM)  += pwm.o
>  obj-$(CONFIG_USB_EHCI_MXC) += ehci.o
> diff --git a/arch/arm/plat-mxc/devices/Kconfig b/arch/arm/plat-mxc/devices/Kconfig
> index 9aa6f3e..e8860d9 100644
> --- a/arch/arm/plat-mxc/devices/Kconfig
> +++ b/arch/arm/plat-mxc/devices/Kconfig
> @@ -1,3 +1,6 @@
> +config IMX_HAVE_PLATFORM_DUART
> +	bool
> +
>  config IMX_HAVE_PLATFORM_ESDHC
>  	bool
>  
> diff --git a/arch/arm/plat-mxc/devices/Makefile b/arch/arm/plat-mxc/devices/Makefile
> index 45aefeb..11e2fcf 100644
> --- a/arch/arm/plat-mxc/devices/Makefile
> +++ b/arch/arm/plat-mxc/devices/Makefile
> @@ -1,3 +1,4 @@
> +obj-$(CONFIG_IMX_HAVE_PLATFORM_DUART) += platform-duart.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_ESDHC) += platform-esdhc.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_FEC) += platform-fec.o
>  obj-$(CONFIG_IMX_HAVE_PLATFORM_FLEXCAN) += platform-flexcan.o
> -- 
> 1.7.1
> 
> 
> 

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
  2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
                   ` (10 preceding siblings ...)
  2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
@ 2010-11-16 10:15 ` Sascha Hauer
  2010-11-16 12:42   ` Shawn Guo
  11 siblings, 1 reply; 28+ messages in thread
From: Sascha Hauer @ 2010-11-16 10:15 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
> This patchset adds the initial support of i.MX28, and the target device
> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
> and adding codes into arch/arm/mxc and arch/arm/mach-imx.

Without further looking at the patch I agree with Uwe: The i.MX23/28
are totally different from the other i.MX SoCs and should not be
integrated in current i.MX support. And definitely it should not be
integrated by adding cpu_is_* into each and every function.

Now you have two choices: Add the code to plat-stmp3xxx (for the
interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
add a new mach-mxs like you did in the Freescale Kernel.
I'm not sure which choice of these two is best. It would be good to get
some other opinions from people who already had the situation that a
vendor got sold and we get the same old metal with new names.

BTW the imx-single-kernel branch is a branch to show where things might
or might not go. You should not base your work on this.

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] 28+ messages in thread

* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
  2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
@ 2010-11-16 12:42   ` Shawn Guo
  2010-11-16 17:24     ` Uwe Kleine-König
  0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-16 12:42 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Sascha,

Thanks for the comments.  Please see my comments below.

On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> Hello Shawn,
>
> On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
>> This patchset adds the initial support of i.MX28, and the target device
>> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
>> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
>
> Without further looking at the patch I agree with Uwe: The i.MX23/28
> are totally different from the other i.MX SoCs and should not be
> integrated in current i.MX support. And definitely it should not be
> integrated by adding cpu_is_* into each and every function.
>
cpu_is_* is not being added into each and every function. Uwe had this
comment on only two files, arch/arm/plat-mxc/gpio.c and
arch/arm/plat-mxc/time.c. As there are big percentage of
infrastructural common codes that are IP block independent, I though
it's good to use the same file.  But since you are not in this
position, I would propose another option. Like what I'm doing with
iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
based time implementation.

The philosophy behind this is we treat arch/arm/plat-mxc as the
Freescale IP block pool.  The driver in this folder is IP block
oriented other than SoC oriented.  And SoC is actually a collection of
IP blocks.  MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
AVIC/TZIC.  Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
avic.c/tzic.c in.  The only thing we need to deal with is picking up
the file name to stand for the IP block.

> Now you have two choices: Add the code to plat-stmp3xxx (for the
> interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
> add a new mach-mxs like you did in the Freescale Kernel.
> I'm not sure which choice of these two is best. It would be good to get
> some other opinions from people who already had the situation that a
> vendor got sold and we get the same old metal with new names.
>
Yes, MX23/28 are based on former Sigmatel SoCs.  The imx-single-kernel
demonstrates the possibility of single image for different SoCs from
same vendor.  My patchset somehow adds the the possibility for SoCs
even from different vendors, even though I'm unsure if single image
for SoCs from different vendor is something ARM Kernel will possibly
go in the future?

The plat-stmp3xxx is not an option for me because of the Freescale
marketing concern.  For the choice of what Freescale Kernel is doing,
there is no mach-mxs.  Instead, there are arch/arm/plat-mxs,
arch/arm/mach-mx23 and arch/arm/mach-mx28.  Going this way, MX23/28
will be totally separated from i.MX family, though their name tells
the relationship with i.MX family.  Also, Freescale is merging the
Sigmatel IP pool into i.MX one and will only maintain the same pool.
In another words, Sigmatel IP block are getting consolidated with i.MX
ones. You can still say MX28 are former Sigmatel based, but it gets
i.MX IP blocks, FEC(ENET), FlexCAN integrated.  If MX28 is not so
typical, MX50 can be the one.  It primarily derives from MX51/MX53 and
will go into plat-mxc and mach-mx5 in common understanding, but it
gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
GPMI, DCP, APHB DMA, and so on.  SoC is merging these two families
into one.  It makes no sense for SW to keeps them separated.

Can you please think about the IP oriented way I mentioned above to
see if there is any problem that stops us going?  Also do you want to
eventually include MX23/28 into imx-single-kernel image?  If you do,
don't you think my proposal will make it a little bit easier?

> BTW the imx-single-kernel branch is a branch to show where things might
> or might not go. You should not base your work on this.
>
> 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 |
>



-- 
Regards,
Shawn

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

* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
  2010-11-16 12:42   ` Shawn Guo
@ 2010-11-16 17:24     ` Uwe Kleine-König
  2010-11-17  1:28       ` Shawn Guo
  0 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-16 17:24 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Shawn,

On Tue, Nov 16, 2010 at 08:42:29PM +0800, Shawn Guo wrote:
> On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> > Hello Shawn,
> >
> > On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
> >> This patchset adds the initial support of i.MX28, and the target device
> >> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
> >> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
> >
> > Without further looking at the patch I agree with Uwe: The i.MX23/28
> > are totally different from the other i.MX SoCs and should not be
> > integrated in current i.MX support. And definitely it should not be
> > integrated by adding cpu_is_* into each and every function.
> >
> cpu_is_* is not being added into each and every function. Uwe had this
> comment on only two files, arch/arm/plat-mxc/gpio.c and
I consider the irq handling very ugly, but I didn't feel like repeating
the same argument gives much value.  (And OK, the irq handling was ugly
already before, that's on my plate to evaluate.)  I didn't recheck where
I thought the runtime checks were non-optimal, but seeing to much of
them makes me feel that this is the wrong approach.  This is more a
subjective thing and for that it's independant if there are one, two or
five instances.

> arch/arm/plat-mxc/time.c. As there are big percentage of
> infrastructural common codes that are IP block independent, I though
> it's good to use the same file.  But since you are not in this
> position, I would propose another option. Like what I'm doing with
> iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
> arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
> based time implementation.
> 
> The philosophy behind this is we treat arch/arm/plat-mxc as the
> Freescale IP block pool.  The driver in this folder is IP block
> oriented other than SoC oriented.  And SoC is actually a collection of
> IP blocks.  MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
> MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
> AVIC/TZIC.  Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
> icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
> avic.c/tzic.c in.  The only thing we need to deal with is picking up
> the file name to stand for the IP block.
For me (not having seen mx50) integrating mx28 into mach-imx seems
wrong.  Currently they are completely orthogonal for the components that
matter for architecture support (i.e. timer, irq handling, clocks, pin
muxing, power management and to a slightly lesser degree gpio and memory
mapping).

> > Now you have two choices: Add the code to plat-stmp3xxx (for the
> > interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
> > add a new mach-mxs like you did in the Freescale Kernel.
> > I'm not sure which choice of these two is best. It would be good to get
> > some other opinions from people who already had the situation that a
> > vendor got sold and we get the same old metal with new names.
> >
> Yes, MX23/28 are based on former Sigmatel SoCs.  The imx-single-kernel
> demonstrates the possibility of single image for different SoCs from
> same vendor.  My patchset somehow adds the the possibility for SoCs
> even from different vendors, even though I'm unsure if single image
> for SoCs from different vendor is something ARM Kernel will possibly
> go in the future?
That's one of the goals of Linaro.  I'd prefer to get an
"really-all-i.MX" image via this more global approach.

> The plat-stmp3xxx is not an option for me because of the Freescale
> marketing concern.  For the choice of what Freescale Kernel is doing,
I prefer technical arguments here.  Just because some guys in the
marketing department consider giving similar names to completely
different products *I* don't believe grouping them together in the
source code makes more sense.  (It just reinforces my opinion about
marketing guys :-)

> there is no mach-mxs.  Instead, there are arch/arm/plat-mxs,
> arch/arm/mach-mx23 and arch/arm/mach-mx28.  Going this way, MX23/28
> will be totally separated from i.MX family, though their name tells
Adding mach-mx23, mach-mx28 and plat-mxs is (IMHO) too much.  mx23 and
mx28 are similar enough to put both of the two into a single mach
directory.  So seeing the naming choices Freescale did for their kernel
mach-mxs looks reasonable to me.

> the relationship with i.MX family.  Also, Freescale is merging the
This wouldn't be worse than what we had before I merged mach-mx1 and
mach-mx2 into mach-imx for 2.6.36: mach-mx1, mach-mx2, mach-mx25,
mach-mx3 and mach-mx5.

> Sigmatel IP pool into i.MX one and will only maintain the same pool.
> In another words, Sigmatel IP block are getting consolidated with i.MX
> ones. You can still say MX28 are former Sigmatel based, but it gets
> i.MX IP blocks, FEC(ENET), FlexCAN integrated.  If MX28 is not so
This is natural and OK.  But these components are no reason to put mx28
into mach-imx.  The respective drivers live in drivers/net and
drivers/net/can.  So at best they can share the imx_add_device_du_jour
functions.  Here I'd suggest to make these functions available for all
ARMs (or even all archs).

> typical, MX50 can be the one.  It primarily derives from MX51/MX53 and
> will go into plat-mxc and mach-mx5 in common understanding, but it
Let's discuss that when you come up with mx50 patches :-)

> gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
> GPMI, DCP, APHB DMA, and so on.  SoC is merging these two families
> into one.  It makes no sense for SW to keeps them separated.
I don't want to separate things artificially that belong together, but I
don't want to put things together that are really seperate, too.
 
> Can you please think about the IP oriented way I mentioned above to
> see if there is any problem that stops us going?  Also do you want to
> eventually include MX23/28 into imx-single-kernel image?  If you do,
> don't you think my proposal will make it a little bit easier?
It might be easier, yes, but there are also some other criterias that
matter, like maintainability, efficiency of compiled code etc.  And I
think when taking these into account using a different machine directory
is the right choice.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
  2010-11-16 17:24     ` Uwe Kleine-König
@ 2010-11-17  1:28       ` Shawn Guo
  2010-11-17  6:06         ` Uwe Kleine-König
  0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-17  1:28 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Uwe,

2010/11/17 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Tue, Nov 16, 2010 at 08:42:29PM +0800, Shawn Guo wrote:
>> On Tue, Nov 16, 2010 at 6:15 PM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
>> > Hello Shawn,
>> >
>> > On Mon, Nov 15, 2010 at 10:36:24PM +0800, Shawn Guo wrote:
>> >> This patchset adds the initial support of i.MX28, and the target device
>> >> is i.MX28 EVK Rev C. It's based on the imx-single-kernel branch below,
>> >> and adding codes into arch/arm/mxc and arch/arm/mach-imx.
>> >
>> > Without further looking at the patch I agree with Uwe: The i.MX23/28
>> > are totally different from the other i.MX SoCs and should not be
>> > integrated in current i.MX support. And definitely it should not be
>> > integrated by adding cpu_is_* into each and every function.
>> >
>> cpu_is_* is not being added into each and every function. Uwe had this
>> comment on only two files, arch/arm/plat-mxc/gpio.c and
> I consider the irq handling very ugly, but I didn't feel like repeating
> the same argument gives much value. ?(And OK, the irq handling was ugly
> already before, that's on my plate to evaluate.) ?I didn't recheck where
> I thought the runtime checks were non-optimal, but seeing to much of
> them makes me feel that this is the wrong approach. ?This is more a
> subjective thing and for that it's independant if there are one, two or
> five instances.
>
>> arch/arm/plat-mxc/time.c. As there are big percentage of
>> infrastructural common codes that are IP block independent, I though
>> it's good to use the same file. ?But since you are not in this
>> position, I would propose another option. Like what I'm doing with
>> iomux-pinctrl, we can create arch/arm/plat-mxc/gpio-pinctrl.c and
>> arch/arm/plat-mxc/time-timrot.c for PINCTRL based gpio and TIMROT
>> based time implementation.
>>
>> The philosophy behind this is we treat arch/arm/plat-mxc as the
>> Freescale IP block pool. ?The driver in this folder is IP block
>> oriented other than SoC oriented. ?And SoC is actually a collection of
>> IP blocks. ?MX23/MX28 integrates PINCTRL, TIMROT, ICOLL, and
>> MX21/MX25/MX27/MX31/MX35/MX51 integrates GPIO/IOMUXC, GPT and
>> AVIC/TZIC. ?Accordingly, MX23/MX28 builds gpio-pinctrl.c, timrot.c and
>> icoll.c in, and other i.MX builds gpio.c, iomux-v1//v2/v3,
>> avic.c/tzic.c in. ?The only thing we need to deal with is picking up
>> the file name to stand for the IP block.
> For me (not having seen mx50) integrating mx28 into mach-imx seems
> wrong. ?Currently they are completely orthogonal for the components that
> matter for architecture support (i.e. timer, irq handling, clocks, pin
> muxing, power management and to a slightly lesser degree gpio and memory
> mapping).
>
>> > Now you have two choices: Add the code to plat-stmp3xxx (for the
>> > interested reader: the i.MX23/28 are based on former Sigmatel SoCs), or
>> > add a new mach-mxs like you did in the Freescale Kernel.
>> > I'm not sure which choice of these two is best. It would be good to get
>> > some other opinions from people who already had the situation that a
>> > vendor got sold and we get the same old metal with new names.
>> >
>> Yes, MX23/28 are based on former Sigmatel SoCs. ?The imx-single-kernel
>> demonstrates the possibility of single image for different SoCs from
>> same vendor. ?My patchset somehow adds the the possibility for SoCs
>> even from different vendors, even though I'm unsure if single image
>> for SoCs from different vendor is something ARM Kernel will possibly
>> go in the future?
> That's one of the goals of Linaro. ?I'd prefer to get an
> "really-all-i.MX" image via this more global approach.
>
>> The plat-stmp3xxx is not an option for me because of the Freescale
>> marketing concern. ?For the choice of what Freescale Kernel is doing,
> I prefer technical arguments here. ?Just because some guys in the
> marketing department consider giving similar names to completely
> different products *I* don't believe grouping them together in the
> source code makes more sense. ?(It just reinforces my opinion about
> marketing guys :-)
>
>> there is no mach-mxs. ?Instead, there are arch/arm/plat-mxs,
>> arch/arm/mach-mx23 and arch/arm/mach-mx28. ?Going this way, MX23/28
>> will be totally separated from i.MX family, though their name tells
> Adding mach-mx23, mach-mx28 and plat-mxs is (IMHO) too much. ?mx23 and
> mx28 are similar enough to put both of the two into a single mach
> directory. ?So seeing the naming choices Freescale did for their kernel
> mach-mxs looks reasonable to me.
>
>> the relationship with i.MX family. ?Also, Freescale is merging the
> This wouldn't be worse than what we had before I merged mach-mx1 and
> mach-mx2 into mach-imx for 2.6.36: mach-mx1, mach-mx2, mach-mx25,
> mach-mx3 and mach-mx5.
>
>> Sigmatel IP pool into i.MX one and will only maintain the same pool.
>> In another words, Sigmatel IP block are getting consolidated with i.MX
>> ones. You can still say MX28 are former Sigmatel based, but it gets
>> i.MX IP blocks, FEC(ENET), FlexCAN integrated. ?If MX28 is not so
> This is natural and OK. ?But these components are no reason to put mx28
> into mach-imx. ?The respective drivers live in drivers/net and
> drivers/net/can. ?So at best they can share the imx_add_device_du_jour
> functions. ?Here I'd suggest to make these functions available for all
> ARMs (or even all archs).
>
>> typical, MX50 can be the one. ?It primarily derives from MX51/MX53 and
>> will go into plat-mxc and mach-mx5 in common understanding, but it
> Let's discuss that when you come up with mx50 patches :-)
>
>> gets a lot of MX28 (Sigmatel) based IP blocks integrated, LCDIF, PXP,
>> GPMI, DCP, APHB DMA, and so on. ?SoC is merging these two families
>> into one. ?It makes no sense for SW to keeps them separated.
> I don't want to separate things artificially that belong together, but I
> don't want to put things together that are really seperate, too.
>
>> Can you please think about the IP oriented way I mentioned above to
>> see if there is any problem that stops us going? ?Also do you want to
>> eventually include MX23/28 into imx-single-kernel image? ?If you do,
>> don't you think my proposal will make it a little bit easier?
> It might be easier, yes, but there are also some other criterias that
> matter, like maintainability, efficiency of compiled code etc. ?And I
> think when taking these into account using a different machine directory
> is the right choice.
>
plat-stmp3xxx is not an option for me.  Another reason is it has the
support for mach-stmp37xx.  If I change anything in plat-stmp3xxx, I
can not even find a board to test mach-stmp37xx.  For me
plat-stmp3xxx, mach-stmp37xx and mach-stmp378x seem out of
maintaining.  I do not see they are moving.

So at the end of the day, mach-mxs + plat-mxs becomes the option that
could work for both of us, right?  Correct me I misunderstood your
comments.


> Best regards
> Uwe
>
> --
> Pengutronix e.K. ? ? ? ? ? ? ? ? ? ? ? ? ? | Uwe Kleine-K?nig ? ? ? ? ? ?|
> Industrial Linux Solutions ? ? ? ? ? ? ? ? | http://www.pengutronix.de/ ?|
>



-- 
Regards,
Shawn

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

* [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support
  2010-11-17  1:28       ` Shawn Guo
@ 2010-11-17  6:06         ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-17  6:06 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Shawn,

> plat-stmp3xxx is not an option for me.  Another reason is it has the
> support for mach-stmp37xx.  If I change anything in plat-stmp3xxx, I
> can not even find a board to test mach-stmp37xx.  For me
> plat-stmp3xxx, mach-stmp37xx and mach-stmp378x seem out of
> maintaining.  I do not see they are moving.
> 
> So at the end of the day, mach-mxs + plat-mxs becomes the option that
> could work for both of us, right?  Correct me I misunderstood your
> comments.
As long as you don't use more than mach directory there is no need to
populate plat-mxs.  Everything can go into mach-mxs.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
  2010-11-15 16:36   ` Uwe Kleine-König
@ 2010-11-17 11:17     ` Shawn Guo
  2010-11-17 13:44       ` Uwe Kleine-König
  0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-11-17 11:17 UTC (permalink / raw)
  To: linux-arm-kernel

2010/11/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
>> +#ifdef CONFIG_ARCH_MX28
>> +int mxc_reset_block(void __iomem *reg_addr)
>> +{
>> + ? ? u32 reg;
>> + ? ? int timeout;
>> +
>> + ? ? /*
>> + ? ? ?* The process of software reset of IP block is done
>> + ? ? ?* in several steps:
>> + ? ? ?*
>> + ? ? ?* 1) clear SFTRST and wait it cleared;
>> + ? ? ?* 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
>> + ? ? ?* 3) clear SFTRST and wait it cleared;
>> + ? ? ?* 4) clear CLKGATE and wait it cleared.
>> + ? ? ?*/
>> +
>> + ? ? /* Clear SFTRST */
>> + ? ? reg = __raw_readl(reg_addr);
>> + ? ? reg &= ~(1 << 31);
>> + ? ? __raw_writel(reg, reg_addr);
>> + ? ? /* Wait SFTRST cleared */
>> + ? ? timeout = 1000;
>> + ? ? do {
>> + ? ? ? ? ? ? mdelay(1);
>> + ? ? ? ? ? ? if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
>> + ? ? ? ? ? ? ? ? ? ? break;
>> + ? ? } while (--timeout > 0);
> Does the mdelay make sence here?
>
i.MX28 Application Processor Reference Manual, Chapter 39.5.10
"Correct Way to Software Reset a Block".

-- 
Regards,
Shawn

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

* [PATCH 03/11] ARM: imx: Add reset routine for i.MX28
  2010-11-17 11:17     ` Shawn Guo
@ 2010-11-17 13:44       ` Uwe Kleine-König
  0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-11-17 13:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Nov 17, 2010 at 07:17:39PM +0800, Shawn Guo wrote:
> 2010/11/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Mon, Nov 15, 2010 at 10:36:27PM +0800, Shawn Guo wrote:
> >> +#ifdef CONFIG_ARCH_MX28
> >> +int mxc_reset_block(void __iomem *reg_addr)
> >> +{
> >> + ? ? u32 reg;
> >> + ? ? int timeout;
> >> +
> >> + ? ? /*
> >> + ? ? ?* The process of software reset of IP block is done
> >> + ? ? ?* in several steps:
> >> + ? ? ?*
> >> + ? ? ?* 1) clear SFTRST and wait it cleared;
> >> + ? ? ?* 2) clear CLKGATE, set SFTRST, wait CLKGATE set;
> >> + ? ? ?* 3) clear SFTRST and wait it cleared;
> >> + ? ? ?* 4) clear CLKGATE and wait it cleared.
> >> + ? ? ?*/
> >> +
> >> + ? ? /* Clear SFTRST */
> >> + ? ? reg = __raw_readl(reg_addr);
> >> + ? ? reg &= ~(1 << 31);
> >> + ? ? __raw_writel(reg, reg_addr);
> >> + ? ? /* Wait SFTRST cleared */
> >> + ? ? timeout = 1000;
> >> + ? ? do {
> >> + ? ? ? ? ? ? mdelay(1);
> >> + ? ? ? ? ? ? if ((__raw_readl(reg_addr) & (1 << 31)) == 0)
> >> + ? ? ? ? ? ? ? ? ? ? break;
> >> + ? ? } while (--timeout > 0);
> > Does the mdelay make sence here?
> >
> i.MX28 Application Processor Reference Manual, Chapter 39.5.10
> "Correct Way to Software Reset a Block".
Quoting the chapter you pointed out:

	// Prepare for soft-reset by making sure that SFTRST is not currently
	// asserted. Also clear CLKGATE so we can wait for its assertion below.
	HW_GPMI_CTRL0_CLR(BM_GPMI_CTRL0_SFTRST);
	// Wait at least a microsecond for SFTRST to deassert. In actuality, we
	// need to wait 3 GPMI clocks, but this is much easier to implement.
	musecs = hw_profile_GetMicroseconds();
	while (HW_GPMI_CTRL0.B.SFTRST || (hw_profile_GetMicroseconds() - musecs <
	DDI_NAND_HAL_GPMI_SOFT_RESET_LATENCY));
	[...]

This talks about a microsecond, not a millisecond.

Expecting that most of the time not a whole millisecond is needed, I'd
do something like that:

	val = __raw_readl(reset_addr);
	val &= ~MX28_MODULERESET_SFTRST;
	__raw_writel(val, reset_addr);

	/*
	 * SFTRST needs 3 GPMI clocks to settle, the reference manual
         * recommends to wait 1us.
	 */
	udelay(1);

	timeout = 0x400;
	while ((__raw_readl(reset_addr) & MX28_MODULERESET_SFTRST) && --timeout)
		/* nothing /*;

	if (!timeout)
		goto error;

That is do a busy read and don't busy wait a millisecond between two
consecutive reads just twiddling thumbs.

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-K?nig            |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

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

end of thread, other threads:[~2010-11-17 13:44 UTC | newest]

Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-15 14:36 [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Shawn Guo
2010-11-15 14:36 ` [PATCH 01/11] ARM: imx: Add basic definitions for i.MX28 Shawn Guo
2010-11-15 16:25   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 02/11] ARM: imx: Add support of interrupt controller ICOLL Shawn Guo
2010-11-15 16:33   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 03/11] ARM: imx: Add reset routine for i.MX28 Shawn Guo
2010-11-15 16:36   ` Uwe Kleine-König
2010-11-17 11:17     ` Shawn Guo
2010-11-17 13:44       ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 04/11] ARM: imx: Add timer support " Shawn Guo
2010-11-15 16:40   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 05/11] ARM: imx: Add GPIO " Shawn Guo
2010-11-15 16:43   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 06/11] ARM: imx: Add IOMUX " Shawn Guo
2010-11-15 16:46   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 07/11] ARM: imx: Add support of uncompress print " Shawn Guo
2010-11-15 16:47   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 08/11] ARM: imx: Add clock support " Shawn Guo
2010-11-15 14:36 ` [PATCH 09/11] ARM: imx: Add memory map " Shawn Guo
2010-11-15 14:36 ` [PATCH 10/11] ARM: imx: Add initial support of machine mx28evk Shawn Guo
2010-11-15 16:54   ` Uwe Kleine-König
2010-11-15 14:36 ` [PATCH 11/11] ARM: imx: Add i.MX28 support into Kconfig and Makefile Shawn Guo
2010-11-15 17:01   ` Uwe Kleine-König
2010-11-16 10:15 ` [RFC][PATCH 00/11] ARM: imx: Add initial i.MX28 support Sascha Hauer
2010-11-16 12:42   ` Shawn Guo
2010-11-16 17:24     ` Uwe Kleine-König
2010-11-17  1:28       ` Shawn Guo
2010-11-17  6:06         ` Uwe Kleine-König

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.