mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] i.MX28 architecture inclusion into barebox
@ 2010-12-13 10:53 Juergen Beisert
  2010-12-13 10:53 ` [PATCH 01/14] Make DIV_ROUND_UP macro globally available Juergen Beisert
                   ` (13 more replies)
  0 siblings, 14 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

This patch stack adds the new Freescale i.MX28 CPU as a basic implementation
to barebox. This new CPU shares most components with the existing i.MX23
(former STM378x), but also some components with the existing IMX. So, this
patch stack has to touch i.MX23 related files and also some IMX related ones.
As a user of this implementation the stack comes with support for the KARO
TX28 CPU card and its evaluation starterkit-5.

The following changes since commit 4f21f1ec978c5cb43a25d1b52a49ff5fe84d4206:

  arm: update mach-types (2010-12-10 10:06:18 +0100)

are available in the git repository at:
  http://git.pengutronix.de/git/jbe/for_barebox_next/ next_iMX28v4

Juergen Beisert (14):
      Make DIV_ROUND_UP macro globally available
      Add macro for correct rounding in integer devisions
      STM378x: Use Hz as the clock unit like in all other arch
      STM378x: Do not configure any pin usage in the driver
      STM378x: Parameterize the max. possible GPIO number
      STM378x: Separate i.MX23 clock handling
      IMX: Ignore i.MX23/i.MX28 related code in shared devices
      STM378x: Add i.MX28 architecture
      STM378x: Adapt the serial driver to support i.MX23 and i.MX28
      STM378x: Adapt the MCI driver to support i.MX23 and i.MX28
      Fixup the FEC driver files
      MX28: add FEC support
      STM378x: Add TX28 CPU module
      STM378x: Add the TX28 Starterkit-5 baseboard

 Documentation/boards.dox                         |    1 +
 arch/arm/Makefile                                |    1 +
 arch/arm/boards/karo-tx28/Makefile               |    2 +
 arch/arm/boards/karo-tx28/config.h               |   16 +
 arch/arm/boards/karo-tx28/env/config             |   47 ++
 arch/arm/boards/karo-tx28/tx28-stk5.c            |  229 +++++++++
 arch/arm/boards/karo-tx28/tx28.c                 |  156 ++++++
 arch/arm/configs/tx28stk5_defconfig              |   38 ++
 arch/arm/mach-imx/include/mach/generic.h         |    2 +
 arch/arm/mach-stm/Kconfig                        |   36 ++
 arch/arm/mach-stm/Makefile                       |    5 +-
 arch/arm/mach-stm/clocksource-imx28.c            |   73 +++
 arch/arm/mach-stm/{imx23.c => imx.c}             |    0
 arch/arm/mach-stm/include/mach/clock-imx23.h     |   26 +
 arch/arm/mach-stm/include/mach/clock-imx28.h     |   29 ++
 arch/arm/mach-stm/include/mach/clock.h           |   22 +-
 arch/arm/mach-stm/include/mach/generic.h         |    6 +
 arch/arm/mach-stm/include/mach/gpio.h            |    3 +
 arch/arm/mach-stm/include/mach/imx-regs.h        |    9 +
 arch/arm/mach-stm/include/mach/imx28-regs.h      |   47 ++
 arch/arm/mach-stm/include/mach/iomux-imx28.h     |  552 ++++++++++++++++++++++
 arch/arm/mach-stm/{iomux-imx23.c => iomux-imx.c} |   29 +-
 arch/arm/mach-stm/{reset-imx23.c => reset-imx.c} |    0
 arch/arm/mach-stm/speed-imx23.c                  |   52 +-
 arch/arm/mach-stm/speed-imx28.c                  |  392 +++++++++++++++
 drivers/mci/Kconfig                              |    4 +-
 drivers/mci/stm378x.c                            |  141 +++++-
 drivers/net/fec_imx.c                            |   95 +++-
 drivers/net/fec_imx.h                            |   21 +-
 drivers/serial/Kconfig                           |    2 +-
 drivers/serial/stm-serial.c                      |    9 +-
 drivers/spi/imx_spi.c                            |    3 -
 include/common.h                                 |    9 +
 33 files changed, 1955 insertions(+), 102 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/Makefile
 create mode 100644 arch/arm/boards/karo-tx28/config.h
 create mode 100644 arch/arm/boards/karo-tx28/env/config
 create mode 100644 arch/arm/boards/karo-tx28/tx28-stk5.c
 create mode 100644 arch/arm/boards/karo-tx28/tx28.c
 create mode 100644 arch/arm/configs/tx28stk5_defconfig
 create mode 100644 arch/arm/mach-stm/clocksource-imx28.c
 rename arch/arm/mach-stm/{imx23.c => imx.c} (100%)
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx23.h
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx28.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx28-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx28.h
 rename arch/arm/mach-stm/{iomux-imx23.c => iomux-imx.c} (82%)
 rename arch/arm/mach-stm/{reset-imx23.c => reset-imx.c} (100%)
 create mode 100644 arch/arm/mach-stm/speed-imx28.c


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 01/14] Make DIV_ROUND_UP macro globally available
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 02/14] Add macro for correct rounding in integer devisions Juergen Beisert
                   ` (12 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/speed-imx23.c |    3 +--
 drivers/spi/imx_spi.c           |    3 ---
 include/common.h                |    2 ++
 3 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
index 7418ad5..f32ae92 100644
--- a/arch/arm/mach-stm/speed-imx23.c
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -244,8 +244,7 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
 		printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
 		ssp_div = 1U;
 	} else {
-		ssp_div += nc - 1U;
-		ssp_div /= nc;
+		ssp_div = DIV_ROUND_UP(ssp_div, nc);
 		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
 			ssp_div = CLKCTRL_SSP_DIV_MASK;
 	}
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 2ad1bfa..1857d6c 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -224,9 +224,6 @@ static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
 	return readl(base + CSPI_2_3_RXDATA);
 }
 
-/* FIXME: include/linux/kernel.h */
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
 static unsigned int cspi_2_3_clkdiv(unsigned int fin, unsigned int fspi)
 {
 	/*
diff --git a/include/common.h b/include/common.h
index a14bfc1..be83a31 100644
--- a/include/common.h
+++ b/include/common.h
@@ -222,4 +222,6 @@ extern const char version_string[];
 
 #define IOMEM(addr)	((void __force __iomem *)(addr))
 
+#define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 02/14] Add macro for correct rounding in integer devisions
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
  2010-12-13 10:53 ` [PATCH 01/14] Make DIV_ROUND_UP macro globally available Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch Juergen Beisert
                   ` (11 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Just stolen from Linux.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 drivers/mci/stm378x.c |    2 +-
 include/common.h      |    7 +++++++
 2 files changed, 8 insertions(+), 1 deletions(-)

diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index 039fbb9..a2802af 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -484,7 +484,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 	ssp = imx_get_sspclk(0) * 1000;
 
 	for (div = 2; div < 255; div += 2) {
-		rate = (((ssp + (nc >> 1) ) / nc) + (div >> 1)) / div;
+		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
 		if (rate <= 0x100)
 			break;
 	}
diff --git a/include/common.h b/include/common.h
index be83a31..1bea10c 100644
--- a/include/common.h
+++ b/include/common.h
@@ -224,4 +224,11 @@ extern const char version_string[];
 
 #define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
 
+#define DIV_ROUND_CLOSEST(x, divisor)(			\
+{							\
+	typeof(divisor) __divisor = divisor;		\
+	(((x) + ((__divisor) / 2)) / (__divisor));	\
+}							\
+)
+
 #endif	/* __COMMON_H_ */
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
  2010-12-13 10:53 ` [PATCH 01/14] Make DIV_ROUND_UP macro globally available Juergen Beisert
  2010-12-13 10:53 ` [PATCH 02/14] Add macro for correct rounding in integer devisions Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 04/14] STM378x: Do not configure any pin usage in the driver Juergen Beisert
                   ` (10 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

i.MX23 currently uses kHz as the unit for its clock handling and calculation
to avoid overflows when calculation with the internal 480 MHz PLL and its
fractional divider. This patch changes all routines to accept Hz and deliver
Hz as the clock unit.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/speed-imx23.c |   49 +++++++++++++++++++--------------------
 drivers/mci/stm378x.c           |   10 ++++----
 drivers/serial/stm-serial.c     |    2 +-
 3 files changed, 30 insertions(+), 31 deletions(-)

diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
index f32ae92..a31139d 100644
--- a/arch/arm/mach-stm/speed-imx23.c
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -29,8 +29,6 @@
 #include <mach/generic.h>
 #include <mach/clock.h>
 
-/* Note: all clock frequencies are returned in kHz */
-
 #define HW_CLKCTRL_PLLCTRL0 0x000
 #define HW_CLKCTRL_PLLCTRL1 0x010
 #define HW_CLKCTRL_CPU 0x20
@@ -84,13 +82,13 @@
 unsigned imx_get_mpllclk(void)
 {
 	/* the main PLL runs at 480 MHz */
-	return 480U * 1000U;
+	return 480000000;
 }
 
 unsigned imx_get_xtalclk(void)
 {
 	/* the external reference runs at 24 MHz */
-	return 24U * 1000U;
+	return 24000000;
 }
 
 /* used for the SDRAM controller */
@@ -105,14 +103,15 @@ unsigned imx_get_emiclk(void)
 	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
 		return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
 
-	rate = imx_get_mpllclk();
+	rate = imx_get_mpllclk() / 1000;
 	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
 	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
 		rate *= 18U;
 		rate /= GET_EMIFRAC(reg);
 	}
 
-	return rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+	return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+			* 1000;
 }
 
 /*
@@ -121,7 +120,7 @@ unsigned imx_get_emiclk(void)
 unsigned imx_get_ioclk(void)
 {
 	uint32_t reg;
-	unsigned rate = imx_get_mpllclk();
+	unsigned rate = imx_get_mpllclk() / 1000;
 
 	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
 	if (reg & CLKCTRL_FRAC_CLKGATEIO)
@@ -129,12 +128,12 @@ unsigned imx_get_ioclk(void)
 
 	rate *= 18U;
 	rate /= GET_IOFRAC(reg);
-	return rate;
+	return rate * 1000;
 }
 
 /**
  * Setup a new frequency to the IOCLK domain.
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
  *
  * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
  */
@@ -143,10 +142,9 @@ unsigned imx_set_ioclk(unsigned nc)
 	uint32_t reg;
 	unsigned div;
 
-	div = imx_get_mpllclk();
-	div *= 18U;
-	div += nc >> 1;
-	div /= nc;
+	nc /= 1000;
+	div = (imx_get_mpllclk() / 1000) * 18;
+	div = DIV_ROUND_CLOSEST(div, nc);
 	if (div > 0x3f)
 		div = 0x3f;
 	/* mask the current settings */
@@ -171,24 +169,25 @@ unsigned imx_get_armclk(void)
 	if (reg & CLKCTRL_FRAC_CLKGATECPU)
 		return 0U;	/* should not possible, shouldn't it? */
 
-	rate = imx_get_mpllclk();
+	rate = imx_get_mpllclk() / 1000;
 	rate *= 18U;
 	rate /= GET_CPUFRAC(reg);
 
-	return rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+	return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+			* 1000;
 }
 
 /* this is the AHB and APBH bus clock */
 unsigned imx_get_hclk(void)
 {
-	unsigned rate = imx_get_armclk();
+	unsigned rate = imx_get_armclk() / 1000;
 
 	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
 		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
 		rate >>= 5U; /* / 32 */
 	} else
 		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
-	return rate;
+	return rate * 1000;
 }
 
 /*
@@ -219,7 +218,7 @@ unsigned imx_get_sspclk(unsigned index)
 
 /**
  * @param index Unit index (ignored on i.MX23)
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
  * @param high != 0 if ioclk should be the source
  * @return The new possible frequency in [kHz]
  */
@@ -269,11 +268,11 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
 
 void imx_dump_clocks(void)
 {
-	printf("mpll:    %10u kHz\n", imx_get_mpllclk());
-	printf("arm:     %10u kHz\n", imx_get_armclk());
-	printf("ioclk:   %10u kHz\n", imx_get_ioclk());
-	printf("emiclk:  %10u kHz\n", imx_get_emiclk());
-	printf("hclk:    %10u kHz\n", imx_get_hclk());
-	printf("xclk:    %10u kHz\n", imx_get_xclk());
-	printf("ssp:     %10u kHz\n", imx_get_sspclk(0));
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk() / 1000);
+	printf("arm:     %10u kHz\n", imx_get_armclk() / 1000);
+	printf("ioclk:   %10u kHz\n", imx_get_ioclk() / 1000);
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk() / 1000);
+	printf("hclk:    %10u kHz\n", imx_get_hclk() / 1000);
+	printf("xclk:    %10u kHz\n", imx_get_xclk() / 1000);
+	printf("ssp:     %10u kHz\n", imx_get_sspclk(0) / 1000);
 }
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index a2802af..fb74822 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -481,7 +481,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 		return 0;
 	}
 
-	ssp = imx_get_sspclk(0) * 1000;
+	ssp = imx_get_sspclk(0);
 
 	for (div = 2; div < 255; div += 2) {
 		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -658,20 +658,20 @@ static int stm_mci_probe(struct device_d *hw_dev)
 	host->host_caps = pd->caps;
 
 	if (pd->f_min == 0) {
-		host->f_min = imx_get_sspclk(0) / 254U / 256U * 1000U;
+		host->f_min = imx_get_sspclk(0) / 254U / 256U;
 		pr_debug("Min. frequency is %u Hz\n", host->f_min);
 	} else {
 		host->f_min = pd->f_min;
 		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
-			host->f_min, imx_get_sspclk(0) / 254U / 256U * 1000U);
+			host->f_min, imx_get_sspclk(0) / 254U / 256U);
 	}
 	if (pd->f_max == 0) {
-		host->f_max = imx_get_sspclk(0) / 2U / 1U * 1000U;
+		host->f_max = imx_get_sspclk(0) / 2U / 1U;
 		pr_debug("Max. frequency is %u Hz\n", host->f_max);
 	} else {
 		host->f_max =  pd->f_max;
 		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
-			host->f_max, imx_get_sspclk(0) / 2U / 1U * 1000U);
+			host->f_max, imx_get_sspclk(0) / 2U / 1U);
 	}
 
 #ifdef CONFIG_MCI_INFO
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 90563f5..3edd484 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -108,7 +108,7 @@ static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
 	writel(0, dev->map_base + UARTDBGCR);
 
 	/* Calculate and set baudrate */
-	quot = (imx_get_xclk() * 4000) / new_baudrate;
+	quot = (imx_get_xclk() * 4) / new_baudrate;
 	writel(quot & 0x3f, dev->map_base + UARTDBGFBRD);
 	writel(quot >> 6, dev->map_base + UARTDBGIBRD);
 
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 04/14] STM378x: Do not configure any pin usage in the driver
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (2 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number Juergen Beisert
                   ` (9 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Only the platform should configure pins to be used by the driver.
The driver must work independently from the settings.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 drivers/serial/stm-serial.c |    7 -------
 1 files changed, 0 insertions(+), 7 deletions(-)

diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 3edd484..a225e30 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -134,13 +134,6 @@ static int stm_clocksource_clock_change(struct notifier_block *nb, unsigned long
 static int stm_serial_init_port(struct console_device *cdev)
 {
 	struct device_d *dev = cdev->dev;
-	/*
-	 * If the board specific file registers this console we should force
-	 * the usage of the debug UART pins, to be able to let the user see
-	 * the output, even if the board file forgets to configure these pins.
-	 */
-	imx_gpio_mode(PWM1_DUART_TX);
-	imx_gpio_mode(PWM0_DUART_RX);
 
 	/* Disable UART */
 	writel(0, dev->map_base + UARTDBGCR);
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (3 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 04/14] STM378x: Do not configure any pin usage in the driver Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 06/14] STM378x: Separate i.MX23 clock handling Juergen Beisert
                   ` (8 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

This is for easier integration of the i.MX28 architecture (to share the code
later on).

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/iomux-imx23.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
index b0f4046..5d4465e 100644
--- a/arch/arm/mach-stm/iomux-imx23.c
+++ b/arch/arm/mach-stm/iomux-imx23.c
@@ -31,6 +31,8 @@
 #define HW_PINCTRL_DIN0 0x600
 #define HW_PINCTRL_DOE0 0x700
 
+#define MAX_GPIO_NO 95
+
 static uint32_t calc_mux_reg(uint32_t no)
 {
 	/* each register controls 16 pads */
@@ -77,7 +79,7 @@ void imx_gpio_mode(unsigned m)
 	writel(reg, IMX_IOMUXC_BASE + reg_offset);
 
 	/* some pins are disabled when configured for GPIO */
-	if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) {
+	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
 		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
 		return;
 	}
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 06/14] STM378x: Separate i.MX23 clock handling
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (4 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices Juergen Beisert
                   ` (7 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Separate i.MX23 clock handling to simplify the addition of the upcoming i.MX28.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/include/mach/clock-imx23.h |   26 ++++++++++++++++++++++++++
 arch/arm/mach-stm/include/mach/clock.h       |   19 ++++++-------------
 2 files changed, 32 insertions(+), 13 deletions(-)
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx23.h

diff --git a/arch/arm/mach-stm/include/mach/clock-imx23.h b/arch/arm/mach-stm/include/mach/clock-imx23.h
new file mode 100644
index 0000000..bb499f2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx23.h
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+#ifndef MACH_CLOCK_IMX23_H
+# define MACH_CLOCK_IMX23_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(void);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned);
+
+#endif /* MACH_CLOCK_IMX23_H */
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
index 0e1a6d6..5200e89 100644
--- a/arch/arm/mach-stm/include/mach/clock.h
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -17,18 +17,11 @@
  * MA 02111-1307 USA
  */
 
-#ifndef ASM_ARCH_CLOCK_IMX23_H
-#define ASM_ARCH_CLOCK_IMX23_H
+#ifndef __MACH_CLOCK_H
+# define __MACH_CLOCK_H
 
-unsigned imx_get_mpllclk(void);
-unsigned imx_get_emiclk(void);
-unsigned imx_get_ioclk(void);
-unsigned imx_get_armclk(void);
-unsigned imx_get_hclk(void);
-unsigned imx_get_xclk(void);
-unsigned imx_get_sspclk(unsigned);
-unsigned imx_set_sspclk(unsigned, unsigned, int);
-unsigned imx_set_ioclk(unsigned);
-
-#endif /* ASM_ARCH_CLOCK_IMX23_H */
+#if defined CONFIG_ARCH_IMX23
+# include <mach/clock-imx23.h>
+#endif
 
+#endif /* __MACH_CLOCK_H */
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (5 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 06/14] STM378x: Separate i.MX23 clock handling Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 08/14] STM378x: Add i.MX28 architecture Juergen Beisert
                   ` (6 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

At least the FEC and the CAN controller drivers can also be used by the i.MX28.
When still used by IMX, the i.MX28 (and maybe i.MX23) related code must be
ignored.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-imx/include/mach/generic.h |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 9ca838b..2926036 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -51,3 +51,5 @@ u64 imx_uid(void);
 #define cpu_is_mx51()	(0)
 #endif
 
+#define cpu_is_mx23()	(0)
+#define cpu_is_mx28()	(0)
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 08/14] STM378x: Add i.MX28 architecture
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (6 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and i.MX28 Juergen Beisert
                   ` (5 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

The i.MX28 shares a lot of functionality with its predecessor, the
i.MX23 (formerly known as stm378x). This patch adds some files to support
both CPUs.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/Kconfig                    |    4 +
 arch/arm/mach-stm/Makefile                   |    5 +-
 arch/arm/mach-stm/clocksource-imx28.c        |   73 ++++
 arch/arm/mach-stm/imx.c                      |   35 ++
 arch/arm/mach-stm/imx23.c                    |   35 --
 arch/arm/mach-stm/include/mach/clock-imx28.h |   29 ++
 arch/arm/mach-stm/include/mach/clock.h       |    3 +
 arch/arm/mach-stm/include/mach/generic.h     |    6 +
 arch/arm/mach-stm/include/mach/gpio.h        |    3 +
 arch/arm/mach-stm/include/mach/imx-regs.h    |    9 +
 arch/arm/mach-stm/include/mach/imx28-regs.h  |   47 +++
 arch/arm/mach-stm/include/mach/iomux-imx28.h |  552 ++++++++++++++++++++++++++
 arch/arm/mach-stm/iomux-imx.c                |  136 +++++++
 arch/arm/mach-stm/iomux-imx23.c              |  119 ------
 arch/arm/mach-stm/reset-imx.c                |   61 +++
 arch/arm/mach-stm/reset-imx23.c              |   61 ---
 arch/arm/mach-stm/speed-imx28.c              |  392 ++++++++++++++++++
 17 files changed, 1353 insertions(+), 217 deletions(-)
 create mode 100644 arch/arm/mach-stm/clocksource-imx28.c
 create mode 100644 arch/arm/mach-stm/imx.c
 delete mode 100644 arch/arm/mach-stm/imx23.c
 create mode 100644 arch/arm/mach-stm/include/mach/clock-imx28.h
 create mode 100644 arch/arm/mach-stm/include/mach/imx28-regs.h
 create mode 100644 arch/arm/mach-stm/include/mach/iomux-imx28.h
 create mode 100644 arch/arm/mach-stm/iomux-imx.c
 delete mode 100644 arch/arm/mach-stm/iomux-imx23.c
 create mode 100644 arch/arm/mach-stm/reset-imx.c
 delete mode 100644 arch/arm/mach-stm/reset-imx23.c
 create mode 100644 arch/arm/mach-stm/speed-imx28.c

diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 021919a..15765fd 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -18,6 +18,10 @@ config ARCH_IMX23
 	bool "i.MX23"
 	select CPU_ARM926T
 
+config ARCH_IMX28
+	bool "i.MX28"
+	select CPU_ARM926T
+
 endchoice
 
 if ARCH_IMX23
diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
index 59d70b6..3c7ce09 100644
--- a/arch/arm/mach-stm/Makefile
+++ b/arch/arm/mach-stm/Makefile
@@ -1,2 +1,3 @@
-obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o
-
+obj-y += imx.o iomux-imx.o reset-imx.o
+obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o
+obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
diff --git a/arch/arm/mach-stm/clocksource-imx28.c b/arch/arm/mach-stm/clocksource-imx28.c
new file mode 100644
index 0000000..15ae951
--- /dev/null
+++ b/arch/arm/mach-stm/clocksource-imx28.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define TIMROTCTRL 0x00
+# define TIMROTCTRL_SFTRST
+# define TIMROTCTRL_CLKGATE
+# define TIMROTCTRL_DIVIDER(x) ((x & 0x3f) << 16)
+
+#define TIMCTRL1 0x60
+#define TIMCTRL1_SET 0x64
+#define TIMCTRL1_CLR 0x68
+#define TIMCTRL1_TOG 0x6c
+# define TIMCTRL_RELOAD (1 << 6)
+# define TIMCTRL_UPDATE (1 << 7)
+# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4)
+# define TIMCTRL_SELECT(x) (x & 0xf)
+#define TIMCOUNT1 0x70
+#define TIMFIX1 0x80
+
+static const void __iomem * timer_base = (void *)IMX_TIM1_BASE;
+
+/* we are using the 32 kHz reference */
+#define CLOCK_TICK_RATE 32000
+
+static uint64_t imx28_clocksource_read(void)
+{
+	return ~(readl(timer_base + TIMCOUNT1));
+}
+
+static struct clocksource imx28_cs = {
+	.read	= imx28_clocksource_read,
+	.mask	= CLOCKSOURCE_MASK(32),
+	.shift	= 17,
+};
+
+static int imx28_clocksource_init(void)
+{
+	/* enable the whole timer block */
+	writel(0x00000000, timer_base + TIMROTCTRL);
+	/* setup start value of the general purpose timer */
+	writel(0x00000000, timer_base + TIMCTRL1);
+	writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1);
+	/* setup the reload value of the general purpose timer */
+	writel(0xffffffff, timer_base + TIMFIX1);
+
+	writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) |
+			TIMCTRL_SELECT(0xb), timer_base + TIMCTRL1);
+	imx28_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, imx28_cs.shift);
+	init_clock(&imx28_cs);
+
+	return 0;
+}
+
+core_initcall(imx28_clocksource_init);
diff --git a/arch/arm/mach-stm/imx.c b/arch/arm/mach-stm/imx.c
new file mode 100644
index 0000000..14a4249
--- /dev/null
+++ b/arch/arm/mach-stm/imx.c
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+
+extern void imx_dump_clocks(void);
+
+static int do_clocks(struct command *cmdtp, int argc, char *argv[])
+{
+	imx_dump_clocks();
+
+	return 0;
+}
+
+BAREBOX_CMD_START(dump_clocks)
+	.cmd		= do_clocks,
+	.usage		= "show clock frequencies",
+BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx23.c
deleted file mode 100644
index 14a4249..0000000
--- a/arch/arm/mach-stm/imx23.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <command.h>
-
-extern void imx_dump_clocks(void);
-
-static int do_clocks(struct command *cmdtp, int argc, char *argv[])
-{
-	imx_dump_clocks();
-
-	return 0;
-}
-
-BAREBOX_CMD_START(dump_clocks)
-	.cmd		= do_clocks,
-	.usage		= "show clock frequencies",
-BAREBOX_CMD_END
diff --git a/arch/arm/mach-stm/include/mach/clock-imx28.h b/arch/arm/mach-stm/include/mach/clock-imx28.h
new file mode 100644
index 0000000..afc9fb6
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx28.h
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+#ifndef MACH_CLOCK_IMX28_H
+#define MACH_CLOCK_IMX28_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(unsigned);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned, unsigned);
+unsigned imx_get_fecclk(void);
+void imx_enable_enetclk(void);
+
+#endif /* MACH_CLOCK_IMX28_H */
+
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
index 5200e89..bd1fa7c 100644
--- a/arch/arm/mach-stm/include/mach/clock.h
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -23,5 +23,8 @@
 #if defined CONFIG_ARCH_IMX23
 # include <mach/clock-imx23.h>
 #endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/clock-imx28.h>
+#endif
 
 #endif /* __MACH_CLOCK_H */
diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h
index 3a552a8..50f25c5 100644
--- a/arch/arm/mach-stm/include/mach/generic.h
+++ b/arch/arm/mach-stm/include/mach/generic.h
@@ -22,3 +22,9 @@
 #else
 # define cpu_is_mx23()	(0)
 #endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define cpu_is_mx28()	(1)
+#else
+# define cpu_is_mx28()	(0)
+#endif
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
index fa8263c..5615b67 100644
--- a/arch/arm/mach-stm/include/mach/gpio.h
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -23,6 +23,9 @@
 #if defined CONFIG_ARCH_IMX23
 # include <mach/iomux-imx23.h>
 #endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/iomux-imx28.h>
+#endif
 
 void imx_gpio_mode(unsigned);
 
diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h
index 40dc742..9b33a06 100644
--- a/arch/arm/mach-stm/include/mach/imx-regs.h
+++ b/arch/arm/mach-stm/include/mach/imx-regs.h
@@ -20,8 +20,17 @@
 #ifndef _IMX_REGS_H
 # define _IMX_REGS_H
 
+/* Note: Some registers do not support this bit change feature! */
+#define BIT_SET 0x04
+#define BIT_CLR 0x08
+#define BIT_TGL 0x0C
+
 #if defined CONFIG_ARCH_IMX23
 # include <mach/imx23-regs.h>
 #endif
 
+#if defined CONFIG_ARCH_IMX28
+# include <mach/imx28-regs.h>
+#endif
+
 #endif /* _IMX_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx28-regs.h b/arch/arm/mach-stm/include/mach/imx28-regs.h
new file mode 100644
index 0000000..0c97c4c
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx28-regs.h
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ */
+
+#ifndef __ASM_ARCH_MX28_REGS_H
+#define __ASM_ARCH_MX28_REGS_H
+
+/*
+ * sanity check
+ */
+#ifndef _IMX_REGS_H
+# error "Please do not include directly. Use imx-regs.h instead."
+#endif
+
+#define IMX_SRAM_BASE		0x00000000
+#define IMX_MEMORY_BASE		0x40000000
+
+#define IMX_NFC_BASE		0x8000C000
+#define IMX_SSP0_BASE		0x80010000
+#define IMX_SSP1_BASE		0x80012000
+#define IMX_SSP2_BASE		0x80014000
+#define IMX_SSP3_BASE		0x80016000
+#define IMX_IOMUXC_BASE		0x80018000
+#define IMX_FB_BASE		0x80030000
+#define IMX_CCM_BASE		0x80040000
+#define IMX_WDT_BASE		0x80056000
+#define IMX_I2C0_BASE		0x80058000
+#define IMX_I2C1_BASE		0x8005a000
+#define IMX_TIM1_BASE		0x80068000
+#define IMX_UART0_BASE		0x8006a000
+#define IMX_UART1_BASE		0x8006c000
+#define IMX_UART2_BASE		0x8006e000
+#define IMX_UART3_BASE		0x80070000
+#define IMX_UART4_BASE		0x80072000
+#define IMX_DBGUART_BASE	0x80074000
+#define IMX_FEC0_BASE		0x800F0000
+#define IMX_FEC1_BASE		0x800F4000
+
+#endif /* __ASM_ARCH_MX28_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/iomux-imx28.h b/arch/arm/mach-stm/include/mach/iomux-imx28.h
new file mode 100644
index 0000000..1e6d421
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/iomux-imx28.h
@@ -0,0 +1,552 @@
+/*
+ * 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.
+ */
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ *                            ^^^^^_ Bit offset
+ *                         ^^^______ Register Number
+ *                       ^^_________ Function
+ *                      ^___________ Drive strength feature present
+ *                     ^____________ Pull up / bit keeper present
+ *                   ^^_____________ Drive strength setting
+ *                  ^_______________ Pull up / bit keeper setting
+ *                 ^________________ Voltage select present
+ *                ^_________________ Voltage selection
+ *            ^_____________________ direction if enabled as GPIO (1 = output)
+ *           ^______________________ initial output value if enabled as GPIO
+ *                                   and configured as output
+ */
+#ifndef __MACH_IOMUX_IMX28_H
+#define __MACH_IOMUX_IMX28_H
+
+/* control pad's function */
+#define FBANK_SHIFT (5)
+#define PORTF(bank,bit)	(((bank) << FBANK_SHIFT) | (bit))
+#define GET_GPIO_NO(x) ((x) & 0xff)
+#define FUNC_SHIFT 8
+#define FUNC(x)	((x) << FUNC_SHIFT)
+#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3)
+#define IS_GPIO (3)
+
+/* control pad's GPIO feature if enabled */
+#define GPIO_OUT (1 << 20)
+#define GPIO_VALUE(x) ((x) << 21)
+#define GPIO_IN (0 << 20)
+#define GET_GPIODIR(x) (!!((x) & (1 << 20)))
+#define GET_GPIOVAL(x) (!!((x) & (1 << 21)))
+
+/* control pad's drive strength */
+#define SE (1 << 10)
+#define SE_PRESENT(x) (!!((x) & SE))
+#define STRENGTH(x) ((x) << 12)
+#define S4MA 0	/* used to define a 4 mA drive strength */
+#define S8MA 1	/* used to define a 8 mA drive strength */
+#define S12MA 2	/* used to define a 12 mA drive strength */
+#define S16MA 3	/* used to define a 16 mA drive strength,
+		   not all pads can drive this current! */
+#define GET_STRENGTH(x) (((x) >> 12) & 0x3)
+
+/* control pad's pull up / bit keeper feature */
+#define PE (1 << 11)
+#define BK (1 << 11)	/* FIXME useful to distinguish? */
+#define PE_PRESENT(x) (!!((x) & PE))
+#define BK_PRESENT(x) (!!((x) & BK))
+#define PULLUP(x) ((x) << 14)
+#define BITKEEPER(x) ((x) << 14)
+#define GET_PULLUP(x) (!!((x) & PULLUP(1)))
+#define GET_BITKEEPER(x) (!!((x) & BITKEEPER(1)))
+
+/* control pad's voltage feature */
+#define VE (1 << 15)
+#define VE_PRESENT(x) (!!((x) & VE))
+#define VE_1_8V (0 << 16)
+#define VE_3_3V (1 << 16)
+#define GET_VOLTAGE(x) (!!((x) & (1 << 16)))
+
+/* Bank 0, GPIO pins 0 ... 31 */
+#define GPMI_RESETN		(FUNC(0) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_SSP3_CMD	(FUNC(1) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_GPIO	(FUNC(3) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_CLE		(FUNC(0) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D2	(FUNC(1) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D5	(FUNC(2) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_GPIO		(FUNC(3) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_ALE		(FUNC(0) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D1	(FUNC(1) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D4	(FUNC(2) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_GPIO		(FUNC(3) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_WRN		(FUNC(0) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_SSP1_SCK	(FUNC(1) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_GPIO		(FUNC(3) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_RDN		(FUNC(0) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_SSP3_SCK	(FUNC(1) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_GPIO		(FUNC(3) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_READY3		(FUNC(0) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_CAN0_RX	(FUNC(1) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_HSDAC_TRIG	(FUNC(2) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_GPIO	(FUNC(3) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY2		(FUNC(0) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_CAN0_TX	(FUNC(1) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_ENET0_TX_ER	(FUNC(2) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_GPIO	(FUNC(3) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY1		(FUNC(0) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_SSP1_CMD	(FUNC(1) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_GPIO	(FUNC(3) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY0		(FUNC(0) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_SSP1_CD	(FUNC(1) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_USB0_ID	(FUNC(2) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_GPIO	(FUNC(3) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_CE3N		(FUNC(0) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_CAN1_RX	(FUNC(1) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_SAIF1_MCLK	(FUNC(2) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_GPIO		(FUNC(3) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE2N		(FUNC(0) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_CAN1_TX	(FUNC(1) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_ENET0_RX_ER	(FUNC(2) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_GPIO		(FUNC(3) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE1N		(FUNC(0) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_SSP3_D3	(FUNC(1) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_GPIO		(FUNC(3) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE0N		(FUNC(0) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_SSP3_D0	(FUNC(1) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_GPIO		(FUNC(3) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_D7			(FUNC(0) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_SSP1_D7		(FUNC(1) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_GPIO		(FUNC(3) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D6			(FUNC(0) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_SSP1_D6		(FUNC(1) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_GPIO		(FUNC(3) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D5			(FUNC(0) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_SSP1_D5		(FUNC(1) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_GPIO		(FUNC(3) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D4			(FUNC(0) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_SSP1_D4		(FUNC(1) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_GPIO		(FUNC(3) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D3			(FUNC(0) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_SSP1_D3		(FUNC(1) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_GPIO		(FUNC(3) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D2			(FUNC(0) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_SSP1_D2		(FUNC(1) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_GPIO		(FUNC(3) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D1			(FUNC(0) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_SSP1_D1		(FUNC(1) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_GPIO		(FUNC(3) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D0			(FUNC(0) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_SSP1_D0		(FUNC(1) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_GPIO		(FUNC(3) | PORTF(0, 0) | SE | VE | PE)
+
+/* Bank 1, GPIO pins 32 ... 63 */
+
+#define LCD_ENABLE		(FUNC(0) | PORTF(1, 31) | SE | VE | BK)
+#define LCD_ENABLE_GPIO		(FUNC(3) | PORTF(1, 31) | SE | VE | BK)
+
+#define LCD_DOTCLK		(FUNC(0) | PORTF(1, 30) | SE | VE | BK)
+
+#define LCD_HSYNC		(FUNC(0) | PORTF(1, 29) | SE | VE | BK)
+
+#define LCD_VSYNC		(FUNC(0) | PORTF(1, 28) | SE | VE | BK)
+
+#define LCD_CS			(FUNC(0) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_LCD_ENABLE	(FUNC(1) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_GPIO		(FUNC(3) | PORTF(1, 27) | SE | VE | BK)
+
+#define LCD_RS			(FUNC(0) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_LCD_DOTCLK	(FUNC(1) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_GPIO		(FUNC(3) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_WR_RWN		(FUNC(0) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_LCD_HSYNC	(FUNC(1) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_ETM_TCLK	(FUNC(2) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_GPIO		(FUNC(3) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_RD_E		(FUNC(0) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_LCD_VSYNC	(FUNC(1) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_ETM_TCTL	(FUNC(2) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_GPIO		(FUNC(3) | PORTF(1, 24) | SE | VE | BK)
+
+#define LCD_D23			(FUNC(0) | PORTF(1, 23) | SE | VE | BK)
+
+#define LCD_D22			(FUNC(0) | PORTF(1, 22) | SE | VE | BK)
+
+#define LCD_D21			(FUNC(0) | PORTF(1, 21) | SE | VE | BK)
+
+#define LCD_D20			(FUNC(0) | PORTF(1, 20) | SE | VE | BK)
+
+#define LCD_D19			(FUNC(0) | PORTF(1, 19) | SE | VE | BK)
+
+#define LCD_D18			(FUNC(0) | PORTF(1, 18) | SE | VE | BK)
+
+#define LCD_D17			(FUNC(0) | PORTF(1, 17) | SE | VE | BK)
+
+#define LCD_D16			(FUNC(0) | PORTF(1, 16) | SE | VE | BK)
+
+#define LCD_D15			(FUNC(0) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_ETM_DA15	(FUNC(2) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_GPIO		(FUNC(3) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D14			(FUNC(0) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_ETM_DA14	(FUNC(2) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_GPIO		(FUNC(3) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D13			(FUNC(0) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_ETM_DA13	(FUNC(2) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_GPIO		(FUNC(3) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D12			(FUNC(0) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_ETM_DA12	(FUNC(2) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_GPIO		(FUNC(3) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D11			(FUNC(0) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_ETM_DA11	(FUNC(2) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_GPIO		(FUNC(3) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D10			(FUNC(0) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_ETM_DA10	(FUNC(2) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_GPIO		(FUNC(3) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D9			(FUNC(0) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA4		(FUNC(1) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA9		(FUNC(2) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_GPIO		(FUNC(3) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D8			(FUNC(0) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA3		(FUNC(1) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA8		(FUNC(2) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_GPIO		(FUNC(3) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D7			(FUNC(0) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_ETM_DA7		(FUNC(2) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_GPIO		(FUNC(3) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D6			(FUNC(0) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_ETM_DA6		(FUNC(2) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_GPIO		(FUNC(3) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D5			(FUNC(0) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_ETM_DA5		(FUNC(2) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_GPIO		(FUNC(3) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D4			(FUNC(0) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA9		(FUNC(1) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA4		(FUNC(2) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_GPIO		(FUNC(3) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D3			(FUNC(0) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA8		(FUNC(1) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA3		(FUNC(2) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_GPIO		(FUNC(3) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D2			(FUNC(0) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_ETM_DA2		(FUNC(2) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_GPIO		(FUNC(3) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D1			(FUNC(0) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_ETM_DA1		(FUNC(2) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_GPIO		(FUNC(3) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D0			(FUNC(0) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_ETM_DA0		(FUNC(2) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_GPIO		(FUNC(3) | PORTF(1, 0) | SE | VE | BK)
+
+/* TODO */
+
+/* Bank 2, GPIO pins 64 ... 95 */
+
+/* TODO */
+
+#define SSP1_D3			(FUNC(0) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_SSP2_D7		(FUNC(1) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_ENET_1588_EVENT3_IN (FUNC(2) | PORTF(4, 15) | SE | VE | PE)
+#define SSP1_D3_GPIO		(FUNC(3) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D0			(FUNC(0) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_SSP2_D6		(FUNC(1) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_ENET_1588_EVENT3_OUT (FUNC(2) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_GPIO		(FUNC(3) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_CMD		(FUNC(0) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_SSP2_D2	(FUNC(1) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_ENET_1588_EVENT2_IN (FUNC(2) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_GPIO		(FUNC(3) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_SCK		(FUNC(0) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_SSP2_D1	(FUNC(1) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_ENET_1588_EVENT2_OUT (FUNC(2) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_GPIO		(FUNC(3) | PORTF(2, 12) | SE | VE | PE)
+#define SSP0_SCK		(FUNC(0) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_SCK_GPIO		(FUNC(3) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_CD			(FUNC(0) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CD_GPIO		(FUNC(3) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CMD		(FUNC(0) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_CMD_GPIO		(FUNC(3) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_D7			(FUNC(0) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_SSP2_SCK	(FUNC(1) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_GPIO		(FUNC(3) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D6			(FUNC(0) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_SSP2_CMD	(FUNC(1) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_GPIO		(FUNC(3) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D5			(FUNC(0) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_SSP2_D3		(FUNC(1) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_GPIO		(FUNC(3) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D4			(FUNC(0) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_SSP2_D0		(FUNC(1) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_GPIO		(FUNC(3) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D3			(FUNC(0) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D3_GPIO		(FUNC(3) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D2			(FUNC(0) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D2_GPIO		(FUNC(3) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D1			(FUNC(0) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D1_GPIO		(FUNC(3) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D0			(FUNC(0) | PORTF(2, 0) | SE | VE | PE)
+#define SSP0_D0_GPIO		(FUNC(3) | PORTF(2, 0) | SE | VE | PE)
+
+/* Bank 3, GPIO pins 96 ... 127 */
+
+#define LCD_RESET		(FUNC(0) | PORTF(3, 30))
+#define LCD_RESET_LCD_VSYNC	(FUNC(1) | PORTF(3, 30))
+#define LCD_RESET_GPIO		(FUNC(3) | PORTF(3, 30))
+#define PWM4			(FUNC(0) | PORTF(3, 29))
+#define PWM4_GPIO		(FUNC(3) | PORTF(3, 29))
+#define PWM3			(FUNC(0) | PORTF(3 28))
+#define PWM3_GPIO		(FUNC(3) | PORTF(3, 28))
+
+#define PWM2			(FUNC(0) | PORTF(3, 18))
+
+#define PWM1			(FUNC(0) | PORTF(3, 17))
+
+#define PWM0			(FUNC(0) | PORTF(3, 16))
+#define PWM0_I2C1_SCL		(FUNC(1) | PORTF(3, 16))
+#define PWM0_DUART_RX		(FUNC(2) | PORTF(3, 16))
+#define PWM0_GPIO		(FUNC(3) | PORTF(3, 16))
+#define AUART3_RTS		(FUNC(0) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_CAN1_RX	(FUNC(1) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_ENET0_1588_EVENT1_IN	(FUNC(2) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_GPIO		(FUNC(3) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_CTS		(FUNC(0) | PORTF(3, 14) | SE | VE | BK | BK)
+#define AUART3_CTS_CAN1_TX	(FUNC(1) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_ENET0_1588_EVENT1_OUT (FUNC(2) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_GPIO		(FUNC(3) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_TX		(FUNC(0) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_CAN0_RX	(FUNC(1) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_ENET0_1588_EVENT0_IN	(FUNC(2) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_GPIO		(FUNC(3) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_RX		(FUNC(0) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_CAN0_TX	(FUNC(1) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_ENET0_1588_EVENT0_OUT	(FUNC(2) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_GPIO		(FUNC(3) | PORTF(3, 12) | SE | VE | BK)
+#define AUART2_RTS		(FUNC(0) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_I2C1_SDA	(FUNC(1) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_SAIF1_IRCLK	(FUNC(2) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_GPIO		(FUNC(3) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_CTS		(FUNC(0) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_I2C1_SCL	(FUNC(1) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_SAIF1_BITCLK	(FUNC(2) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_GPIO		(FUNC(3) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_TX		(FUNC(0) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D2	(FUNC(1) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D5	(FUNC(2) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_GPIO		(FUNC(3) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_RX		(FUNC(0) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D1	(FUNC(1) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D4	(FUNC(2) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_GPIO		(FUNC(3) | PORTF(3, 8) | SE | VE | PE)
+#define AUART1_RTS		(FUNC(0) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_USB0_ID	(FUNC(1) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_ROTARYB	(FUNC(2) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_GPIO		(FUNC(3) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_CTS		(FUNC(0) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_USB0_OC	(FUNC(1) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_ROTARYA	(FUNC(2) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_GPIO		(FUNC(3) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_TX		(FUNC(0) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_SSP3_CD	(FUNC(1) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_PWM1		(FUNC(2) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_GPIO		(FUNC(3) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_RX		(FUNC(0) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_SSP2_CD	(FUNC(1) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_PWM0		(FUNC(2) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_GPIO		(FUNC(3) | PORTF(3, 4) | SE | VE | BK)
+#define AUART0_RTS		(FUNC(0) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_AUART4_TX	(FUNC(1) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_DUART_TX	(FUNC(2) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_GPIO		(FUNC(3) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_CTS		(FUNC(0) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_AUART4_RX	(FUNC(1) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_DUART_RX	(FUNC(2) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_GPIO		(FUNC(3) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_TX		(FUNC(0) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_I2C0_SDA	(FUNC(1) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_DUART_RTS	(FUNC(2) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_GPIO		(FUNC(3) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_RX		(FUNC(0) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_I2C0_SCL	(FUNC(1) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_DUART_CTS	(FUNC(2) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_GPIO		(FUNC(3) | PORTF(3, 0) | SE | VE | BK)
+
+/* Bank 4, GPIO pins 128 ... 159 */
+
+#define JTAG_RTCK		(FUNC(0) | PORTF(4, 20) | SE | VE | BK)
+#define JTAG_RTCK_GPIO		(FUNC(3) | PORTF(4, 20) | SE | VE | BK)
+#define ENET_CLK		(FUNC(0) | PORTF(4, 16) | SE | VE | BK)
+#define ENET_CLK_GPIO		(FUNC(3) | PORTF(4, 16) | SE | VE | BK)
+
+#define ENET0_CRS		(FUNC(0) | PORTF(4, 15) | SE | VE | BK)
+
+#define ENET0_COL		(FUNC(0) | PORTF(4, 14) | SE | VE | BK)
+
+#define ENET0_RX_CLK		(FUNC(0) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_RX_ER	(FUNC(1) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_ENET0_1588_EVENT2_IN (FUNC(2) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_GPIO	(FUNC(3) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_TXD3		(FUNC(0) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET1_TXD1	(FUNC(1) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET0_1588_EVENT1_IN (FUNC(2) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_GPIO		(FUNC(3) | PORTF(4, 12) | SE | VE | BK)
+
+#define ENET0_TXD2		(FUNC(0) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_TXD2_GPIO		(FUNC(3) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_RXD3		(FUNC(0) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET1_RXD1	(FUNC(1) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET0_1588_EVENT0_IN (FUNC(2) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_GPIO		(FUNC(3) | PORTF(4, 10) | SE | VE | BK)
+
+#define ENET0_RXD2		(FUNC(0) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_RXD2_GPIO		(FUNC(3) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_TXD1		(FUNC(0) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD1_GPIO		(FUNC(3) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD0		(FUNC(0) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TXD0_GPIO		(FUNC(3) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TX_EN		(FUNC(0) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_EN_GPIO	(FUNC(3) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_CLK		(FUNC(0) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_TX_CLK_GPIO	(FUNC(3) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_RXD1		(FUNC(0) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPMI_READY4	(FUNC(1) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPIO		(FUNC(3) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD0		(FUNC(0) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPMI_CE7N	(FUNC(1) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_SAIF1_SDATA2	(FUNC(2) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPIO		(FUNC(3) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RX_EN		(FUNC(0) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPMI_CE6N	(FUNC(1) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_SAIF1_SDATA1 (FUNC(2) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPIO	(FUNC(3) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_MDIO		(FUNC(0) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPMI_CE5N	(FUNC(1) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_SAIF0_SDATA2	(FUNC(2) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPIO		(FUNC(3) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDC		(FUNC(0) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPMI_CE4N	(FUNC(1) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_SAIF0_SDATA1	(FUNC(2) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPIO		(FUNC(3) | PORTF(4, 0) | SE | VE | PE)
+
+/*
+ * Bank 5, GPIO pins 160 ... 191
+ * Note: These pins are disabled instead of being GPIOs
+ */
+#define EMI_DDR_OPEN		(FUNC(0) | PORTF(5, 26) | BK)
+#define EMI_DDR_OPEN_OFF	(FUNC(3) | PORTF(5, 26) | BK)
+#define EMI_DSQ1		(FUNC(0) | PORTF(5, 23) | BK)
+#define EMI_DSQ1_OFF		(FUNC(3) | PORTF(5, 23) | BK)
+#define EMI_DSQ0		(FUNC(0) | PORTF(5, 22) | BK)
+#define EMI_DSQ0_OFF		(FUNC(3) | PORTF(5, 22) | BK)
+#define EMI_CLK			(FUNC(0) | PORTF(5, 21) | BK)
+#define EMI_CLK_OFF		(FUNC(3) | PORTF(5, 21) | BK)
+#define EMI_DDR_OPEN_FB		(FUNC(0) | PORTF(5, 20) | BK)
+#define EMI_DDR_OPEN_FB_OFF	(FUNC(3) | PORTF(5, 20) | BK)
+#define EMI_DQM1		(FUNC(0) | PORTF(5, 19) | BK)
+#define EMI_DQM1_OFF		(FUNC(3) | PORTF(5, 19) | BK)
+#define EMI_ODT1		(FUNC(0) | PORTF(5, 18) | BK)
+#define EMI_ODT1_OFF		(FUNC(3) | PORTF(5, 18) | BK)
+#define EMI_DQM0		(FUNC(0) | PORTF(5, 17) | BK)
+#define EMI_DQM0_OFF		(FUNC(3) | PORTF(5, 17) | BK)
+#define EMI_ODT0		(FUNC(0) | PORTF(5, 16) | BK)
+#define EMI_ODT0_OFF		(FUNC(3) | PORTF(5, 16) | BK)
+#define EMI_DATA15		(FUNC(0) | PORTF(5, 15) | BK)
+#define EMI_DATA15_OFF		(FUNC(3) | PORTF(5, 15) | BK)
+#define EMI_DATA14		(FUNC(0) | PORTF(5, 14) | BK)
+#define EMI_DATA14_OFF		(FUNC(3) | PORTF(5, 14) | BK)
+#define EMI_DATA13		(FUNC(0) | PORTF(5, 13) | BK)
+#define EMI_DATA13_OFF		(FUNC(3) | PORTF(5, 13) | BK)
+#define EMI_DATA12		(FUNC(0) | PORTF(5, 12) | BK)
+#define EMI_DATA12_OFF		(FUNC(3) | PORTF(5, 12) | BK)
+#define EMI_DATA11		(FUNC(0) | PORTF(5, 11) | BK)
+#define EMI_DATA10_OFF		(FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA10		(FUNC(0) | PORTF(5, 10) | BK)
+#define EMI_DATA10_OFF		(FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA9		(FUNC(0) | PORTF(5, 9) | BK)
+#define EMI_DATA9_OFF		(FUNC(3) | PORTF(5, 9) | BK)
+#define EMI_DATA8		(FUNC(0) | PORTF(5, 8) | BK)
+#define EMI_DATA8_OFF		(FUNC(3) | PORTF(5, 8) | BK)
+#define EMI_DATA7		(FUNC(0) | PORTF(5, 7) | BK)
+#define EMI_DATA7_OFF		(FUNC(3) | PORTF(5, 7) | BK)
+#define EMI_DATA6		(FUNC(0) | PORTF(5, 6) | BK)
+#define EMI_DATA6_OFF		(FUNC(3) | PORTF(5, 6) | BK)
+#define EMI_DATA5		(FUNC(0) | PORTF(5, 5) | BK)
+#define EMI_DATA5_OFF		(FUNC(3) | PORTF(5, 5) | BK)
+#define EMI_DATA4		(FUNC(0) | PORTF(5, 4) | BK)
+#define EMI_DATA4_OFF		(FUNC(3) | PORTF(5, 4) | BK)
+#define EMI_DATA3		(FUNC(0) | PORTF(5, 3) | BK)
+#define EMI_DATA3_OFF		(FUNC(3) | PORTF(5, 3) | BK)
+#define EMI_DATA2		(FUNC(0) | PORTF(5, 2) | BK)
+#define EMI_DATA2_OFF		(FUNC(3) | PORTF(5, 2) | BK)
+#define EMI_DATA1		(FUNC(0) | PORTF(5, 1) | BK)
+#define EMI_DATA1_OFF		(FUNC(3) | PORTF(5, 1) | BK)
+#define EMI_DATA0		(FUNC(0) | PORTF(5, 0) | BK)
+#define EMI_DATA0_OFF		(FUNC(3) | PORTF(5, 0) | BK)
+
+/*
+ * Bank 6, GPIO pins 192 ... 223
+ * Note: This pins are disabled instead of being GPIOs
+ */
+#define EMI_CKE			(FUNC(0) | PORTF(6, 24) | BK)
+#define EMI_CKE_OFF		(FUNC(3) | PORTF(6, 24) | BK)
+#define EMI_CE1N		(FUNC(0) | PORTF(6, 23) | BK)
+#define EMI_CE1N_OFF		(FUNC(3) | PORTF(6, 23) | BK)
+#define EMI_CE0N		(FUNC(0) | PORTF(6, 22) | BK)
+#define EMI_CE0N_OFF		(FUNC(3) | PORTF(6, 22) | BK)
+#define EMI_WEN			(FUNC(0) | PORTF(6, 21) | BK)
+#define EMI_WEN_OFF		(FUNC(3) | PORTF(6, 21) | BK)
+#define EMI_RASN		(FUNC(0) | PORTF(6, 20) | BK)
+#define EMI_RASN_OFF		(FUNC(3) | PORTF(6, 20) | BK)
+#define EMI_CASN		(FUNC(0) | PORTF(6, 19) | BK)
+#define EMI_CASN_OFF		(FUNC(3) | PORTF(6, 19) | BK)
+#define EMI_BA2			(FUNC(0) | PORTF(6, 18) | BK)
+#define EMI_BA2_OFF		(FUNC(3) | PORTF(6, 18) | BK)
+#define EMI_BA1			(FUNC(0) | PORTF(6, 17) | BK)
+#define EMI_BA1_OFF		(FUNC(3) | PORTF(6, 17) | BK)
+#define EMI_BA0			(FUNC(0) | PORTF(6, 16) | BK)
+#define EMI_BA0_OFF		(FUNC(3) | PORTF(6, 16) | BK)
+#define EMI_A14			(FUNC(0) | PORTF(6, 14) | BK)
+#define EMI_A14_OFF		(FUNC(3) | PORTF(6, 14) | BK)
+#define EMI_A13			(FUNC(0) | PORTF(6, 13) | BK)
+#define EMI_A13_OFF		(FUNC(3) | PORTF(6, 13) | BK)
+#define EMI_A12			(FUNC(0) | PORTF(6, 12) | BK)
+#define EMI_A12_OFF		(FUNC(3) | PORTF(6, 12) | BK)
+#define EMI_A11			(FUNC(0) | PORTF(6, 11) | BK)
+#define EMI_A11_OFF		(FUNC(3) | PORTF(6, 11) | BK)
+#define EMI_A10			(FUNC(0) | PORTF(6, 10) | BK)
+#define EMI_A10_OFF		(FUNC(3) | PORTF(6, 10) | BK)
+#define EMI_A9			(FUNC(0) | PORTF(6, 9) | BK)
+#define EMI_A9_OFF		(FUNC(3) | PORTF(6, 9) | BK)
+#define EMI_A8			(FUNC(0) | PORTF(6, 8) | BK)
+#define EMI_A8_OFF		(FUNC(3) | PORTF(6, 8) | BK)
+#define EMI_A7			(FUNC(0) | PORTF(6, 7) | BK)
+#define EMI_A7_OFF		(FUNC(3) | PORTF(6, 7) | BK)
+#define EMI_A6			(FUNC(0) | PORTF(6, 6) | BK)
+#define EMI_A6_OFF		(FUNC(3) | PORTF(6, 6) | BK)
+#define EMI_A5			(FUNC(0) | PORTF(6, 5) | BK)
+#define EMI_A5_OFF		(FUNC(3) | PORTF(6, 5) | BK)
+#define EMI_A4			(FUNC(0) | PORTF(6, 4) | BK)
+#define EMI_A4_OFF		(FUNC(3) | PORTF(6, 4) | BK)
+#define EMI_A3			(FUNC(0) | PORTF(6, 3) | BK)
+#define EMI_A3_OFF		(FUNC(3) | PORTF(6, 3) | BK)
+#define EMI_A2			(FUNC(0) | PORTF(6, 2) | BK)
+#define EMI_A2_OFF		(FUNC(3) | PORTF(6, 2) | BK)
+#define EMI_A1			(FUNC(0) | PORTF(6, 1) | BK)
+#define EMI_A1_OFF		(FUNC(3) | PORTF(6, 1) | BK)
+#define EMI_A0			(FUNC(0) | PORTF(6, 0) | BK)
+#define EMI_A0_OFF		(FUNC(3) | PORTF(6, 0) | BK)
+
+#endif /* __MACH_IOMUX_IMX28_H */
diff --git a/arch/arm/mach-stm/iomux-imx.c b/arch/arm/mach-stm/iomux-imx.c
new file mode 100644
index 0000000..2c68ebf
--- /dev/null
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -0,0 +1,136 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+
+#define HW_PINCTRL_CTRL 0x000
+#define HW_PINCTRL_MUXSEL0 0x100
+
+#ifdef CONFIG_ARCH_IMX23
+#define HW_PINCTRL_DRIVE0 0x200
+#define HW_PINCTRL_PULL0 0x400
+#define HW_PINCTRL_DOUT0 0x500
+#define HW_PINCTRL_DIN0 0x600
+#define HW_PINCTRL_DOE0 0x700
+
+#define MAX_GPIO_NO 95
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+#define HW_PINCTRL_DRIVE0 0x300
+#define HW_PINCTRL_PULL0 0x600
+#define HW_PINCTRL_DOUT0 0x700
+#define HW_PINCTRL_DIN0 0x900
+#define HW_PINCTRL_DOE0 0xb00
+
+#define MAX_GPIO_NO 159
+#endif
+
+static uint32_t calc_mux_reg(uint32_t no)
+{
+	/* each register controls 16 pads */
+	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
+}
+
+static uint32_t calc_strength_reg(uint32_t no)
+{
+	/* each register controls 8 pads */
+	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
+}
+
+static uint32_t calc_pullup_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
+}
+
+static uint32_t calc_output_enable_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
+}
+
+static uint32_t calc_output_reg(uint32_t no)
+{
+	/* each register controls 32 pads */
+	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
+}
+
+/**
+ * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ */
+void imx_gpio_mode(unsigned m)
+{
+	uint32_t reg_offset, gpio_pin, reg;
+
+	gpio_pin = GET_GPIO_NO(m);
+
+	/* configure the pad to its function (always) */
+	reg_offset = calc_mux_reg(gpio_pin);
+	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
+	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
+	writel(reg, IMX_IOMUXC_BASE + reg_offset);
+
+	/* some pins are disabled when configured for GPIO */
+	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
+		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
+		return;
+	}
+
+	if (SE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
+		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
+		writel(reg, IMX_IOMUXC_BASE + reg_offset);
+	}
+
+	if (VE_PRESENT(m)) {
+		reg_offset = calc_strength_reg(gpio_pin);
+		if (GET_VOLTAGE(m) == 1)
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+				IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+		else
+			writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+				IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+	}
+
+	if (PE_PRESENT(m)) {
+		reg_offset = calc_pullup_reg(gpio_pin);
+		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+	}
+
+	if (GET_FUNC(m) == IS_GPIO) {
+		if (GET_GPIODIR(m) == 1) {
+			/* first set the output value */
+			reg_offset = calc_output_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+			/* then the direction */
+			reg_offset = calc_output_enable_reg(gpio_pin);
+			writel(0x1 << (gpio_pin % 32),
+				IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+		} else {
+			writel(0x1 << (gpio_pin % 32),
+				IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+		}
+	}
+}
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx23.c
deleted file mode 100644
index 5d4465e..0000000
--- a/arch/arm/mach-stm/iomux-imx23.c
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <init.h>
-#include <gpio.h>
-#include <asm/io.h>
-#include <mach/imx-regs.h>
-
-#define HW_PINCTRL_CTRL 0x000
-#define HW_PINCTRL_MUXSEL0 0x100
-#define HW_PINCTRL_DRIVE0 0x200
-#define HW_PINCTRL_PULL0 0x400
-#define HW_PINCTRL_DOUT0 0x500
-#define HW_PINCTRL_DIN0 0x600
-#define HW_PINCTRL_DOE0 0x700
-
-#define MAX_GPIO_NO 95
-
-static uint32_t calc_mux_reg(uint32_t no)
-{
-	/* each register controls 16 pads */
-	return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
-}
-
-static uint32_t calc_strength_reg(uint32_t no)
-{
-	/* each register controls 8 pads */
-	return  ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
-}
-
-static uint32_t calc_pullup_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_PULL0;
-}
-
-static uint32_t calc_output_enable_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_DOE0;
-}
-
-static uint32_t calc_output_reg(uint32_t no)
-{
-	/* each register controls 32 pads */
-	return  ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
-}
-
-/**
- * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
- */
-void imx_gpio_mode(unsigned m)
-{
-	uint32_t reg_offset, gpio_pin, reg;
-
-	gpio_pin = GET_GPIO_NO(m);
-
-	/* configure the pad to its function (always) */
-	reg_offset = calc_mux_reg(gpio_pin);
-	reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 16) << 1));
-	reg |= GET_FUNC(m) << ((gpio_pin % 16) << 1);
-	writel(reg, IMX_IOMUXC_BASE + reg_offset);
-
-	/* some pins are disabled when configured for GPIO */
-	if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
-		printf("Cannot configure pad %d to GPIO\n", gpio_pin);
-		return;
-	}
-
-	if (SE_PRESENT(m)) {
-		reg_offset = calc_strength_reg(gpio_pin);
-		reg = readl(IMX_IOMUXC_BASE + reg_offset) & ~(0x3 << ((gpio_pin % 8) << 2));
-		reg |= GET_STRENGTH(m) << ((gpio_pin % 8) << 2);
-		writel(reg, IMX_IOMUXC_BASE + reg_offset);
-	}
-
-	if (VE_PRESENT(m)) {
-		reg_offset = calc_strength_reg(gpio_pin);
-		if (GET_VOLTAGE(m) == 1)
-			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4);
-		else
-			writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8);
-	}
-
-	if (PE_PRESENT(m)) {
-		reg_offset = calc_pullup_reg(gpio_pin);
-		writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
-	}
-
-	if (GET_FUNC(m) == IS_GPIO) {
-		if (GET_GPIODIR(m) == 1) {
-			/* first set the output value */
-			reg_offset = calc_output_reg(gpio_pin);
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
-			/* then the direction */
-			reg_offset = calc_output_enable_reg(gpio_pin);
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4);
-		} else {
-			writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8);
-		}
-	}
-}
diff --git a/arch/arm/mach-stm/reset-imx.c b/arch/arm/mach-stm/reset-imx.c
new file mode 100644
index 0000000..b35f796
--- /dev/null
+++ b/arch/arm/mach-stm/reset-imx.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <init.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <asm/io.h>
+
+#define HW_RTC_CTRL     0x000
+# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
+#define HW_RTC_CTRL_SET 0x004
+#define HW_RTC_CTRL_CLR 0x008
+#define HW_RTC_CTRL_TOG 0x00C
+
+#define HW_RTC_WATCHDOG     0x050
+#define HW_RTC_WATCHDOG_SET 0x054
+#define HW_RTC_WATCHDOG_CLR 0x058
+#define HW_RTC_WATCHDOG_TOG 0x05C
+
+#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
+
+#define HW_RTC_PERSISTENT1     0x070
+# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
+#define HW_RTC_PERSISTENT1_SET 0x074
+#define HW_RTC_PERSISTENT1_CLR 0x078
+#define HW_RTC_PERSISTENT1_TOG 0x07C
+
+/*
+ * Reset the cpu by setting up the watchdog timer and let it time out
+ *
+ * TODO There is a much easier way to reset the CPU: Refer bit 2 in
+ *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
+ */
+void __noreturn reset_cpu (unsigned long addr)
+{
+	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
+	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
+	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
+
+	while (1)
+		;
+	/*NOTREACHED*/
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx23.c
deleted file mode 100644
index b35f796..0000000
--- a/arch/arm/mach-stm/reset-imx23.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * (C) Copyright 2010 Juergen Beisert - Pengutronix
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#include <common.h>
-#include <init.h>
-#include <notifier.h>
-#include <mach/imx-regs.h>
-#include <asm/io.h>
-
-#define HW_RTC_CTRL     0x000
-# define BM_RTC_CTRL_WATCHDOGEN (1 << 4)
-#define HW_RTC_CTRL_SET 0x004
-#define HW_RTC_CTRL_CLR 0x008
-#define HW_RTC_CTRL_TOG 0x00C
-
-#define HW_RTC_WATCHDOG     0x050
-#define HW_RTC_WATCHDOG_SET 0x054
-#define HW_RTC_WATCHDOG_CLR 0x058
-#define HW_RTC_WATCHDOG_TOG 0x05C
-
-#define WDOG_COUNTER_RATE	1000 /* 1 kHz clock */
-
-#define HW_RTC_PERSISTENT1     0x070
-# define BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER 0x80000000
-#define HW_RTC_PERSISTENT1_SET 0x074
-#define HW_RTC_PERSISTENT1_CLR 0x078
-#define HW_RTC_PERSISTENT1_TOG 0x07C
-
-/*
- * Reset the cpu by setting up the watchdog timer and let it time out
- *
- * TODO There is a much easier way to reset the CPU: Refer bit 2 in
- *       the HW_CLKCTRL_RESET register, data sheet page 106/4-30
- */
-void __noreturn reset_cpu (unsigned long addr)
-{
-	writel(WDOG_COUNTER_RATE, IMX_WDT_BASE + HW_RTC_WATCHDOG);
-	writel(BM_RTC_CTRL_WATCHDOGEN, IMX_WDT_BASE + HW_RTC_CTRL_SET);
-	writel(BV_RTC_PERSISTENT1_GENERAL__RTC_FORCE_UPDATER, IMX_WDT_BASE + HW_RTC_PERSISTENT1);
-
-	while (1)
-		;
-	/*NOTREACHED*/
-}
-EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-stm/speed-imx28.c b/arch/arm/mach-stm/speed-imx28.c
new file mode 100644
index 0000000..63c6b07
--- /dev/null
+++ b/arch/arm/mach-stm/speed-imx28.c
@@ -0,0 +1,392 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
+ *
+ * This code is based partially on code that has:
+ *
+ * (c) 2008 Embedded Alley Solutions, Inc.
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the 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 <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/generic.h>
+#include <mach/clock.h>
+
+#define HW_CLKCTRL_PLL0CTRL0 0x000
+#define HW_CLKCTRL_PLL0CTRL1 0x010
+#define HW_CLKCTRL_PLL1CTRL0 0x020
+#define HW_CLKCTRL_PLL1CTRL1 0x030
+#define HW_CLKCTRL_PLL2CTRL0 0x040
+# define CLKCTRL_PLL2CTRL0_CLKGATE (1 << 31)
+# define CLKCTRL_PLL2CTRL0_POWER (1 << 23)
+#define HW_CLKCTRL_CPU 0x50
+# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
+# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_HBUS 0x60
+#define HW_CLKCTRL_XBUS 0x70
+#define HW_CLKCTRL_XTAL 0x080
+#define HW_CLKCTRL_SSP0 0x090
+#define HW_CLKCTRL_SSP1 0x0a0
+#define HW_CLKCTRL_SSP2 0x0b0
+#define HW_CLKCTRL_SSP3 0x0c0
+/* note: no set/clear register! */
+# define CLKCTRL_SSP_CLKGATE (1 << 31)
+# define CLKCTRL_SSP_BUSY (1 << 29)
+# define CLKCTRL_SSP_DIV_FRAC_EN (1 << 9)
+# define CLKCTRL_SSP_DIV_MASK 0x1ff
+# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+#define HW_CLKCTRL_GPMI 0x0d0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SPDIF 0x0e0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_EMI	0xf0
+/* note: no set/clear register! */
+# define CLKCTRL_EMI_CLKGATE (1 << 31)
+# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
+# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_SAIF0 0x100
+#define HW_CLKCTRL_SAIF1 0x110
+#define HW_CLKCTRL_DIS_LCDIF 0x120
+# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+# define SET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+# define GET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+#define HW_CLKCTRL_ETM 0x130
+#define HW_CLKCTRL_ENET 0x140
+# define SET_CLKCTRL_ENET_DIV(x) (((x) & 0x3f) << 21)
+# define SET_CLKCTRL_ENET_SEL(x) (((x) & 0x3) << 19)
+# define CLKCTRL_ENET_CLK_OUT_EN (1 << 18)
+#define HW_CLKCTRL_HSADC 0x150
+#define HW_CLKCTRL_FLEXCAN 0x160
+#define HW_CLKCTRL_FRAC0 0x1b0
+# define CLKCTRL_FRAC_CLKGATEIO0 (1 << 31)
+# define GET_IO0FRAC(x) (((x) >> 24) & 0x3f)
+# define SET_IO0FRAC(x) (((x) & 0x3f) << 24)
+# define CLKCTRL_FRAC_CLKGATEIO1 (1 << 23)
+# define GET_IO1FRAC(x) (((x) >> 16) & 0x3f)
+# define SET_IO1FRAC(x) (((x) & 0x3f) << 16)
+# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
+# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
+# define GET_CPUFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_FRAC1 0x1c0
+# define CLKCTRL_FRAC_CLKGATEGPMI (1 << 23)
+# define GET_GPMIFRAC(x) (((x) >> 16) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEHSADC (1 << 15)
+# define GET_HSADCFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
+# define GET_PIXFRAC(x) ((x) & 0x3f)
+# define SET_PIXFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_CLKSEQ 0x1d0
+# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 18)
+# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
+# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
+# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 7)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP3 (1 << 6)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP2 (1 << 5)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP1 (1 << 4)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP0 (1 << 3)
+# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 2)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF1 (1 << 1)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF0 (1 << 0)
+#define HW_CLKCTRL_RESET 0x1e0
+#define HW_CLKCTRL_STATUS 0x1f0
+#define HW_CLKCTRL_VERSION 0x200
+
+unsigned imx_get_mpllclk(void)
+{
+	/* the main PLL runs at 480 MHz */
+	return 480000000;
+}
+
+unsigned imx_get_xtalclk(void)
+{
+	/* the external reference runs at 24 MHz */
+	return 24000000;
+}
+
+unsigned imx_get_fecclk(void)
+{
+	/* this PLL always runs at 50 MHz */
+	return 50000000;
+}
+
+
+/* used for the SDRAM controller */
+unsigned imx_get_emiclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
+		return 0;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
+		return imx_get_xtalclk() /
+			GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+
+	rate = imx_get_mpllclk() / 1000;
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
+		rate *= 18;
+		rate /= GET_EMIFRAC(reg);
+	}
+
+	return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+				* 1000;
+}
+
+/*
+ * Source of ssp, gpmi, ir
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ */
+unsigned imx_get_ioclk(unsigned index)
+{
+	uint32_t reg;
+	unsigned rate = imx_get_mpllclk() / 1000;
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	switch (index) {
+	case 0:
+		if (reg & CLKCTRL_FRAC_CLKGATEIO0)
+			return 0;	/* clock is off */
+
+		rate *= 18;
+		rate /= GET_IO0FRAC(reg);
+		break;
+	case 1:
+		if (reg & CLKCTRL_FRAC_CLKGATEIO1)
+			return 0;	/* clock is off */
+
+		rate *= 18;
+		rate /= GET_IO1FRAC(reg);
+		break;
+	}
+
+	return rate * 1000;
+}
+
+/**
+ * Setup a new frequency to the IOCLK domain.
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ * @param nc New frequency in [Hz]
+ *
+ * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
+ *
+ * ioclock0 is the shared clock source of SSP0/SSP1, ioclock1 the shared clock
+ * source of SSP2/SSP3
+ */
+unsigned imx_set_ioclk(unsigned index, unsigned nc)
+{
+	uint32_t reg;
+	unsigned div;
+
+	nc /= 1000;
+	div = (imx_get_mpllclk() / 1000) * 18;
+	div = DIV_ROUND_CLOSEST(div, nc);
+	if (div > 0x3f)
+		div = 0x3f;
+
+	switch (index) {
+	case 0:
+		reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+				~(SET_IO0FRAC(0x3f));
+		/* mask the current settings */
+		writel(reg | SET_IO0FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+		/* enable the IO clock at its new frequency */
+		writel(CLKCTRL_FRAC_CLKGATEIO0,
+				IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+		break;
+	case 1:
+		reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+				~(SET_IO1FRAC(0x3f));
+		/* mask the current settings */
+		writel(reg | SET_IO1FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+		/* enable the IO clock at its new frequency */
+		writel(CLKCTRL_FRAC_CLKGATEIO1,
+				IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+		break;
+	}
+
+	return imx_get_ioclk(index);
+}
+
+/* this is CPU core clock */
+unsigned imx_get_armclk(void)
+{
+	uint32_t reg;
+	unsigned rate;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
+		return imx_get_xtalclk() /
+			GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+	if (reg & CLKCTRL_FRAC_CLKGATECPU)
+		return 0;	/* should not possible, shouldn't it? */
+
+	rate = (imx_get_mpllclk() / 1000) * 18;
+	rate /= GET_CPUFRAC(reg);
+
+	return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+			* 1000;
+}
+
+/* this is the AHB and APBH bus clock */
+unsigned imx_get_hclk(void)
+{
+	unsigned rate = imx_get_armclk() / 1000;
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+		rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+		rate /= 32;
+	} else
+		rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+	return rate * 1000;
+}
+
+/*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+unsigned imx_get_xclk(void)
+{
+	/* runs from the 24 MHz crystal reference */
+	unsigned rate = imx_get_xtalclk();
+
+	return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ */
+unsigned imx_get_sspclk(unsigned index)
+{
+	unsigned rate, offset, shift, ioclk_index;
+
+	if (index > 3) {
+		pr_debug("Unknown SSP unit: %u\n", index);
+		return 0;
+	}
+
+	ioclk_index = index >> 1;
+
+	offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+	shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+	if (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+		return 0;	/* clock is off */
+
+	if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & shift)
+		rate = imx_get_xtalclk();
+	else
+		rate = imx_get_ioclk(ioclk_index);
+
+	return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + offset));
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ * @param nc New frequency in [Hz]
+ * @param high != 0 if ioclk should be the source
+ * @return The new possible frequency
+ */
+unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
+{
+	uint32_t reg;
+	unsigned ssp_div, offset, shift, ioclk_index;
+
+	if (index > 3) {
+		pr_debug("Unknown SSP unit: %u\n", index);
+		return 0;
+	}
+
+	ioclk_index = index >> 1;
+
+	offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+	shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+	reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_CLKGATE;
+	/* Datasheet says: Do not change the DIV setting if the clock is off */
+	writel(reg, IMX_CCM_BASE + offset);
+	/* Wait while clock is gated */
+	while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+		;
+
+	if (high)
+		ssp_div = imx_get_ioclk(ioclk_index);
+	else
+		ssp_div = imx_get_xtalclk();
+
+	if (nc > ssp_div) {
+		printf("Cannot setup SSP unit clock to %u kHz, base clock is "
+						"only %u kHz\n", nc, ssp_div);
+		ssp_div = 1;
+	} else {
+		ssp_div = DIV_ROUND_UP(ssp_div, nc);
+		if (ssp_div > CLKCTRL_SSP_DIV_MASK)
+			ssp_div = CLKCTRL_SSP_DIV_MASK;
+	}
+
+	/* Set new divider value */
+	reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_DIV_MASK;
+	writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + offset);
+
+	/* Wait until new divider value is set */
+	while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_BUSY)
+		;
+
+	if (high)
+		/* switch to ioclock */
+		writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
+	else
+		/* switch to 24 MHz crystal */
+		writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
+
+	return imx_get_sspclk(index);
+}
+
+void imx_enable_enetclk(void)
+{
+	uint32_t reg;
+
+	/* wake up main enet PLL */
+	reg = readl(IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+	if (!(reg & CLKCTRL_PLL2CTRL0_POWER)) {
+		reg |= CLKCTRL_PLL2CTRL0_POWER;
+		writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+		udelay(50);	/* wait until this PLL locks */
+	}
+	reg &= ~CLKCTRL_PLL2CTRL0_CLKGATE;
+	writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+
+	writel(SET_CLKCTRL_ENET_DIV(1) | SET_CLKCTRL_ENET_SEL(0) |
+		CLKCTRL_ENET_CLK_OUT_EN, /* FIXME may be platform specific */
+		IMX_CCM_BASE + HW_CLKCTRL_ENET);
+}
+
+void imx_dump_clocks(void)
+{
+	printf("mpll:    %10u kHz\n", imx_get_mpllclk() / 1000);
+	printf("arm:     %10u kHz\n", imx_get_armclk() / 1000);
+	printf("ioclk0:  %10u kHz\n", imx_get_ioclk(0) / 1000);
+	printf("ioclk1:  %10u kHz\n", imx_get_ioclk(1) / 1000);
+	printf("emiclk:  %10u kHz\n", imx_get_emiclk() / 1000);
+	printf("hclk:    %10u kHz\n", imx_get_hclk() / 1000);
+	printf("xclk:    %10u kHz\n", imx_get_xclk() / 1000);
+	printf("ssp0:    %10u kHz\n", imx_get_sspclk(0) / 1000);
+	printf("ssp1:    %10u kHz\n", imx_get_sspclk(1) / 1000);
+	printf("ssp2:    %10u kHz\n", imx_get_sspclk(2) / 1000);
+	printf("ssp3:    %10u kHz\n", imx_get_sspclk(3) / 1000);
+}
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and i.MX28
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (7 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 08/14] STM378x: Add i.MX28 architecture Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 10/14] STM378x: Adapt the MCI " Juergen Beisert
                   ` (4 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 drivers/serial/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3a8882f..04d9b98 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -21,7 +21,7 @@ config DRIVER_SERIAL_IMX
 config DRIVER_SERIAL_STM378X
 	depends on ARCH_STM
 	default y
-	bool "i.MX23 serial driver"
+	bool "i.MX23/i.MX28 serial driver"
 
 config DRIVER_SERIAL_NETX
 	depends on ARCH_NETX
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 10/14] STM378x: Adapt the MCI driver to support i.MX23 and i.MX28
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (8 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and i.MX28 Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 11/14] Fixup the FEC driver files Juergen Beisert
                   ` (3 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 drivers/mci/Kconfig   |    4 +-
 drivers/mci/stm378x.c |  139 +++++++++++++++++++++++++++++++++++++++++++------
 2 files changed, 124 insertions(+), 19 deletions(-)

diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index b1f2773..ee04079 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -28,11 +28,11 @@ config MCI_INFO
 comment "--- MCI host drivers ---"
 
 config MCI_STM378X
-	bool "i.MX23"
+	bool "i.MX23/i.MX28"
 	depends on ARCH_STM
 	help
 	  Enable this entry to add support to read and write SD cards on a
-	  i.MX23 based system.
+	  i.MX23/i.MX28 based system.
 
 config MCI_S3C
 	bool "S3C"
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index fb74822..94b0f4a 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -61,37 +61,77 @@
 # define SSP_CTRL0_LONG_RESP (1 << 19)
 # define SSP_CTRL0_GET_RESP (1 << 17)
 # define SSP_CTRL0_ENABLE (1 << 16)
+#ifdef CONFIG_ARCH_IMX23
 # define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+#endif
 
 #define HW_SSP_CMD0 0x010
 # define SSP_CMD0_SLOW_CLK (1 << 22)
 # define SSP_CMD0_CONT_CLK (1 << 21)
 # define SSP_CMD0_APPEND_8CYC (1 << 20)
+#ifdef CONFIG_ARCH_IMX23
 # define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
 # define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+#endif
 # define SSP_CMD0_CMD(x) ((x) & 0xff)
 
 #define HW_SSP_CMD1 0x020
-#define HW_SSP_COMPREF 0x030
-#define HW_SSP_COMPMASK 0x040
-#define HW_SSP_TIMING 0x050
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_COMPREF 0x030
+# define HW_SSP_COMPMASK 0x040
+# define HW_SSP_TIMING 0x050
+# define HW_SSP_CTRL1 0x060
+# define HW_SSP_DATA 0x070
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_XFER_COUNT 0x30
+# define HW_SSP_BLOCK_SIZE 0x40
+#  define SSP_BLOCK_SIZE(x) ((x) & 0xf)
+#  define SSP_BLOCK_COUNT(x) (((x) & 0xffffff) << 4)
+# define HW_SSP_COMPREF 0x050
+# define HW_SSP_COMPMASK 0x060
+# define HW_SSP_TIMING 0x070
+# define HW_SSP_CTRL1 0x080
+# define HW_SSP_DATA 0x090
+#endif
+/* bit definition for register HW_SSP_TIMING */
 # define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
 # define SSP_TIMING_TIMEOUT(x) ((x) << 16)
 # define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
 # define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
 
-#define HW_SSP_CTRL1 0x060
+/* bit definition for register HW_SSP_CTRL1 */
 # define SSP_CTRL1_POLARITY (1 << 9)
 # define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
 # define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
 
-#define HW_SSP_DATA 0x070
-#define HW_SSP_SDRESP0 0x080
-#define HW_SSP_SDRESP1 0x090
-#define HW_SSP_SDRESP2 0x0A0
-#define HW_SSP_SDRESP3 0x0B0
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_SDRESP0 0x080
+# define HW_SSP_SDRESP1 0x090
+# define HW_SSP_SDRESP2 0x0A0
+# define HW_SSP_SDRESP3 0x0B0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_SDRESP0 0x0A0
+# define HW_SSP_SDRESP1 0x0B0
+# define HW_SSP_SDRESP2 0x0C0
+# define HW_SSP_SDRESP3 0x0D0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DDR_CTRL 0x0E0
+# define HW_SSP_DLL_CTRL 0x0F0
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_STATUS 0x0C0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_STATUS 0x100
+#endif
 
-#define HW_SSP_STATUS 0x0C0
+/* bit definition for register HW_SSP_STATUS */
 # define SSP_STATUS_PRESENT (1 << 31)
 # define SSP_STATUS_SD_PRESENT (1 << 29)
 # define SSP_STATUS_CARD_DETECT (1 << 28)
@@ -111,11 +151,23 @@
 	SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
 	SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
 
-#define HW_SSP_DEBUG 0x100
-#define HW_SSP_VERSION 0x110
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DLL_STS 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_DEBUG 0x100
+# define HW_SSP_VERSION 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DEBUG 0x120
+# define HW_SSP_VERSION 0x130
+#endif
 
 struct stm_mci_host {
 	unsigned	clock;	/* current clock speed in Hz ("0" if disabled) */
+	unsigned	index;
 #ifdef CONFIG_MCI_INFO
 	unsigned	f_min;
 	unsigned	f_max;
@@ -124,6 +176,18 @@ struct stm_mci_host {
 };
 
 /**
+ * Get the SSP clock rate
+ * @param hw_dev Host interface device instance
+ * @return Unit's clock in [Hz]
+ */
+static unsigned get_unit_clock(struct device_d *hw_dev)
+{
+	struct stm_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+	return imx_get_sspclk(host_data->index);
+}
+
+/**
  * Get MCI cards response if defined for the type of command
  * @param hw_dev Host interface device instance
  * @param cmd Command description
@@ -417,6 +481,7 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
 		xfer_cnt = log2blocksize = block_cnt = 0;
 
 	/* setup command and transfer parameters */
+#ifdef CONFIG_ARCH_IMX23
 	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
 		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
 		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
@@ -430,6 +495,23 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
 		SSP_CMD0_BLOCK_COUNT(block_cnt) |
 		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
 		hw_dev->map_base + HW_SSP_CMD0);
+#endif
+#ifdef CONFIG_ARCH_IMX28
+	writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+		SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+		(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+		SSP_CTRL0_ENABLE,
+		hw_dev->map_base + HW_SSP_CTRL0);
+	writel(xfer_cnt, hw_dev->map_base + HW_SSP_XFER_COUNT);
+
+	/* prepare the command and the transfered data count */
+	writel(SSP_CMD0_CMD(cmd->cmdidx) |
+		(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+		hw_dev->map_base + HW_SSP_CMD0);
+	writel(SSP_BLOCK_SIZE(log2blocksize) |
+		SSP_BLOCK_COUNT(block_cnt),
+		hw_dev->map_base + HW_SSP_BLOCK_SIZE);
+#endif
 
 	/* prepare command's arguments */
 	writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
@@ -481,7 +563,7 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
 		return 0;
 	}
 
-	ssp = imx_get_sspclk(0);
+	ssp = get_unit_clock(hw_dev);
 
 	for (div = 2; div < 255; div += 2) {
 		rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
@@ -657,21 +739,44 @@ static int stm_mci_probe(struct device_d *hw_dev)
 	host->voltages = pd->voltages;
 	host->host_caps = pd->caps;
 
+#ifdef CONFIG_ARCH_IMX23
+	host_data->index = 0;	/* there is only one clock for all */
+#endif
+#ifdef CONFIG_ARCH_IMX28
+	/* one dedicated clock per unit */
+	switch (hw_dev->map_base) {
+	case IMX_SSP0_BASE:
+		host_data->index = 0;
+		break;
+	case IMX_SSP1_BASE:
+		host_data->index = 1;
+		break;
+	case IMX_SSP2_BASE:
+		host_data->index = 2;
+		break;
+	case IMX_SSP3_BASE:
+		host_data->index = 3;
+		break;
+	default:
+		pr_debug("Unknown SSP unit at address 0x%08x\n", hw_dev->map_base);
+		return 0;
+	}
+#endif
 	if (pd->f_min == 0) {
-		host->f_min = imx_get_sspclk(0) / 254U / 256U;
+		host->f_min = get_unit_clock(hw_dev) / 254 / 256;
 		pr_debug("Min. frequency is %u Hz\n", host->f_min);
 	} else {
 		host->f_min = pd->f_min;
 		pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
-			host->f_min, imx_get_sspclk(0) / 254U / 256U);
+			host->f_min, get_unit_clock(hw_dev) / 254 / 256);
 	}
 	if (pd->f_max == 0) {
-		host->f_max = imx_get_sspclk(0) / 2U / 1U;
+		host->f_max = get_unit_clock(hw_dev) / 2 / 1;
 		pr_debug("Max. frequency is %u Hz\n", host->f_max);
 	} else {
 		host->f_max =  pd->f_max;
 		pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
-			host->f_max, imx_get_sspclk(0) / 2U / 1U);
+			host->f_max, get_unit_clock(hw_dev) / 2 / 1);
 	}
 
 #ifdef CONFIG_MCI_INFO
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 11/14] Fixup the FEC driver files
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (9 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 10/14] STM378x: Adapt the MCI " Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 12/14] MX28: add FEC support Juergen Beisert
                   ` (2 subsequent siblings)
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Some register bits are not defined in the IMX CPUs using this FEC (at least
I did not find anything about them in the related datasheets) and they will
get (partially) a new meaning in the i.MX28 CPU. So, removing them from the
source seems the best way to avoid any accidental usage on i.MX28.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 drivers/net/fec_imx.c |    3 +--
 drivers/net/fec_imx.h |    4 ----
 2 files changed, 1 insertions(+), 6 deletions(-)

diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 9c8de77..91ef929 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -476,8 +476,7 @@ static int fec_recv(struct eth_device *dev)
 	ievent = readl(fec->regs + FEC_IEVENT);
 	writel(ievent, fec->regs + FEC_IEVENT);
 
-	if (ievent & (FEC_IEVENT_BABT | FEC_IEVENT_XFIFO_ERROR |
-				FEC_IEVENT_RFIFO_ERROR)) {
+	if (ievent & FEC_IEVENT_BABT) {
 		/* BABT, Rx/Tx FIFO errors */
 		fec_halt(dev);
 		fec_init(dev);
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index ce0fd89..f7fbdc9 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -73,8 +73,6 @@
 #define FEC_IEVENT_LATE_COL             0x00200000
 #define FEC_IEVENT_COL_RETRY_LIM        0x00100000
 #define FEC_IEVENT_XFIFO_UN             0x00080000
-#define FEC_IEVENT_XFIFO_ERROR          0x00040000
-#define FEC_IEVENT_RFIFO_ERROR          0x00020000
 
 #define FEC_IMASK_HBERR                 0x80000000
 #define FEC_IMASK_BABR                  0x40000000
@@ -84,8 +82,6 @@
 #define FEC_IMASK_LATE_COL              0x00200000
 #define FEC_IMASK_COL_RETRY_LIM         0x00100000
 #define FEC_IMASK_XFIFO_UN              0x00080000
-#define FEC_IMASK_XFIFO_ERROR           0x00040000
-#define FEC_IMASK_RFIFO_ERROR           0x00020000
 
 #define FEC_RCNTRL_MAX_FL_SHIFT         16
 #define FEC_RCNTRL_LOOP                 0x01
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 12/14] MX28: add FEC support
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (10 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 11/14] Fixup the FEC driver files Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 13/14] STM378x: Add TX28 CPU module Juergen Beisert
  2010-12-13 10:53 ` [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard Juergen Beisert
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

The i.MX28 comes with an extended ethernet controller (ENET/FEC) which
is backwards compatible to the FEC known from other i.MX CPUs. Add a few
adaptions to the existing driver to make it work with the MX28 FEC.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/mach-stm/Kconfig |    1 +
 drivers/net/fec_imx.c     |   92 +++++++++++++++++++++++++++++++++++++-------
 drivers/net/fec_imx.h     |   17 +++++++-
 3 files changed, 93 insertions(+), 17 deletions(-)

diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 15765fd..9a46138 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -21,6 +21,7 @@ config ARCH_IMX23
 config ARCH_IMX28
 	bool "i.MX28"
 	select CPU_ARM926T
+	select ARCH_HAS_FEC_IMX
 
 endchoice
 
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 91ef929..e63e42e 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -29,10 +29,13 @@
 
 #include <asm/mmu.h>
 #include <asm/io.h>
+#include <mach/generic.h>
 #include <mach/imx-regs.h>
 #include <clock.h>
 #include <mach/clock.h>
-#include <mach/iim.h>
+#ifndef CONFIG_ARCH_STM
+# include <mach/iim.h>
+#endif
 #include <xfuncs.h>
 
 #include "fec_imx.h"
@@ -151,6 +154,39 @@ static int fec_tx_task_disable(struct fec_priv *fec)
 }
 
 /**
+ * Swap endianess to send data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ * @return Pointer to the big endian data
+ */
+static void *imx28_fix_endianess_wr(uint32_t *buf, unsigned wlen)
+{
+	unsigned u;
+	static uint32_t data[376];	/* = 1500 bytes + 4 bytes */
+
+	for (u = 0; u < wlen; u++, buf++)
+		data[u] = __swab32(*buf);
+
+	return data;
+}
+
+/**
+ * Swap endianess to read data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ *
+ * TODO: Check for the risk of destroying some other data behind the buffer
+ * if its size is not a multiple of 4.
+ */
+static void imx28_fix_endianess_rd(uint32_t *buf, unsigned wlen)
+{
+	unsigned u;
+
+	for (u = 0; u < wlen; u++, buf++)
+		*buf = __swab32(*buf);
+}
+
+/**
  * Initialize receive task's buffer descriptors
  * @param[in] fec all we know about the device yet
  * @param[in] count receive buffer count to be allocated
@@ -233,7 +269,11 @@ static void fec_rbd_clean(int last, struct buffer_descriptor __iomem *pRbd)
 
 static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac)
 {
+#ifdef CONFIG_ARCH_STM
+	return -1;
+#else
 	return imx_iim_get_mac(mac);
+#endif
 }
 
 static int fec_set_hwaddr(struct eth_device *dev, unsigned char *mac)
@@ -270,12 +310,13 @@ static int fec_init(struct eth_device *dev)
 		/*
 		 * Frame length=1518; 7-wire mode
 		 */
-		writel((1518 << 16), fec->regs + FEC_R_CNTRL);
+		writel(FEC_R_CNTRL_MAX_FL(1518), fec->regs + FEC_R_CNTRL);
 	} else {
 		/*
 		 * Frame length=1518; MII mode;
 		 */
-		writel((1518 << 16) | (1 << 2), fec->regs + FEC_R_CNTRL);
+		writel(FEC_R_CNTRL_MAX_FL(1518) | FEC_R_CNTRL_MII_MODE,
+			fec->regs + FEC_R_CNTRL);
 		/*
 		 * Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
 		 * and do not drop the Preamble.
@@ -285,16 +326,26 @@ static int fec_init(struct eth_device *dev)
 	}
 
 	if (fec->xcv_type == RMII) {
-		/* disable the gasket and wait */
-		writel(0, fec->regs + FEC_MIIGSK_ENR);
-		while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
-			udelay(1);
+		if (cpu_is_mx28()) {
+			/* just another way to enable RMII */
+			uint32_t reg = readl(fec->regs + FEC_R_CNTRL);
+			writel(reg | FEC_R_CNTRL_RMII_MODE
+				/* the linux driver add these bits, why not we? */
+				/* | FEC_R_CNTRL_FCE | */
+				/* FEC_R_CNTRL_NO_LGTH_CHECK */,
+				fec->regs + FEC_R_CNTRL);
+		} else {
+			/* disable the gasket and wait */
+			writel(0, fec->regs + FEC_MIIGSK_ENR);
+			while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
+				udelay(1);
 
-		/* configure the gasket for RMII, 50 MHz, no loopback, no echo */
-		writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
+			/* configure the gasket for RMII, 50 MHz, no loopback, no echo */
+			writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
 
-		/* re-enable the gasket */
-		writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+			/* re-enable the gasket */
+			writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+		}
 	}
 
 	/*
@@ -419,6 +470,9 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
 	 * Note: We are always using the first buffer for transmission,
 	 * the second will be empty and only used to stop the DMA engine
 	 */
+	if (cpu_is_mx28())
+		eth_data = imx28_fix_endianess_wr(eth_data, (data_length + 3) >> 2);
+
 	writew(data_length, &fec->tbd_base[fec->tbd_index].data_length);
 
 	writel((uint32_t)(eth_data), &fec->tbd_base[fec->tbd_index].data_pointer);
@@ -483,10 +537,12 @@ static int fec_recv(struct eth_device *dev)
 		printf("some error: 0x%08x\n", ievent);
 		return 0;
 	}
-	if (ievent & FEC_IEVENT_HBERR) {
-		/* Heartbeat error */
-		writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
-				fec->regs + FEC_X_CNTRL);
+	if (!cpu_is_mx28()) {
+		if (ievent & FEC_IEVENT_HBERR) {
+			/* Heartbeat error */
+			writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
+					fec->regs + FEC_X_CNTRL);
+		}
 	}
 	if (ievent & FEC_IEVENT_GRA) {
 		/* Graceful stop complete */
@@ -506,6 +562,12 @@ static int fec_recv(struct eth_device *dev)
 	if (!(bd_status & FEC_RBD_EMPTY)) {
 		if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
 			((readw(&rbd->data_length) - 4) > 14)) {
+
+			if (cpu_is_mx28())
+				imx28_fix_endianess_rd(
+					(void *)readl(&rbd->data_pointer),
+					(readw(&rbd->data_length) + 3) >> 2);
+
 			/*
 			 * Get buffer address and size
 			 */
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index f7fbdc9..e07071a 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -63,8 +63,19 @@
 #define FEC_MIIGSK_ENR_READY		(1 << 2)
 #define FEC_MIIGSK_ENR_EN		(1 << 1)
 
-
-#define FEC_IEVENT_HBERR                0x80000000
+#define FEC_R_CNTRL_GRS			(1 << 31)
+#define FEC_R_CNTRL_NO_LGTH_CHECK	(1 << 30)
+#ifdef CONFIG_ARCH_IMX28
+# define FEC_R_CNTRL_MAX_FL(x)		(((x) & 0x3fff) << 16)
+#else
+# define FEC_R_CNTRL_MAX_FL(x)		(((x) & 0x7ff) << 16)
+#endif
+#define FEC_R_CNTRL_RMII_10T		(1 << 9) /* i.MX28 specific */
+#define FEC_R_CNTRL_RMII_MODE		(1 << 8) /* i.MX28 specific */
+#define FEC_R_CNTRL_FCE			(1 << 5)
+#define FEC_R_CNTRL_MII_MODE		(1 << 2)
+
+#define FEC_IEVENT_HBERR                0x80000000 /* Note: Not on i.MX28 */
 #define FEC_IEVENT_BABR                 0x40000000
 #define FEC_IEVENT_BABT                 0x20000000
 #define FEC_IEVENT_GRA                  0x10000000
@@ -74,7 +85,7 @@
 #define FEC_IEVENT_COL_RETRY_LIM        0x00100000
 #define FEC_IEVENT_XFIFO_UN             0x00080000
 
-#define FEC_IMASK_HBERR                 0x80000000
+#define FEC_IMASK_HBERR                 0x80000000 /* Note: Not on i.MX28 */
 #define FEC_IMASK_BABR                  0x40000000
 #define FEC_IMASK_BABT                  0x20000000
 #define FEC_IMASK_GRA                   0x10000000
@@ -120,6 +131,8 @@
  * @brief Receive & Transmit Buffer Descriptor definitions
  *
  * Note: The first BD must be aligned (see DB_ALIGNMENT)
+ *
+ * BTW: Don't trust the i.MX27 and i.MX28 data sheet
  */
 struct buffer_descriptor {
 	uint16_t data_length;		/**< payload's length in bytes */
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 13/14] STM378x: Add TX28 CPU module
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (11 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 12/14] MX28: add FEC support Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  2010-12-13 10:53 ` [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard Juergen Beisert
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 Documentation/boards.dox           |    1 +
 arch/arm/Makefile                  |    1 +
 arch/arm/boards/karo-tx28/Makefile |    1 +
 arch/arm/boards/karo-tx28/config.h |   16 +++++
 arch/arm/boards/karo-tx28/tx28.c   |  119 ++++++++++++++++++++++++++++++++++++
 arch/arm/mach-stm/Kconfig          |   16 +++++
 6 files changed, 154 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/Makefile
 create mode 100644 arch/arm/boards/karo-tx28/config.h
 create mode 100644 arch/arm/boards/karo-tx28/tx28.c

diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index c04e06b..8087f01 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -14,6 +14,7 @@ ARM type:
 @li @subpage pcm043
 @li @subpage imx21ads
 @li @subpage imx27ads
+@li @subpage tx28
 @li @subpage the3stack
 @li @subpage mx23_evk
 @li @subpage board_babage
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23..9d3350b 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -88,6 +88,7 @@ board-$(CONFIG_MACH_SCB9328)			:= scb9328
 board-$(CONFIG_MACH_NESO)			:= guf-neso
 board-$(CONFIG_MACH_MX23EVK)			:= freescale-mx23-evk
 board-$(CONFIG_MACH_CHUMBY)			:= chumby_falconwing
+board-$(CONFIG_MACH_TX28)			:= karo-tx28
 board-$(CONFIG_MACH_FREESCALE_MX51_PDK)		:= freescale-mx51-pdk
 board-$(CONFIG_MACH_GUF_CUPID)			:= guf-cupid
 board-$(CONFIG_MACH_MINI2440)			:= mini2440
diff --git a/arch/arm/boards/karo-tx28/Makefile b/arch/arm/boards/karo-tx28/Makefile
new file mode 100644
index 0000000..6f7e865
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/Makefile
@@ -0,0 +1 @@
+obj-y += tx28.o
diff --git a/arch/arm/boards/karo-tx28/config.h b/arch/arm/boards/karo-tx28/config.h
new file mode 100644
index 0000000..8f18fda
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/config.h
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+#ifndef _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
new file mode 100644
index 0000000..d5edf5d
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel@pengutronix.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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+	.name = "ram0",
+	.flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+	.id = -1,
+	.name = "mem",
+	.map_base = IMX_MEMORY_BASE,
+	.size = 128 * 1024 * 1024,
+	.platform_data = &ram_pdata,
+};
+
+/* setup the CPU card internal signals */
+static const uint32_t tx28_pad_setup[] = {
+	/* NAND interface */
+	GPMI_D0 | VE_3_3V | PULLUP(1),
+	GPMI_D1 | VE_3_3V | PULLUP(1),
+	GPMI_D2 | VE_3_3V | PULLUP(1),
+	GPMI_D3 | VE_3_3V | PULLUP(1),
+	GPMI_D4 | VE_3_3V | PULLUP(1),
+	GPMI_D5 | VE_3_3V | PULLUP(1),
+	GPMI_D6 | VE_3_3V | PULLUP(1),
+	GPMI_D7 | VE_3_3V | PULLUP(1),
+	GPMI_READY0 | VE_3_3V | PULLUP(0),	/* external PU */
+	GPMI_RDN | VE_3_3V | PULLUP(1),
+	GPMI_WRN | VE_3_3V | BITKEEPER(1),
+	GPMI_ALE | VE_3_3V | PULLUP(1),
+	GPMI_CLE | VE_3_3V | PULLUP(1),
+	GPMI_RESETN_GPIO | VE_3_3V | GPIO_IN,	/* act as WP, external PU */
+
+	/* Network interface */
+
+	/*
+	 * Note: To setup the external phy in a manner the baseboard
+	 * supports, its configuration is divided into a small part here in
+	 * the CPU card setup and the remaining configuration in the baseboard
+	 * file.
+	 * Here: Switch on the power supply to the external phy, but keep its
+	 * reset line low.
+	 */
+
+	/* send a "good morning" to the ext. phy 0 = reset */
+	ENET0_RX_CLK_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(0),
+
+	/* phy power control 1 = on */
+	PWM4_GPIO | VE_3_3V | GPIO_OUT | PULLUP(0) | GPIO_VALUE(1),
+
+	ENET_CLK | VE_3_3V | BITKEEPER(0),
+	ENET0_MDC | VE_3_3V | PULLUP(0),
+	ENET0_MDIO | VE_3_3V | PULLUP(0),
+	ENET0_TXD0 | VE_3_3V | PULLUP(0),
+	ENET0_TXD1 | VE_3_3V | PULLUP(0),
+	ENET0_TX_EN | VE_3_3V | PULLUP(0),
+	ENET0_TX_CLK | VE_3_3V | BITKEEPER(0),
+
+};
+
+extern void base_board_init(void);
+
+static int tx28_devices_init(void)
+{
+	int i;
+
+	/* initizalize gpios */
+	for (i = 0; i < ARRAY_SIZE(tx28_pad_setup); i++)
+		imx_gpio_mode(tx28_pad_setup[i]);
+
+	register_device(&sdram_dev);
+
+	armlinux_add_dram(&sdram_dev);
+	armlinux_set_bootparams((void *)(sdram_dev.map_base + 0x100));
+	armlinux_set_architecture(MACH_TYPE_TX28);
+
+	base_board_init();
+
+	return 0;
+}
+
+device_initcall(tx28_devices_init);
+
+/**
+@page tx28 KARO's TX28 CPU module
+
+http://www.karo-electronics.de/
+
+This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
+
+- 128 MiB synchronous dynamic RAM (DDR2 type), 200 MHz support
+- 128 MiB NAND K9F1G08U0A (3.3V type)
+- PCA9554 GPIO expander
+- DS1339 RTC
+- LAN8710 Phy
+
+*/
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 9a46138..824b2cf 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -4,10 +4,12 @@ config ARCH_TEXT_BASE
 	hex
 	default 0x41000000 if MACH_MX23EVK
 	default 0x42000000 if MACH_CHUMBY
+	default 0x47000000 if MACH_TX28
 
 config BOARDINFO
 	default "Freescale i.MX23-EVK" if MACH_MX23EVK
 	default "Chumby Falconwing" if MACH_CHUMBY
+	default "Karo TX28" if MACH_TX28
 
 comment "SigmaTel/Freescale i.MX System-on-Chip"
 
@@ -46,6 +48,20 @@ endchoice
 
 endif
 
+if ARCH_IMX28
+
+choice
+	prompt "i.MX28 Board Type"
+
+config MACH_TX28
+	bool "KARO tx28"
+	help
+	  Say Y here if you are using the KARO TX28 CPU module.
+
+endchoice
+
+endif
+
 menu "Board specific settings       "
 
 endmenu
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

* [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard
  2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
                   ` (12 preceding siblings ...)
  2010-12-13 10:53 ` [PATCH 13/14] STM378x: Add TX28 CPU module Juergen Beisert
@ 2010-12-13 10:53 ` Juergen Beisert
  13 siblings, 0 replies; 15+ messages in thread
From: Juergen Beisert @ 2010-12-13 10:53 UTC (permalink / raw)
  To: barebox

This file is to be used in conjunction with the TX28 CPU module.

Signed-off-by: Juergen Beisert <jbe@pengutronix.de>
---
 arch/arm/boards/karo-tx28/Makefile    |    1 +
 arch/arm/boards/karo-tx28/env/config  |   47 +++++++
 arch/arm/boards/karo-tx28/tx28-stk5.c |  229 +++++++++++++++++++++++++++++++++
 arch/arm/boards/karo-tx28/tx28.c      |   37 ++++++
 arch/arm/configs/tx28stk5_defconfig   |   38 ++++++
 arch/arm/mach-stm/Kconfig             |   15 ++
 6 files changed, 367 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/boards/karo-tx28/env/config
 create mode 100644 arch/arm/boards/karo-tx28/tx28-stk5.c
 create mode 100644 arch/arm/configs/tx28stk5_defconfig

diff --git a/arch/arm/boards/karo-tx28/Makefile b/arch/arm/boards/karo-tx28/Makefile
index 6f7e865..d80ba17 100644
--- a/arch/arm/boards/karo-tx28/Makefile
+++ b/arch/arm/boards/karo-tx28/Makefile
@@ -1 +1,2 @@
 obj-y += tx28.o
+obj-$(CONFIG_MACH_TX28STK5) += tx28-stk5.o
diff --git a/arch/arm/boards/karo-tx28/env/config b/arch/arm/boards/karo-tx28/env/config
new file mode 100644
index 0000000..9b302b8
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/env/config
@@ -0,0 +1,47 @@
+#
+#
+
+machine=tx28
+baseboard=tx28stk5
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.ethaddr=de:ad:be:ef:00:00
+#eth0.netmask=a.b.c.d
+#eth0.serverip=a.b.c.d
+#eth0.gateway=a.b.c.d
+
+# can be either 'net'
+kernel_loc=net
+# can be either 'net' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+	kernelimage="$user"-"$kernelimage"
+	nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+	rootfsimage="$user"-"$rootfsimage"
+else
+	nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttyAM0,115200 tx28_base=$baseboard"
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
new file mode 100644
index 0000000..a032e6a
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel@pengutronix.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.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <mci.h>
+#include <fec.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/mci.h>
+
+static struct stm_mci_platform_data mci_pdata = {
+	.caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
+	.voltages = MMC_VDD_32_33 | MMC_VDD_33_34,	/* fixed to 3.3 V */
+	.f_min = 400 * 1000,
+};
+
+static struct device_d mci_socket = {
+	.name = "stm_mci",
+	.map_base = IMX_SSP0_BASE,
+	.platform_data = &mci_pdata,
+};
+
+/* PhyAD[0..2]=0, RMIISEL=1 */
+static struct fec_platform_data fec_info = {
+	.xcv_type = RMII,
+	.phy_addr = 0,
+};
+
+static struct device_d fec_dev = {
+	.name = "fec_imx",
+	.map_base = IMX_FEC0_BASE,
+	.platform_data = &fec_info,
+};
+
+static const uint32_t tx28_starterkit_pad_setup[] = {
+	/*
+	 * Part II of phy's initialization
+	 * Setup phy's mode to '111'
+	 */
+
+	/*
+	 * force the mod pins to a specific level
+	 * '111' means: "All capable. Auto-negotiation enabled".
+	 * For other values refer LAN8710's datasheet,
+	 * chapter "Mode Bus - MODE[2:0]"
+	 */
+	ENET0_RXD0_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD0 */
+	ENET0_RXD1_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD1 */
+	ENET0_RX_EN_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD2 */
+
+	/* release the reset ('mod' pins get latched) */
+	ENET0_RX_CLK_GPIO | VE_3_3V | BITKEEPER(0) | GPIO_OUT | GPIO_VALUE(1),
+
+	/* right now the 'mod' pins are in their native mode */
+	ENET0_RXD0 | VE_3_3V | PULLUP(0),
+	ENET0_RXD1 | VE_3_3V | PULLUP(0),
+	ENET0_RX_EN | VE_3_3V | PULLUP(0),
+
+	/* Debug UART, available at card connector UART1 */
+	AUART0_CTS_DUART_RX | VE_3_3V | STRENGTH(S8MA),
+	AUART0_RTS_DUART_TX | VE_3_3V | STRENGTH(S8MA),
+	AUART0_RX_DUART_CTS | VE_3_3V | STRENGTH(S8MA),
+	AUART0_TX_DUART_RTS | VE_3_3V | STRENGTH(S8MA),
+	/* Application UART, available at connector UART2 */
+	AUART1_RX | VE_3_3V | BITKEEPER(0),
+	AUART1_TX | VE_3_3V | BITKEEPER(0),
+	AUART1_CTS | VE_3_3V | PULLUP(1),
+	AUART1_RTS | VE_3_3V | PULLUP(1),
+	/* Application UART, available at connector FIXME */
+	AUART2_RX | VE_3_3V | PULLUP(1),
+	AUART2_TX | VE_3_3V | PULLUP(1),
+	AUART2_CTS | VE_3_3V | BITKEEPER(0),
+	AUART2_RTS | VE_3_3V | BITKEEPER(0),
+
+	/* MCI interface */
+	SSP0_D0 | VE_3_3V | PULLUP(1),
+	SSP0_D1 | VE_3_3V | PULLUP(1),
+	SSP0_D2 | VE_3_3V | PULLUP(1),
+	SSP0_D3 | VE_3_3V | PULLUP(1),
+	SSP0_CMD | VE_3_3V | PULLUP(1),
+	SSP0_CD | VE_3_3V | PULLUP(1),
+	SSP0_SCK | VE_3_3V | BITKEEPER(0),
+
+	/* MCI slot power control 1 = off */
+	PWM3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+	/* MCI write protect 1 = not protected */
+	SSP1_SCK_GPIO | VE_3_3V | GPIO_IN,	/* FIXME pull up ? */
+
+	/* LED */
+	ENET0_RXD3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1),
+
+	/*
+	 * The backlight is on, if:
+	 * - the PWM0 pin outputs a low level
+	 *   * AND *
+	 * - the LCD_ENABLE is at high level.
+	 * In all other combinations the backlight is off.
+	 *
+	 * Switch it off here to avoid flickering.
+	 */
+	PWM0_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(1),
+
+	/* LCD interface to the VGA connector */
+	/* sync signals */
+	LCD_WR_RWN_LCD_HSYNC | VE_3_3V | BITKEEPER(0),
+	LCD_RD_E_LCD_VSYNC | VE_3_3V | BITKEEPER(0),
+	LCD_CS_LCD_ENABLE | VE_3_3V | BITKEEPER(0),
+	LCD_RS_LCD_DOTCLK | VE_3_3V | BITKEEPER(0),
+	/* data signals */
+	LCD_D0 | VE_3_3V | BITKEEPER(0),
+	LCD_D1 | VE_3_3V | BITKEEPER(0),
+	LCD_D2 | VE_3_3V | BITKEEPER(0),
+	LCD_D3 | VE_3_3V | BITKEEPER(0),
+	LCD_D4 | VE_3_3V | BITKEEPER(0),
+	LCD_D5 | VE_3_3V | BITKEEPER(0),
+	LCD_D6 | VE_3_3V | BITKEEPER(0),
+	LCD_D7 | VE_3_3V | BITKEEPER(0),
+	LCD_D8 | VE_3_3V | BITKEEPER(0),
+	LCD_D9 | VE_3_3V | BITKEEPER(0),
+	LCD_D10 | VE_3_3V | BITKEEPER(0),
+	LCD_D11 | VE_3_3V | BITKEEPER(0),
+	LCD_D12 | VE_3_3V | BITKEEPER(0),
+	LCD_D13 | VE_3_3V | BITKEEPER(0),
+	LCD_D14 | VE_3_3V | BITKEEPER(0),
+	LCD_D15 | VE_3_3V | BITKEEPER(0),
+	LCD_D16 | VE_3_3V | BITKEEPER(0),
+	LCD_D17 | VE_3_3V | BITKEEPER(0),
+	LCD_D18 | VE_3_3V | BITKEEPER(0),
+	LCD_D19 | VE_3_3V | BITKEEPER(0),
+	LCD_D20 | VE_3_3V | BITKEEPER(0),
+	LCD_D21 | VE_3_3V | BITKEEPER(0),
+	LCD_D22 | VE_3_3V | BITKEEPER(0),
+	LCD_D23 | VE_3_3V | BITKEEPER(0),
+
+	/* keep display's reset at low */
+	LCD_RESET_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+	/* keep display's power off */
+	LCD_ENABLE_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+};
+
+/**
+ * Try to register an environment storage on the attached MCI card
+ * @return 0 on success
+ *
+ * We rely on the existance of a usable SD card, already attached to
+ * our system, to get a persistent memory for our environment.
+ * If this SD card is also the boot medium, we can use the second partition
+ * for our environment purpose (if present!).
+ */
+static int register_persistent_environment(void)
+{
+	struct cdev *cdev;
+
+	/*
+	 * The TX28 STK5 has only one usable MCI card socket.
+	 * So, we expect its name as "disk0".
+	 */
+	cdev = cdev_by_name("disk0");
+	if (cdev == NULL) {
+		pr_err("No MCI card preset\n");
+		return -ENODEV;
+	}
+
+	/* MCI card is present, also a usable partition on it? */
+	cdev = cdev_by_name("disk0.1");
+	if (cdev == NULL) {
+		pr_err("No second partition available\n");
+		pr_info("Please create at least a second partition with"
+			" 256 kiB...512 kiB in size (your choice)\n");
+		return -ENODEV;
+	}
+
+	/* use the full partition as our persistent environment storage */
+	return devfs_add_partition("disk0.1", 0, cdev->size,
+					DEVFS_PARTITION_FIXED, "env0");
+}
+
+void base_board_init(void)
+{
+	int i, ret;
+
+	/* initialize gpios */
+	for (i = 0; i < ARRAY_SIZE(tx28_starterkit_pad_setup); i++)
+		imx_gpio_mode(tx28_starterkit_pad_setup[i]);
+
+	/* enable IOCLK0 to run at the PLL frequency */
+	imx_set_ioclk(0, 480000000);
+	/* run the SSP unit clock at 100 MHz */
+	imx_set_sspclk(0, 100000000, 1);
+
+	register_device(&mci_socket);
+
+	imx_enable_enetclk();
+	register_device(&fec_dev);
+
+	ret = register_persistent_environment();
+	if (ret != 0)
+		printf("Cannot create the 'env0' persistent environment "
+				"storage (%d)\n", ret);
+}
+
+static struct device_d tx28kit_serial_device = {
+	.name     = "stm_serial",
+	.map_base = IMX_DBGUART_BASE,
+	.size     = 8192,
+};
+
+static int tx28kit_console_init(void)
+{
+	return register_device(&tx28kit_serial_device);
+}
+
+console_initcall(tx28kit_console_init);
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
index d5edf5d..6f4ef4e 100644
--- a/arch/arm/boards/karo-tx28/tx28.c
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -106,6 +106,8 @@ device_initcall(tx28_devices_init);
 /**
 @page tx28 KARO's TX28 CPU module
 
+@section tx28_cpu_card The CPU module
+
 http://www.karo-electronics.de/
 
 This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
@@ -116,4 +118,39 @@ This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
 - DS1339 RTC
 - LAN8710 Phy
 
+@section tx28_basboards Supported baseboards
+
+Supported baseboards are:
+- KARO's Starterkit 5
+
+@section tx28_stk5_howto How to get barebox for 'KARO's Starterkit 5'
+
+Using the default configuration:
+
+@verbatim
+make ARCH=arm tx28stk5_defconfig
+@endverbatim
+
+Build the binary image:
+
+@verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+@endverbatim
+
+@note replace the armv5compiler with your ARM v5 cross compiler.
+
+@note To use the result, you also need the following resources from Freescale:
+- the 'bootlets' archive
+- the 'elftosb2' encryption tool
+- in the case you want to start @b barebox from an attached SD card the
+  'sdimage' tool from Freescale's 'uuc' archive.
+
+@section tx28_mlayout Memory layout when barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+  - below malloc area: stack area
+  - below barebox: malloc area
+- 0x47000000 start of @b barebox
+
 */
diff --git a/arch/arm/configs/tx28stk5_defconfig b/arch/arm/configs/tx28stk5_defconfig
new file mode 100644
index 0000000..17534f5
--- /dev/null
+++ b/arch/arm/configs/tx28stk5_defconfig
@@ -0,0 +1,38 @@
+CONFIG_ARCH_STM=y
+CONFIG_ARCH_IMX28=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_BROKEN=y
+CONFIG_LONGHELP=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx28/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_STM378X=y
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 824b2cf..e47d9f1 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -64,6 +64,21 @@ endif
 
 menu "Board specific settings       "
 
+if MACH_TX28
+
+choice
+	prompt "TX28 Base Board Type"
+
+config MACH_TX28STK5
+	bool "TX28-stk5"
+	help
+	  Select this entry if you are running the TX28 CPU module on the
+	  KARO TX28 Starterkit5.
+
+endchoice
+
+endif
+
 endmenu
 
 endif
-- 
1.7.2.3


_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

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

end of thread, other threads:[~2010-12-13 10:54 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-13 10:53 [PATCH] i.MX28 architecture inclusion into barebox Juergen Beisert
2010-12-13 10:53 ` [PATCH 01/14] Make DIV_ROUND_UP macro globally available Juergen Beisert
2010-12-13 10:53 ` [PATCH 02/14] Add macro for correct rounding in integer devisions Juergen Beisert
2010-12-13 10:53 ` [PATCH 03/14] STM378x: Use Hz as the clock unit like in all other arch Juergen Beisert
2010-12-13 10:53 ` [PATCH 04/14] STM378x: Do not configure any pin usage in the driver Juergen Beisert
2010-12-13 10:53 ` [PATCH 05/14] STM378x: Parameterize the max. possible GPIO number Juergen Beisert
2010-12-13 10:53 ` [PATCH 06/14] STM378x: Separate i.MX23 clock handling Juergen Beisert
2010-12-13 10:53 ` [PATCH 07/14] IMX: Ignore i.MX23/i.MX28 related code in shared devices Juergen Beisert
2010-12-13 10:53 ` [PATCH 08/14] STM378x: Add i.MX28 architecture Juergen Beisert
2010-12-13 10:53 ` [PATCH 09/14] STM378x: Adapt the serial driver to support i.MX23 and i.MX28 Juergen Beisert
2010-12-13 10:53 ` [PATCH 10/14] STM378x: Adapt the MCI " Juergen Beisert
2010-12-13 10:53 ` [PATCH 11/14] Fixup the FEC driver files Juergen Beisert
2010-12-13 10:53 ` [PATCH 12/14] MX28: add FEC support Juergen Beisert
2010-12-13 10:53 ` [PATCH 13/14] STM378x: Add TX28 CPU module Juergen Beisert
2010-12-13 10:53 ` [PATCH 14/14] STM378x: Add the TX28 Starterkit-5 baseboard Juergen Beisert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox