All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support
@ 2011-03-22 20:40 John Rigby
  2011-03-22 20:40 ` [U-Boot] [PATCH 1/4] p101x: extra init for u8500 John Rigby
                   ` (9 more replies)
  0 siblings, 10 replies; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:40 UTC (permalink / raw)
  To: u-boot

Add support for ST-Ericsson U8500 SoC and HREF platform

John Rigby (1):
  armv7: Add support for ST-Ericsson U8500 href platform

Michael Brandt (1):
  I2C: add driver of st-ericsson u8500 i2c

Rabin Vincent (2):
  p101x: extra init for u8500
  armv7: Add ST-Ericsson u8500 arch

 arch/arm/cpu/armv7/u8500/Makefile          |   46 +++
 arch/arm/cpu/armv7/u8500/clock.c           |   56 +++
 arch/arm/cpu/armv7/u8500/lowlevel.S        |   33 ++
 arch/arm/cpu/armv7/u8500/timer.c           |  167 ++++++++
 arch/arm/include/asm/arch-u8500/ab8500.h   |  523 ++++++++++++++++++++++++
 arch/arm/include/asm/arch-u8500/bits.h     |   58 +++
 arch/arm/include/asm/arch-u8500/clock.h    |   72 ++++
 arch/arm/include/asm/arch-u8500/common.h   |  107 +++++
 arch/arm/include/asm/arch-u8500/gpio.h     |  247 ++++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h |   83 ++++
 arch/arm/include/asm/arch-u8500/u8500.h    |   47 +++
 board/st-ericsson/u8500/Makefile           |   50 +++
 board/st-ericsson/u8500/gpio.c             |  346 ++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw-defs_v1.h |  578 ++++++++++++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h         |  182 +++++++++
 board/st-ericsson/u8500/prcmu.c            |  167 ++++++++
 board/st-ericsson/u8500/u8500_href.c       |  540 +++++++++++++++++++++++++
 boards.cfg                                 |    1 +
 drivers/i2c/Makefile                       |    1 +
 drivers/i2c/u8500_i2c.c                    |  603 ++++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h                    |  220 ++++++++++
 drivers/serial/serial_pl01x.c              |   10 +
 drivers/serial/serial_pl01x.h              |    4 +
 include/configs/u8500_href.h               |  243 +++++++++++
 24 files changed, 4384 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/ab8500.h
 create mode 100644 arch/arm/include/asm/arch-u8500/bits.h
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/common.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw-defs_v1.h
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h
 create mode 100644 include/configs/u8500_href.h

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

* [U-Boot] [PATCH 1/4] p101x: extra init for u8500
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
@ 2011-03-22 20:40 ` John Rigby
  2011-03-22 20:40 ` [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:40 UTC (permalink / raw)
  To: u-boot

From: Rabin Vincent <rabin.vincent@stericsson.com>

empty fifo on init
program receive line control register on u8500

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
 drivers/serial/serial_pl01x.c |   10 ++++++++++
 drivers/serial/serial_pl01x.h |    4 ++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 5dfcde8..22ada8f 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -112,6 +112,12 @@ int serial_init (void)
 	unsigned int remainder;
 	unsigned int fraction;
 
+	/* Empty RX fifo if necessary */
+	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+			readl(&regs->dr);
+	}
+
 	/* First, disable everything */
 	writel(0, &regs->pl011_cr);
 
@@ -134,6 +140,10 @@ int serial_init (void)
 	writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN,
 	       &regs->pl011_lcrh);
 
+#ifdef CONFIG_U8500
+	/* program receive line control register */
+	writel(0x70, &regs->pl011_rlcr);
+#endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
 	       &regs->pl011_cr);
diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h
index b670c24..fdd3911 100644
--- a/drivers/serial/serial_pl01x.h
+++ b/drivers/serial/serial_pl01x.h
@@ -43,7 +43,11 @@ struct pl01x_regs {
 	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
 	u32	pl010_cr;	/* 0x14 Control register */
 	u32	fr;		/* 0x18 Flag register (Read only) */
+#ifdef CONFIG_U8500
+	u32	pl011_rlcr;	/* 0x1c Receive line control register */
+#else
 	u32	reserved;
+#endif
 	u32	ilpr;		/* 0x20 IrDA low-power counter register */
 	u32	pl011_ibrd;	/* 0x24 Integer baud rate register */
 	u32	pl011_fbrd;	/* 0x28 Fractional baud rate register */
-- 
1.7.1

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

* [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
  2011-03-22 20:40 ` [U-Boot] [PATCH 1/4] p101x: extra init for u8500 John Rigby
@ 2011-03-22 20:40 ` John Rigby
  2011-04-11 18:04   ` Wolfgang Denk
  2011-03-22 20:40 ` [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:40 UTC (permalink / raw)
  To: u-boot

From: Rabin Vincent <rabin.vincent@stericsson.com>

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
---
 arch/arm/cpu/armv7/u8500/Makefile          |   46 +++
 arch/arm/cpu/armv7/u8500/clock.c           |   56 +++
 arch/arm/cpu/armv7/u8500/lowlevel.S        |   33 ++
 arch/arm/cpu/armv7/u8500/timer.c           |  167 +++++++++
 arch/arm/include/asm/arch-u8500/ab8500.h   |  523 ++++++++++++++++++++++++++++
 arch/arm/include/asm/arch-u8500/bits.h     |   58 +++
 arch/arm/include/asm/arch-u8500/clock.h    |   72 ++++
 arch/arm/include/asm/arch-u8500/common.h   |  107 ++++++
 arch/arm/include/asm/arch-u8500/gpio.h     |  247 +++++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h |   83 +++++
 arch/arm/include/asm/arch-u8500/u8500.h    |   47 +++
 11 files changed, 1439 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/ab8500.h
 create mode 100644 arch/arm/include/asm/arch-u8500/bits.h
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/common.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h

diff --git a/arch/arm/cpu/armv7/u8500/Makefile b/arch/arm/cpu/armv7/u8500/Makefile
new file mode 100644
index 0000000..270aa40
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	= timer.o clock.o
+SOBJS	= lowlevel.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/u8500/clock.c b/arch/arm/cpu/armv7/u8500/clock.c
new file mode 100644
index 0000000..9e3b873
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/clock.c
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2009 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clkrst {
+	unsigned int pcken;
+	unsigned int pckdis;
+	unsigned int kcken;
+	unsigned int kckdis;
+};
+
+static unsigned int clkrst_base[] = {
+	U8500_CLKRST1_BASE,
+	U8500_CLKRST2_BASE,
+	U8500_CLKRST3_BASE,
+	0,
+	U8500_CLKRST5_BASE,
+	U8500_CLKRST6_BASE,
+	U8500_CLKRST7_BASE,	/* ED only */
+};
+
+/* Turn on peripheral clock at PRCC level */
+void u8500_clock_enable(int periph, int cluster, int kern)
+{
+	struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1];
+
+	if (kern != -1)
+		writel(1 << kern, &clkrst->kcken);
+
+	if (cluster != -1)
+		writel(1 << cluster, &clkrst->pcken);
+}
diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S
new file mode 100644
index 0000000..0e3f8fc
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/lowlevel.S
@@ -0,0 +1,33 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+.globl lowlevel_init
+lowlevel_init:
+	mov	pc, lr
+
+	.align	5
+.globl reset_cpu
+reset_cpu:
+        ldr r0, =CFG_PRCMU_BASE
+        ldr r1, =0x1
+        str r1, [r0, #0x228]
+_loop_forever:
+	b	_loop_forever
diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c
new file mode 100644
index 0000000..8850fd5
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/timer.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ * John Rigby <john.rigby@linaro.org>
+ *
+ * Based on original from Linux kernel source and
+ * internal ST-Ericsson U-Boot source.
+ * (C) Copyright 2009 Alessandro Rubini
+ * (C) Copyright 2010 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * The MTU device has some interrupt control registers
+ * followed by 4 timers.
+ */
+
+/* The timers */
+struct u8500_mtu_timer {
+	u32 lr;			/* Load value */
+	u32 cv;			/* Current value */
+	u32 cr;			/* Control reg */
+	u32 bglr;		/* ??? */
+};
+
+/* The MTU that contains the timers */
+struct u8500_mtu {
+	u32 imsc;		/* Interrupt mask set/clear */
+	u32 ris;		/* Raw interrupt status */
+	u32 mis;		/* Masked interrupt status */
+	u32 icr;		/* Interrupt clear register */
+	struct u8500_mtu_timer pt[4];
+};
+
+/* bits for the control register */
+#define MTU_CR_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR */
+#define MTU_CR_32BITS		0x02
+
+#define MTU_CR_PRESCALE_1	0x00
+#define MTU_CR_PRESCALE_16	0x04
+#define MTU_CR_PRESCALE_256	0x08
+#define MTU_CR_PRESCALE_MASK	0x0c
+
+#define MTU_CR_PERIODIC		0x40	/* if 0 = free-running */
+#define MTU_CR_ENA		0x80
+
+/*
+ * The MTU is clocked at 133 MHz by default. (V1 and later)
+ */
+#define TIMER_CLOCK		(133 * 1000 * 1000 / 16)
+#define COUNT_TO_USEC(x)	((x) * 16 / 133)
+#define USEC_TO_COUNT(x)	((x) * 133 / 16)
+#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
+#define TIMER_LOAD_VAL		0xffffffff
+
+/*
+ * MTU timer to use (from 0 to 3).
+ * Linux ux500 timer0 on MTU0 and timer0 on MTU1
+ */
+#define MTU_TIMER 2
+
+static struct u8500_mtu_timer *timer_base =
+	&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
+
+/* macro to read the 32 bit timer: since it decrements, we invert read value */
+#define READ_TIMER() (~readl(&timer_base->cv))
+
+/* Configure a free-running, auto-wrap counter with /16 prescaler */
+int timer_init(void)
+{
+	writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
+	       &timer_base->cr);
+	reset_timer();
+	return 0;
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = TICKS_TO_HZ(READ_TIMER());
+
+	if (now >= gd->lastinc)	/* normal (non rollover) */
+		gd->tbl += (now - gd->lastinc);
+	else			/* rollover */
+		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->tbl;
+}
+
+/* Delay x useconds */
+void __udelay(ulong usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	ulong now, last = READ_TIMER();
+
+	while (tmo > 0) {
+		now = READ_TIMER();
+		if (now > last)	/* normal (non rollover) */
+			tmo -= now - last;
+		else		/* rollover */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+void reset_timer_masked(void)
+{
+	gd->lastinc = TICKS_TO_HZ(READ_TIMER());
+	gd->tbl = 0;		/* reset ticks to 0 */
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+/*
+ * Emulation of Power architecture long long timebase.
+ *
+ * TODO: Support gd->tbu for real long long timebase.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * Emulation of Power architecture timebase.
+ * NB: Low resolution compared to Power tbclk.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/include/asm/arch-u8500/ab8500.h b/arch/arm/include/asm/arch-u8500/ab8500.h
new file mode 100644
index 0000000..02a3c97
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/ab8500.h
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) ST-Ericsson 2009.
+ *
+ * Author: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef _AB8500_H
+#define _AB8500_H
+
+/*
+ * AB8500 bank addresses
+ */
+#define AB8500_SYS_CTRL1_BLOCK	0x1
+#define AB8500_SYS_CTRL2_BLOCK	0x2
+#define AB8500_REGU_CTRL1	0x3
+#define AB8500_REGU_CTRL2	0x4
+#define AB8500_USB		0x5
+#define AB8500_TVOUT		0x6
+#define AB8500_DBI		0x7
+#define AB8500_ECI_AV_ACC	0x8
+#define AB8500_RESERVED	0x9
+#define STw4550_GPADC		0xA
+#define AB8500_GPADC		0xA
+#define AB8500_CHARGER		0xB
+#define AB8500_GAS_GAUGE	0xC
+#define AB8500_AUDIO		0xD
+#define AB8500_INTERRUPT	0xE
+#define AB8500_RTC		0xF
+#define AB8500_MISC		0x10
+#define AB8500_DEBUG		0x12
+#define AB8500_PROD_TEST	0x13
+#define AB8500_OTP_EMUL	0x15
+
+/*
+ * System control 1 register offsets.
+ * Bank = 0x01
+ */
+#define AB8500_TURNON_STAT_REG		0x0100
+#define AB8500_RESET_STAT_REG		0x0101
+#define AB8500_PONKEY1_PRESS_STAT_REG	0x0102
+
+#define AB8500_FSM_STAT1_REG		0x0140
+#define AB8500_FSM_STAT2_REG		0x0141
+#define AB8500_SYSCLK_REQ_STAT_REG	0x0142
+#define AB8500_USB_STAT1_REG		0x0143
+#define AB8500_USB_STAT2_REG		0x0144
+#define AB8500_STATUS_SPARE1_REG	0x0145
+#define AB8500_STATUS_SPARE2_REG	0x0146
+
+#define AB8500_CTRL1_REG		0x0180
+#define AB8500_CTRL2_REG		0x0181
+
+/*
+ * System control 2 register offsets.
+ * bank = 0x02
+ */
+#define AB8500_CTRL3_REG		0x0200
+#define AB8500_CTRL3_RST_DENC_MASK     0x4
+#define AB8500_CTRL3_RST_DENC_SHIFT    2
+#define AB8500_CTRL3_RST_AUD_MASK      0x2
+#define AB8500_CTRL3_RST_AUD_SHIFT     1
+#define AB8500_MAIN_WDOG_CTRL_REG	0x0201
+#define AB8500_MAIN_WDOG_TIMER_REG	0x0202
+#define AB8500_LOW_BAT_REG		0x0203
+#define AB8500_BATT_OK_REG		0x0204
+#define AB8500_SYSCLK_TIMER_REG		0x0205
+#define AB8500_SMPSCLK_CTRL_REG		0x0206
+#define AB8500_SMPSCLK_SEL1_REG		0x0207
+#define AB8500_SMPSCLK_SEL2_REG		0x0208
+#define AB8500_SMPSCLK_SEL3_REG		0x0209
+#define AB8500_SYSULPCLK_CONF_REG	0x020A
+#define AB8500_SYSULPCLK_CTRL1_REG	0x020B
+#define AB8500_SYSCLK_CTRL_REG		0x020C
+#define AB8500_SYSCLK_REQ1_VALID_REG	0x020D
+#define AB8500_SYSCLK_REQ_VALID_REG	0x020E
+#define AB8500_SYSCTRL_SPARE_REG	0x020F
+#define AB8500_PAD_CONF_REG		0x0210
+
+/*
+ * Regu control1 register offsets (SPI)
+ * Bank = 0x03
+ */
+#define AB8500_REGU_SERIAL_CTRL1_REG	0x0300
+#define AB8500_REGU_SERIAL_CTRL2_REG	0x0301
+#define AB8500_REGU_SERIAL_CTRL3_REG	0x0302
+#define AB8500_REGU_REQ_CTRL1_REG	0x0303
+#define AB8500_REGU_REQ_CTRL2_REG	0x0304
+#define AB8500_REGU_REQ_CTRL3_REG	0x0305
+#define AB8500_REGU_REQ_CTRL4_REG	0x0306
+#define AB8500_REGU_SYSCLK_REQ1HP_VALID1_REG	0x0307
+#define AB8500_REGU_SYSCLK_REQ1HP_VALID2_REG	0x0308
+#define AB8500_REGU_HWHPREQ1_VALID1_REG	0x0309
+#define AB8500_REGU_HWHPREQ1_VALID2_REG	0x030A
+#define AB8500_REGU_HWHPREQ2_VALID1_REG	0x030B
+#define AB8500_REGU_HWHPREQ2_VALID2_REG	0x030C
+#define AB8500_REGU_SWHPREQ_VALID1_REG	0x030D
+#define AB8500_REGU_SWHPREQ_VALID2_REG	0x030E
+
+#define AB8500_REGU_SYSCLK_REQ1_VALID_REG	0x030F /* only for ED*/
+#define AB8500_REGU_SYSCLK_REQ2_VALID_REG	0x0310	/*only for ED*/
+
+#define AB8500_REGU_MISC1_REG		0x0380
+#define AB8500_REGU_OTGSUPPLY_CTRL_REG	0x0381
+#define AB8500_REGU_VUSB_CTRL_REG	0x0382 /* see reg manaul*/
+#define AB8500_REGU_VAUDIO_SUPPLY_REG	0x0383
+#define AB8500_REGU_CTRL1_SPARE_REG	0x0384
+
+ /*
+ * Regu control2 register offsets (SPI/APE I2C)
+ * Bank = 0x04
+ */
+#define AB8500_REGU_ARM_REGU1_REG	0x0400
+#define AB8500_REGU_ARM_REGU2_REG	0x0401
+#define AB8500_REGU_VAPE_REGU_REG	0x0402
+#define AB8500_REGU_VSMPS1_REGU_REG	0x0403
+#define AB8500_REGU_VSMPS2_REGU_REG	0x0404
+#define AB8500_REGU_VSMPS3_REGU_REG	0x0405
+#define AB8500_REGU_VPLLVANA_REGU_REG	0x0406
+#define AB8500_REGU_VREF_DDR_REG	0x0407
+#define AB8500_REGU_EXTSUPPLY_REGU_REG	0x0408
+#define AB8500_REGU_VAUX12_REGU_REG	0x0409
+#define AB8500_REGU_VAUX12_REGU_VAUX1_MASK     0x3
+#define AB8500_REGU_VAUX12_REGU_VAUX1_SHIFT    0
+#define AB8500_REGU_VAUX12_REGU_VAUX1_FORCE_HP 0x1
+#define AB8500_REGU_VRF1VAUX3_REGU_REG	0x040A
+#define AB8500_REGU_VARM_SEL1_REG	0x040B
+#define AB8500_REGU_VARM_SEL2_REG	0x040C
+#define AB8500_REGU_VARM_SEL3_REG	0x040D
+#define AB8500_REGU_VAPE_SEL1_REG	0x040E
+#define AB8500_REGU_VAPE_SEL2_REG	0x040F
+#define AB8500_REGU_VAPE_SEL3_REG	0x0410
+#define AB8500_REGU_VBB_SEL2_REG	0x0412
+#define AB8500_REGU_VSMPS1_SEL1_REG	0x0413
+#define AB8500_REGU_VSMPS1_SEL2_REG	0x0414
+#define AB8500_REGU_VSMPS1_SEL3_REG	0x0415
+#define AB8500_REGU_VSMPS2_SEL1_REG	0x0417
+#define AB8500_REGU_VSMPS2_SEL2_REG	0x0418
+#define AB8500_REGU_VSMPS2_SEL3_REG	0x0419
+#define AB8500_REGU_VSMPS3_SEL1_REG	0x041B
+#define AB8500_REGU_VSMPS3_SEL2_REG	0x041C
+#define AB8500_REGU_VSMPS3_SEL3_REG	0x041D
+#define AB8500_REGU_VAUX1_SEL_REG	0x041F
+#define AB8500_REGU_VAUX1_SEL_MASK     0xf
+#define AB8500_REGU_VAUX1_SEL_SHIFT    0
+#define AB8500_REGU_VAUX1_SEL_1_5V     0x4
+#define AB8500_REGU_VAUX1_SEL_2_5V     0x8
+#define AB8500_REGU_VAUX2_SEL_REG	0x0420
+#define AB8500_REGU_VRF1VAUX3_SEL_REG	0x0421
+#define AB8500_REGU_CTRL2_SPARE_REG	0x0422
+
+/*
+ * Regu control2 Vmod register offsets
+ */
+#define AB8500_REGU_VMOD_REGU_REG	0x0440
+#define AB8500_REGU_VMOD_SEL1_REG	0x0441
+#define AB8500_REGU_VMOD_SEL2_REG	0x0442
+#define AB8500_REGU_CTRL_DISCH_REG	0x0443
+#define AB8500_REGU_CTRL_DISCH2_REG	0x0444
+
+/*
+ * Sim control register offsets
+ * Bank:0x4
+ */
+#define AB8500_SIM_REG1_SGR1L_REG		0x0480
+#define AB8500_SIM_REG1_SGR1U_REG		0x0481
+#define AB8500_SIM_REG2_SCR1L_REG		0x0482
+#define AB8500_SIM_REG2_SCR1U_REG		0x0483
+#define AB8500_SIM_REG3_SCTRLRL_REG		0x0484
+#define AB8500_SIM_REG3_SCTRLRU_REG		0x0485
+#define AB8500_SIM_ISOUICCINT_SRC_REG		0x0486
+#define AB8500_SIM_ISOUICCINT_LATCH_REG	0x0487
+#define AB8500_SIM_ISOUICCINT_MASK_REG		0x0488
+#define AB8500_SIM_REG4_USBUICC_REG		0x0489
+#define AB8500_SIM_SDELAYSEL_REG		0x048A
+#define AB8500_SIM_USBUICC_CTRL		0x048B	/* bit 3 only for ED */
+
+/*
+ * USB/ULPI register offsets
+ * Bank : 0x5
+ */
+#define AB8500_USB_LINE_STAT_REG	0x0580
+#define AB8500_USB_LINE_CTRL1_REG	0x0581
+#define AB8500_USB_LINE_CTRL2_REG	0x0582
+#define AB8500_USB_LINE_CTRL3_REG	0x0583
+#define AB8500_USB_LINE_CTRL4_REG	0x0584
+#define AB8500_USB_LINE_CTRL5_REG	0x0585
+#define AB8500_USB_OTG_CTRL_REG	0x0587
+#define AB8500_USB_OTG_STAT_REG	0x0588
+#define AB8500_USB_OTG_STAT_REG	0x0588
+#define AB8500_USB_CTRL_SPARE_REG	0x0589
+#define AB8500_USB_PHY_CTRL_REG	0x058A	/*only in Cut1.0*/
+
+/*
+ * TVOUT / CTRL register offsets
+ * Bank : 0x06
+ */
+#define AB8500_DENC_CONF0_REG  0x0600
+#define AB8500_DENC_CONF1_REG  0x0601
+#define AB8500_DENC_CONF2_REG  0x0602
+#define AB8500_DENC_CONF3_REG  0x0603
+#define AB8500_DENC_CONF4_REG  0x0604
+#define AB8500_DENC_CONF5_REG  0x0605
+#define AB8500_DENC_CONF6_REG  0x0606
+#define AB8500_DENC_CONF6_SOFT_RST_MASK                0x80
+#define AB8500_DENC_CONF6_SOFT_RST_SHIFT       7
+#define AB8500_DENC_CONF6_SOFT_RST_OFF         0x0
+#define AB8500_DENC_CONF6_SOFT_RST_ON          0x1
+#define AB8500_DENC_CONF7_REG  0x0607
+#define AB8500_DENC_CONF8_REG  0x0608
+#define AB8500_TVOUT_CTRL_REG	0x0680
+#define AB8500_TVOUT_CTRL2_REG 0x0681
+/*
+ * DBI register offsets
+ * Bank : 0x07
+ */
+#define AB8500_DBI_REG1_REG	0x0700
+#define AB8500_DBI_REG2_REG	0x0701
+/*
+ * ECI regsiter offsets
+ * Bank : 0x08
+ */
+#define AB8500_ECI_CTRL_REG		0x0800
+#define AB8500_ECI_HOOKLEVEL_REG	0x0801
+#define AB8500_ECI_DATAOUT_REG		0x0802
+#define AB8500_ECI_DATAIN_REG		0x0803
+/*
+ * AV Connector register offsets
+ * Bank : 0x08
+ */
+#define AB8500_AV_CONN_REG	0x0840
+/*
+ * Accessory detection register offsets
+ * Bank : 0x08
+ */
+#define AB8500_ACC_DET_DB1_REG	0x0880
+#define AB8500_ACC_DET_DB2_REG	0x0881
+/*
+ * GPADC register offsets
+ * Bank : 0x0A
+ */
+#define AB8500_GPADC_CTRL1_REG		0x0A00
+#define AB8500_GPADC_CTRL2_REG		0x0A01
+#define AB8500_GPADC_CTRL3_REG		0x0A02
+#define AB8500_GPADC_AUTO_TIMER_REG	0x0A03
+#define AB8500_GPADC_STAT_REG		0x0A04
+#define AB8500_GPADC_MANDATAL_REG	0x0A05
+#define AB8500_GPADC_MANDATAH_REG	0x0A06
+#define AB8500_GPADC_AUTODATAL_REG	0x0A07
+#define AB8500_GPADC_AUTODATAH_REG	0x0A08
+#define AB8500_GPADC_MUX_CTRL_REG	0x0A09
+/*
+ * Charger / status register offfsets
+ * Bank : 0x0B
+ */
+#define AB8500_CH_STATUS1_REG		0x0B00
+#define AB8500_CH_STATUS2_REG		0x0B01
+#define AB8500_CH_USBCH_STAT1_REG	0x0B02
+#define AB8500_CH_USBCH_STAT2_REG	0x0B03
+#define AB8500_CH_FSM_STAT_REG		0x0B04
+#define AB8500_CH_STAT_REG		0x0B05
+/*
+ * Charger / control register offfsets
+ * Bank : 0x0B
+ */
+#define AB8500_CH_VOLT_LVL_REG		0x0B40
+#define AB8500_CH_VOLT_LVL_MAX_REG	0x0B41	/*Only in Cut1.0*/
+#define AB8500_CH_OPT_CRNTLVL_REG	0x0B42	/*Only in Cut1.0*/
+#define AB8500_CH_OPT_CRNTLVL_MAX_REG	0x0B43	/*Only in Cut1.0*/
+#define AB8500_CH_WD_TIMER_REG		0x0B44	/*Only in Cut1.0*/
+#define AB8500_CH_WD_CTRL_REG		0x0B45	/*Only in Cut1.0*/
+#define AB8500_CHARG_WD_CTRL            0x0B51
+#define AB8500_LED_INDICATOR_PWM_CTRL   0x0B53
+#define AB8500_LED_INDICATOR_PWM_DUTY   0x0B54
+#define AB8500_BATT_OVV                 0x0B55
+/*
+ * Charger / main control register offfsets
+ * Bank : 0x0B
+ */
+#define AB8500_MCH_CTRL1		0x0B80
+#define AB8500_MCH_CTRL2		0x0B81
+#define AB8500_MCH_IPT_CURLVL_REG	0x0B82
+#define AB8500_CH_WD_REG		0x0B83
+/*
+ * Charger / USB control register offsets
+ * Bank : 0x0B
+ */
+#define AB8500_USBCH_CTRL1_REG		0x0BC0
+#define AB8500_USBCH_CTRL2_REG		0x0BC1
+#define AB8500_USBCH_IPT_CRNTLVL_REG	0x0BC2
+/*
+ * Gas Gauge register offsets
+ * Bank : 0x0C
+ */
+#define AB8500_GASG_CC_CTRL_REG	0x0C00
+#define AB8500_GASG_CC_ACCU1_REG	0x0C01
+#define AB8500_GASG_CC_ACCU2_REG	0x0C02
+#define AB8500_GASG_CC_ACCU3_REG	0x0C03
+#define AB8500_GASG_CC_ACCU4_REG	0x0C04
+#define AB8500_GASG_CC_SMPL_CNTRL_REG	0x0C05
+#define AB8500_GASG_CC_SMPL_CNTRH_REG	0x0C06
+#define AB8500_GASG_CC_SMPL_CNVL_REG	0x0C07
+#define AB8500_GASG_CC_SMPL_CNVH_REG	0x0C08
+#define AB8500_GASG_CC_CNTR_AVGOFF_REG	0x0C09
+#define AB8500_GASG_CC_OFFSET_REG	0x0C0A
+#define AB8500_GASG_CC_NCOV_ACCU        0x0C10
+#define AB8500_GASG_CC_NCOV_ACCU_CTRL   0x0C11
+#define AB8500_GASG_CC_NCOV_ACCU_LOW    0x0C12
+#define AB8500_GASG_CC_NCOV_ACCU_MED    0x0C13
+#define AB8500_GASG_CC_NCOV_ACCU_HIGH   0x0C14
+
+
+
+/*
+ * Audio
+ * Bank : 0x0D
+ * Should be part of Audio codec driver
+ */
+#define AB8500_AUDIO_POWER_UP		0x0D00
+#define AB8500_AUDIO_ANA_CONF4		0x0D08
+#define AB8500_AUDIO_DA_PATH_CONF	0x0D09
+#define AB8500_AUDIO_PWM_GEN_CONF1	0x0D0F
+#define AB8500_AUDIO_PWM_GEN_CONF2	0x0D10
+#define AB8500_AUDIO_PWM_GEN_CONF3	0x0D11
+#define AB8500_AUDIO_PWM_GEN_CONF4	0x0D12
+#define AB8500_AUDIO_PWM_GEN_CONF5	0x0D13
+
+/*
+ * Interrupt register offsets
+ * Bank : 0x0E
+ */
+#define AB8500_IT_SOURCE1_REG	0x0E00
+#define AB8500_IT_SOURCE2_REG	0x0E01
+#define AB8500_IT_SOURCE3_REG	0x0E02
+#define AB8500_IT_SOURCE4_REG	0x0E03
+#define AB8500_IT_SOURCE5_REG	0x0E04
+#define AB8500_IT_SOURCE6_REG	0x0E05
+
+/* available only in 1.0 */
+#define AB8500_IT_SOURCE7_REG	0x0E06
+#define AB8500_IT_SOURCE8_REG	0x0E07
+#define AB8500_IT_SOURCE19_REG	0x0E12
+
+#define AB8500_IT_SOURCE20_REG	0x0E13
+#define AB8500_IT_SOURCE21_REG	0x0E14
+#define AB8500_IT_SOURCE22_REG	0x0E15
+#define AB8500_IT_SOURCE23_REG	0x0E16
+#define AB8500_IT_SOURCE24_REG	0x0E17
+
+/*
+ * latch registers
+ */
+#define AB8500_IT_LATCH1_REG	0x0E20
+#define AB8500_IT_LATCH2_REG	0x0E21
+#define AB8500_IT_LATCH3_REG	0x0E22
+#define AB8500_IT_LATCH4_REG	0x0E23
+#define AB8500_IT_LATCH5_REG	0x0E24
+#define AB8500_IT_LATCH6_REG	0x0E25
+
+/* available only in 1.0 */
+#define AB8500_IT_LATCH7_REG	0x0E26
+#define AB8500_IT_LATCH8_REG	0x0E27
+#define AB8500_IT_LATCH9_REG	0x0E28
+#define AB8500_IT_LATCH10_REG	0x0E29
+#define AB8500_IT_LATCH19_REG	0x0E32
+
+#define AB8500_IT_LATCH20_REG	0x0E33
+#define AB8500_IT_LATCH21_REG	0x0E34
+#define AB8500_IT_LATCH22_REG	0x0E35
+#define AB8500_IT_LATCH23_REG	0x0E36
+#define AB8500_IT_LATCH24_REG	0x0E37
+
+/*
+ * mask registers
+ */
+
+#define AB8500_IT_MASK1_REG	0x0E40
+#define AB8500_IT_MASK2_REG	0x0E41
+#define AB8500_IT_MASK3_REG	0x0E42
+#define AB8500_IT_MASK4_REG	0x0E43
+#define AB8500_IT_MASK5_REG	0x0E44
+#define AB8500_IT_MASK6_REG	0x0E45
+
+
+/* available only in 1.0 */
+#define AB8500_IT_MASK7_REG	0x0E46
+#define AB8500_IT_MASK8_REG	0x0E47
+#define AB8500_IT_MASK9_REG	0x0E48
+#define AB8500_IT_MASK10_REG	0x0E49
+#define AB8500_IT_MASK11_REG	0x0E4A
+#define AB8500_IT_MASK12_REG	0x0E4B
+#define AB8500_IT_MASK13_REG	0x0E4C
+#define AB8500_IT_MASK14_REG	0x0E4D
+#define AB8500_IT_MASK15_REG	0x0E4E
+#define AB8500_IT_MASK16_REG	0x0E4F
+#define AB8500_IT_MASK17_REG	0x0E50
+#define AB8500_IT_MASK18_REG	0x0E51
+#define AB8500_IT_MASK19_REG	0x0E52
+
+#define AB8500_IT_MASK20_REG	0x0E53
+#define AB8500_IT_MASK21_REG	0x0E54
+#define AB8500_IT_MASK22_REG	0x0E55
+#define AB8500_IT_MASK23_REG	0x0E56
+#define AB8500_IT_MASK24_REG	0x0E57
+
+/*
+ * RTC bank register offsets
+ * Bank : 0xF
+ */
+#define AB8500_RTC_SWITCHOFF_STAT_REG	0x0F00
+#define AB8500_RTC_CC_CONF_REG		0x0F01
+#define AB8500_RTC_READ_REQ_REG	0x0F02
+#define AB8500_RTC_WATCH_TSECMID_REG	0x0F03
+#define AB8500_RTC_WATCH_TSECHI_REG	0x0F04
+#define AB8500_RTC_WATCH_TMIN_LOW_REG	0x0F05
+#define AB8500_RTC_WATCH_TMIN_MID_REG	0x0F06
+#define AB8500_RTC_WATCH_TMIN_HI_REG	0x0F07
+#define AB8500_RTC_ALRM_MIN_LOW_REG	0x0F08
+#define AB8500_RTC_ALRM_MIN_MID_REG	0x0F09
+#define AB8500_RTC_ALRM_MIN_HI_REG	0x0F0A
+#define AB8500_RTC_STAT_REG		0x0F0B
+#define AB8500_RTC_BKUP_CHG_REG	0x0F0C
+#define AB8500_RTC_FORCE_BKUP_REG	0x0F0D
+#define AB8500_RTC_CALIB_REG		0x0F0E
+#define AB8500_RTC_SWITCH_STAT_REG	0x0F0F
+
+/*
+ * Misc block GPIO register offsets - Not for ED
+ * Bank : 0x10
+ */
+/* available only in 1.0 */
+#define AB8500_GPIO_SEL1_REG	0x01000
+#define AB8500_GPIO_SEL2_REG	0x01001
+#define AB8500_GPIO_SEL3_REG	0x01002
+#define AB8500_GPIO_SEL4_REG	0x01003
+#define AB8500_GPIO_SEL5_REG	0x01004
+#define AB8500_GPIO_SEL6_REG	0x01005
+#define AB8500_GPIO_DIR1_REG	0x01010
+#define AB8500_GPIO_DIR2_REG	0x01011
+#define AB8500_GPIO_DIR3_REG	0x01012
+#define AB8500_GPIO_DIR4_REG	0x01013
+#define AB8500_GPIO_DIR5_REG	0x01014
+#define AB8500_GPIO_DIR6_REG	0x01015
+
+#define AB8500_GPIO_OUT1_REG	0x01020
+#define AB8500_GPIO_OUT2_REG	0x01021
+#define AB8500_GPIO_OUT3_REG	0x01022
+#define AB8500_GPIO_OUT4_REG	0x01023
+#define AB8500_GPIO_OUT5_REG	0x01024
+#define AB8500_GPIO_OUT6_REG	0x01025
+
+#define AB8500_GPIO_PUD1_REG	0x01030
+#define AB8500_GPIO_PUD2_REG	0x01031
+#define AB8500_GPIO_PUD3_REG	0x01032
+#define AB8500_GPIO_PUD4_REG	0x01033
+#define AB8500_GPIO_PUD5_REG	0x01034
+#define AB8500_GPIO_PUD6_REG	0x01035
+
+#define AB8500_GPIO_IN1_REG	0x01040
+#define AB8500_GPIO_IN2_REG	0x01041
+#define AB8500_GPIO_IN3_REG	0x01042
+#define AB8500_GPIO_IN4_REG	0x01043
+#define AB8500_GPIO_IN5_REG	0x01044
+#define AB8500_GPIO_IN6_REG	0x01045
+#define AB8500_GPIO_ALT_FUNC	0x01050
+
+/*
+ * PWM Out generators
+ * Bank: 0x10
+ */
+#define AB8500_PWM_OUT_CTRL1_REG	0x1060
+#define AB8500_PWM_OUT_CTRL2_REG	0x1061
+#define AB8500_PWM_OUT_CTRL3_REG	0x1062
+#define AB8500_PWM_OUT_CTRL4_REG	0x1063
+#define AB8500_PWM_OUT_CTRL5_REG	0x1064
+#define AB8500_PWM_OUT_CTRL6_REG	0x1065
+#define AB8500_PWM_OUT_CTRL7_REG	0x1066
+
+#define AB8500_I2C_PAD_CTRL_REG	0x1067
+#define AB8500_REV_REG			0x1080
+
+/*
+ * Misc, Debug Test Configuration register
+ * Bank : 0x11
+ */
+#define AB8500_DEBUG_TESTMODE_REG	0x01100
+
+/* only in 1.0 */
+#define AB8500_I2C_TRIG1_ADR_REG	0x1101
+#define AB8500_I2C_TRIG1_ID_REG	0x1102
+#define AB8500_I2C_TRIG2_ADR_REG	0x1103
+#define AB8500_I2C_TRIG3_ID_REG	0x1104
+#define AB8500_I2C_NOACCESS_SUP_REG	0x1105
+
+/* Offsets in TurnOnstatus register
+ */
+
+#define AB8500_MAX_INT		192
+#define AB8500_MAX_FUTURE_USE	105
+
+#define AB8500_MAX_INT_SOURCE	11
+#define AB8500_MAX_INT_LATCH	13
+#define AB8500_MAX_INT_MASK	21
+
+#define ab8500_read	prcmu_i2c_read
+#define ab8500_write	prcmu_i2c_write
+
+extern int prcmu_i2c_read(u8 reg, u16 slave);
+extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
+
+#endif /* AB8500_H_ */
diff --git a/arch/arm/include/asm/arch-u8500/bits.h b/arch/arm/include/asm/arch-u8500/bits.h
new file mode 100644
index 0000000..17e2f09
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/bits.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+#ifndef __bits_h
+#define __bits_h 1
+
+#define BIT0  (1<<0)
+#define BIT1  (1<<1)
+#define BIT2  (1<<2)
+#define BIT3  (1<<3)
+#define BIT4  (1<<4)
+#define BIT5  (1<<5)
+#define BIT6  (1<<6)
+#define BIT7  (1<<7)
+#define BIT8  (1<<8)
+#define BIT9  (1<<9)
+#define BIT10 (1<<10)
+#define BIT11 (1<<11)
+#define BIT12 (1<<12)
+#define BIT13 (1<<13)
+#define BIT14 (1<<14)
+#define BIT15 (1<<15)
+#define BIT16 (1<<16)
+#define BIT17 (1<<17)
+#define BIT18 (1<<18)
+#define BIT19 (1<<19)
+#define BIT20 (1<<20)
+#define BIT21 (1<<21)
+#define BIT22 (1<<22)
+#define BIT23 (1<<23)
+#define BIT24 (1<<24)
+#define BIT25 (1<<25)
+#define BIT26 (1<<26)
+#define BIT27 (1<<27)
+#define BIT28 (1<<28)
+#define BIT29 (1<<29)
+#define BIT30 (1<<30)
+#define BIT31 (1<<31)
+
+#endif
diff --git a/arch/arm/include/asm/arch-u8500/clock.h b/arch/arm/include/asm/arch-u8500/clock.h
new file mode 100644
index 0000000..b00ab0d
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/clock.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_CLOCK
+#define __ASM_ARCH_CLOCK
+
+struct prcmu {
+	unsigned int armclkfix_mgt;
+	unsigned int armclk_mgt;
+	unsigned int svammdspclk_mgt;
+	unsigned int siammdspclk_mgt;
+	unsigned int reserved;
+	unsigned int sgaclk_mgt;
+	unsigned int uartclk_mgt;
+	unsigned int msp02clk_mgt;
+	unsigned int i2cclk_mgt;
+	unsigned int sdmmcclk_mgt;
+	unsigned int slimclk_mgt;
+	unsigned int per1clk_mgt;
+	unsigned int per2clk_mgt;
+	unsigned int per3clk_mgt;
+	unsigned int per5clk_mgt;
+	unsigned int per6clk_mgt;
+	unsigned int per7clk_mgt;
+	unsigned int lcdclk_mgt;
+	unsigned int reserved1;
+	unsigned int bmlclk_mgt;
+	unsigned int hsitxclk_mgt;
+	unsigned int hsirxclk_mgt;
+	unsigned int hdmiclk_mgt;
+	unsigned int apeatclk_mgt;
+	unsigned int apetraceclk_mgt;
+	unsigned int mcdeclk_mgt;
+	unsigned int ipi2cclk_mgt;
+	unsigned int dsialtclk_mgt;
+	unsigned int spare2clk_mgt;
+	unsigned int dmaclk_mgt;
+	unsigned int b2r2clk_mgt;
+	unsigned int tvclk_mgt;
+	unsigned int unused[82];
+	unsigned int tcr;
+	unsigned int unused1[23];
+	unsigned int ape_softrst;
+};
+
+extern void u8500_clock_enable(int periph, int kern, int cluster);
+
+static inline void u8500_prcmu_enable(unsigned int *reg)
+{
+	writel(readl(reg) | (1 << 8), reg);
+}
+
+#endif /* __ASM_ARCH_CLOCK */
diff --git a/arch/arm/include/asm/arch-u8500/common.h b/arch/arm/include/asm/arch-u8500/common.h
new file mode 100644
index 0000000..ab8a4db
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/common.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+#ifndef _COMMON_H_
+#define _COMMON_H_
+#include <common.h>
+
+#define PASS (1)
+#define FAIL (0)
+
+#define IO(addr)  (*((u32 *) (addr)))
+#define HIO(addr) (*((u16 *) (addr)))
+#define BIO(addr) (*((u8 *)  (addr)))
+
+/*
+ * macro to get at IO space
+ */
+#define IO_ADDRESS(x) (x)
+
+#define REG_WRITE_BITS(reg, val, mask, sb) \
+	(writel(((readl(reg) & ~(mask)) | (((val)<<(sb)) & (mask))), reg))
+
+#define nmdk_error(format, arg...) printf(": " format "\n" , ## arg)
+
+/*-----------------------------------------------------------------------------
+ * Bit mask definition
+ *---------------------------------------------------------------------------*/
+#define MASK_NULL8    0x00
+#define MASK_NULL16   0x0000
+#define MASK_NULL32   0x00000000
+#define MASK_ALL8     0xFF
+#define MASK_ALL16    0xFFFF
+#define MASK_ALL32    0xFFFFFFFF
+
+#define MASK_BIT0     (1UL<<0)
+#define MASK_BIT1     (1UL<<1)
+#define MASK_BIT2     (1UL<<2)
+#define MASK_BIT3     (1UL<<3)
+#define MASK_BIT4     (1UL<<4)
+#define MASK_BIT5     (1UL<<5)
+#define MASK_BIT6     (1UL<<6)
+#define MASK_BIT7     (1UL<<7)
+#define MASK_BIT8     (1UL<<8)
+#define MASK_BIT9     (1UL<<9)
+#define MASK_BIT10    (1UL<<10)
+#define MASK_BIT11    (1UL<<11)
+#define MASK_BIT12    (1UL<<12)
+#define MASK_BIT13    (1UL<<13)
+#define MASK_BIT14    (1UL<<14)
+#define MASK_BIT15    (1UL<<15)
+#define MASK_BIT16    (1UL<<16)
+#define MASK_BIT17    (1UL<<17)
+#define MASK_BIT18    (1UL<<18)
+#define MASK_BIT19    (1UL<<19)
+#define MASK_BIT20    (1UL<<20)
+#define MASK_BIT21    (1UL<<21)
+#define MASK_BIT22    (1UL<<22)
+#define MASK_BIT23    (1UL<<23)
+#define MASK_BIT24    (1UL<<24)
+#define MASK_BIT25    (1UL<<25)
+#define MASK_BIT26    (1UL<<26)
+#define MASK_BIT27    (1UL<<27)
+#define MASK_BIT28    (1UL<<28)
+#define MASK_BIT29    (1UL<<29)
+#define MASK_BIT30    (1UL<<30)
+#define MASK_BIT31    (1UL<<31)
+
+#define NOMADIK_INTERNAL_ERROR                  (-8)
+#define NOMADIK_NOT_CONFIGURED                  (-7)
+#define NOMADIK_REQUEST_PENDING                 (-6)
+#define NOMADIK_REQUEST_NOT_APPLICABLE          (-5)
+#define NOMADIK_INVALID_PARAMETER               (-4)
+#define NOMADIK_UNSUPPORTED_FEATURE             (-3)
+#define NOMADIK_UNSUPPORTED_HW                  (-2)
+#define NOMADIK_ERROR                           (-1)
+#define NOMADIK_OK                              (0)
+#define NOMADIK_INTERNAL_EVENT                  (1)
+#define NOMADIK_REMAINING_PENDING_EVENTS        (2)
+#define NOMADIK_REMAINING_FILTER_PENDING_EVENTS (3)
+#define NOMADIK_NO_MORE_PENDING_EVENT           (4)
+#define NOMADIK_NO_MORE_FILTER_PENDING_EVENT    (5)
+#define NOMADIK_NO_PENDING_EVENT_ERROR          (7)
+
+
+void gpio_init(void);
+void arm_pl180_mmci_init(void);
+
+
+#endif  /* _COMMON_H_ */
diff --git a/arch/arm/include/asm/arch-u8500/gpio.h b/arch/arm/include/asm/arch-u8500/gpio.h
new file mode 100644
index 0000000..39982a6
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/gpio.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _UX500_GPIO_h
+#define _UX500_GPIO_h
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "common.h"
+#include <asm/arch/u8500.h>
+
+#define GPIO_TOTAL_PINS                 268
+
+#define GPIO_PINS_PER_BLOCK	32
+#define GPIO_BLOCKS_COUNT       (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK + 1)
+#define GPIO_BLOCK(pin)		(((pin + GPIO_PINS_PER_BLOCK) >> 5) - 1)
+
+
+struct gpio_register {
+	u32 gpio_dat;	/* data register *//*0x000 */
+	u32 gpio_dats;	/* data Set register *//*0x004 */
+	u32 gpio_datc;	/* data Clear register *//*0x008 */
+	u32 gpio_pdis;	/* Pull disable register *//*0x00C */
+	u32 gpio_dir;	/* data direction register *//*0x010 */
+	u32 gpio_dirs;	/* data dir Set register *//*0x014 */
+	u32 gpio_dirc;	/* data dir Clear register *//*0x018 */
+	u32 gpio_slpm;	/* Sleep mode register *//*0x01C */
+	u32 gpio_afsa;	/* AltFun A Select reg *//*0x020 */
+	u32 gpio_afsb;	/* AltFun B Select reg *//*0x024 */
+	u32 gpio_lowemi;/* low EMI Select reg *//*0x028 */
+	u32 reserved_1[(0x040 - 0x02C) >> 2];	/*0x028-0x3C Reserved*/
+	u32 gpio_rimsc;	/* rising edge intr set/clear *//*0x040 */
+	u32 gpio_fimsc;	/* falling edge intr set/clear register *//*0x044 */
+	u32 gpio_mis;	/* masked interrupt status register *//*0x048 */
+	u32 gpio_ic;	/* Interrupt Clear register *//*0x04C */
+	u32 gpio_rwimsc;/* Rising-edge Wakeup IMSC register *//*0x050 */
+	u32 gpio_fwimsc;/* Falling-edge Wakeup IMSC register *//*0x054 */
+	u32 gpio_wks;	/* Wakeup Status register *//*0x058 */
+};
+
+/* Error values returned by functions */
+enum gpio_error {
+	GPIO_OK = 0,
+	GPIO_UNSUPPORTED_HW = -2,	/* NOMADIK_UNSUPPORTED_HW */
+	GPIO_UNSUPPORTED_FEATURE = -3,	/* NOMADIK_UNSUPPORTED_FEATURE */
+	GPIO_INVALID_PARAMETER = -4,	/* NOMADIK_INVALID_PARAMETER */
+	GPIO_REQUEST_NOT_APPLICABLE = -5, /* NOMADIK_REQUEST_NOT_APPLICABLE */
+	GPIO_REQUEST_PENDING = -6,	/* NOMADIK_REQUEST_PENDING */
+	GPIO_NOT_CONFIGURED = -7,	/* NOMADIK_NOT_CONFIGURED */
+	GPIO_INTERNAL_ERROR = -8,	/* NOMADIK_INTERNAL_ERROR */
+	GPIO_INTERNAL_EVENT = 1,	/* NOMADIK_INTERNAL_EVENT */
+	GPIO_REMAINING_EVENT = 2,	/* NOMADIK_REMAINING_PENDING_EVENTS */
+	GPIO_NO_MORE_PENDING_EVENT = 3,	/* NOMADIK_NO_MORE_PENDING_EVENT */
+	GPIO_INVALID_CLIENT = -25,
+	GPIO_INVALID_PIN = -26,
+	GPIO_PIN_BUSY = -27,
+	GPIO_PIN_NOT_ALLOCATED = -28,
+	GPIO_WRONG_CLIENT = -29,
+	GPIO_UNSUPPORTED_ALTFUNC = -30,
+};
+
+/*GPIO DEVICE ID */
+enum gpio_device_id {
+	GPIO_DEVICE_ID_0,
+	GPIO_DEVICE_ID_1,
+	GPIO_DEVICE_ID_2,
+	GPIO_DEVICE_ID_3,
+	GPIO_DEVICE_ID_INVALID
+};
+
+/*
+ * Alternate Function:
+ *  refered in altfun_table to pointout particular altfun to be enabled
+ *  when using GPIO_ALT_FUNCTION A/B/C enable/disable operation
+ */
+enum gpio_alt_function {
+	GPIO_ALT_UART_0_MODEM,
+	GPIO_ALT_UART_0_NO_MODEM,
+	GPIO_ALT_UART_1,
+	GPIO_ALT_UART_2,
+	GPIO_ALT_I2C_0,
+	GPIO_ALT_I2C_1,
+	GPIO_ALT_I2C_2,
+	GPIO_ALT_I2C_3,
+	GPIO_ALT_MSP_0,
+	GPIO_ALT_MSP_1,
+	GPIO_ALT_MSP_2,
+	GPIO_ALT_MSP_3,
+	GPIO_ALT_MSP_4,
+	GPIO_ALT_MSP_5,
+	GPIO_ALT_SSP_0,
+	GPIO_ALT_SSP_1,
+	GPIO_ALT_MM_CARD0,
+	GPIO_ALT_SD_CARD0,
+	GPIO_ALT_DMA_0,
+	GPIO_ALT_DMA_1,
+	GPIO_ALT_HSI0,
+	GPIO_ALT_CCIR656_INPUT,
+	GPIO_ALT_CCIR656_OUTPUT,
+	GPIO_ALT_LCD_PANEL,
+	GPIO_ALT_MDIF,
+	GPIO_ALT_SDRAM,
+	GPIO_ALT_HAMAC_AUDIO_DBG,
+	GPIO_ALT_HAMAC_VIDEO_DBG,
+	GPIO_ALT_CLOCK_RESET,
+	GPIO_ALT_TSP,
+	GPIO_ALT_IRDA,
+	GPIO_ALT_USB_MINIMUM,
+	GPIO_ALT_USB_I2C,
+	GPIO_ALT_OWM,
+	GPIO_ALT_PWL,
+	GPIO_ALT_FSMC,
+	GPIO_ALT_COMP_FLASH,
+	GPIO_ALT_SRAM_NOR_FLASH,
+	GPIO_ALT_FSMC_ADDLINE_0_TO_15,
+	GPIO_ALT_SCROLL_KEY,
+	GPIO_ALT_MSHC,
+	GPIO_ALT_HPI,
+	GPIO_ALT_USB_OTG,
+	GPIO_ALT_SDIO,
+	GPIO_ALT_HSMMC,
+	GPIO_ALT_FSMC_ADD_DATA_0_TO_25,
+	GPIO_ALT_HSI1,
+	GPIO_ALT_NOR,
+	GPIO_ALT_NAND,
+	GPIO_ALT_KEYPAD,
+	GPIO_ALT_VPIP,
+	GPIO_ALT_CAM,
+	GPIO_ALT_CCP1,
+	GPIO_ALT_EMMC,
+	GPIO_ALT_POP_EMMC,
+	GPIO_ALT_FUNMAX		/* Add new alt func before this */
+};
+
+/* Defines pin assignment(Software mode or Alternate mode) */
+enum gpio_mode {
+	GPIO_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_MODE_SOFTWARE,	/* Pin connected to GPIO (SW controlled) */
+	GPIO_ALTF_A,		/* Pin connected to altfunc 1 (HW periph 1) */
+	GPIO_ALTF_B,		/* Pin connected to altfunc 2 (HW periph 2) */
+	GPIO_ALTF_C,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_FIND,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_DISABLE	/* Pin connected to altfunc 3 (HW periph 3) */
+};
+
+/* Defines GPIO pin direction */
+enum gpio_direction {
+	GPIO_DIR_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_DIR_INPUT,		/* GPIO set as input */
+	GPIO_DIR_OUTPUT		/* GPIO set as output */
+};
+
+/* Interrupt trigger mode */
+enum gpio_trig {
+	GPIO_TRIG_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_TRIG_DISABLE,	/* Trigger no IT */
+	GPIO_TRIG_RISING_EDGE,	/* Trigger an IT on rising edge */
+	GPIO_TRIG_FALLING_EDGE,	/* Trigger an IT on falling edge */
+	GPIO_TRIG_BOTH_EDGES,	/* Trigger an IT on rising and falling edge */
+	GPIO_TRIG_HIGH_LEVEL,	/* Trigger an IT on high level */
+	GPIO_TRIG_LOW_LEVEL	/* Trigger an IT on low level */
+};
+
+/* Configuration parameters for one GPIO pin.*/
+struct gpio_config {
+	enum gpio_mode mode;
+	enum gpio_direction direction;
+	enum gpio_trig trig;
+	char *dev_name;		/* Who owns the gpio pin */
+};
+
+/* GPIO pin data*/
+enum gpio_data {
+	GPIO_DATA_LOW,
+	GPIO_DATA_HIGH
+};
+
+/* GPIO behaviour in sleep mode */
+enum gpio_sleep_mode {
+	GPIO_SLEEP_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,	/* GPIO is an input with pull
+						   up/down enabled when in sleep
+						   mode. */
+	GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO	/* GPIO pin is controlled by
+						   GPIO IP. So mode, direction
+						   and data values for GPIO pin
+						   in sleep mode are determined
+						   by configuration set to GPIO
+						   pin before entering to sleep
+						   mode. */
+};
+
+/* GPIO ability to wake the system up from sleep mode.*/
+enum gpio_wake {
+	GPIO_WAKE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_WAKE_DISABLE,	/* No wake of system from sleep mode. */
+	GPIO_WAKE_LOW_LEVEL,	/* Wake the system up on a LOW level. */
+	GPIO_WAKE_HIGH_LEVEL,	/* Wake the system up on a HIGH level. */
+	GPIO_WAKE_RISING_EDGE,	/* Wake the system up on a RISING edge. */
+	GPIO_WAKE_FALLING_EDGE,	/* Wake the system up on a FALLING edge. */
+	GPIO_WAKE_BOTH_EDGES	/* Wake the system up on both RISE and FALL. */
+};
+
+/* Configuration parameters for one GPIO pin in sleep mode.*/
+struct gpio_sleep_config {
+	enum gpio_sleep_mode sleep_mode;/* GPIO behaviour in sleep mode. */
+	enum gpio_wake wake;		/* GPIO ability to wake up system. */
+};
+
+extern int gpio_setpinconfig(int pin_id, struct gpio_config *pin_config);
+extern int gpio_resetpinconfig(int pin_id, char *dev_name);
+extern int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name);
+extern int gpio_readpin(int pin_id, enum gpio_data *value);
+extern int gpio_altfuncenable(enum gpio_alt_function altfunc,
+				      char *dev_name);
+extern int gpio_altfuncdisable(enum gpio_alt_function altfunc,
+				       char *dev_name);
+
+struct gpio_altfun_data {
+	u16 altfun;
+	u16 start;
+	u16 end;
+	u16 cont;
+	u8 type;
+};
+#endif
diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h
new file mode 100644
index 0000000..6bb95ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/hardware.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Peripheral clusters */
+
+#define U8500_PER3_BASE		0x80000000
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_PER4_BASE		0x80150000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER7_BASE		0xa03d0000
+#define U8500_PER5_BASE		0xa03e0000
+
+/* GPIO */
+
+#define U8500_GPIO0_BASE	(U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO2_BASE	(U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xE000 + 0x80)
+#define U8500_GPIO4_BASE	(U8500_PER3_BASE + 0xE000 + 0x100)
+#define U8500_GPIO5_BASE	(U8500_PER3_BASE + 0xE000 + 0x180)
+
+#define U8500_GPIO6_BASE	(U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO7_BASE	(U8500_PER2_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO8_BASE	(U8500_PER5_BASE + 0x1E000)
+
+/* Per7 */
+#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* Per6 */
+#define U8500_MTU0_BASE_V1	(U8500_PER6_BASE + 0x6000)
+#define U8500_MTU1_BASE_V1	(U8500_PER6_BASE + 0x7000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+
+/* Per5 */
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+
+/* Per4 */
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x0f000)
+
+/* Per3 */
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+
+/* Per2 */
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* Per1 */
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+
+/* Last page of Boot ROM */
+#define U8500_BOOTROM_BASE      0x9001f000
+#define U8500_BOOTROM_ASIC_ID_OFFSET    0x0ff4
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-u8500/u8500.h b/arch/arm/include/asm/arch-u8500/u8500.h
new file mode 100644
index 0000000..0d6dbb7
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/u8500.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __U8500_H
+#define __U8500_H
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   Management Unit */
+#define CFG_SDRAMC_BASE		0x903CF000	/* SDRAMC cnf registers */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+/*
+ * U8500 GPIO register base for 9 banks
+ */
+#define U8500_GPIO_0_BASE			0x8012E000
+#define U8500_GPIO_1_BASE			0x8012E080
+#define U8500_GPIO_2_BASE			0x8000E000
+#define U8500_GPIO_3_BASE			0x8000E080
+#define U8500_GPIO_4_BASE			0x8000E100
+#define U8500_GPIO_5_BASE			0x8000E180
+#define U8500_GPIO_6_BASE			0x8011E000
+#define U8500_GPIO_7_BASE			0x8011E080
+#define U8500_GPIO_8_BASE			0xA03FE000
+
+#endif	/* __U8500_H */
-- 
1.7.1

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

* [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
  2011-03-22 20:40 ` [U-Boot] [PATCH 1/4] p101x: extra init for u8500 John Rigby
  2011-03-22 20:40 ` [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-03-22 20:40 ` John Rigby
  2011-03-23  7:00   ` Heiko Schocher
  2011-03-22 20:40 ` [U-Boot] [PATCH 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:40 UTC (permalink / raw)
  To: u-boot

From: Michael Brandt <michael.brandt@stericsson.com>

Signed-off-by: John Rigby <john.rigby@linaro.org>
---
 drivers/i2c/Makefile    |    1 +
 drivers/i2c/u8500_i2c.c |  603 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h |  220 +++++++++++++++++
 3 files changed, 824 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..ac9c00f 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_DRIVER_U8500_I2C) += u8500_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
new file mode 100644
index 0000000..8965100
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.c
@@ -0,0 +1,603 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Basic U-Boot I2C interface for STn8500/DB8500
+ * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Only 7-bit I2C device addresses are supported.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "u8500_i2c.h"
+#include <asm/io.h>
+#include <asm/arch/common.h>
+#include <asm/arch/clock.h>
+
+#define I2C_ENDAD_COUNTER	(CONFIG_SYS_HZ/100)	/* I2C bus timeout */
+#define I2C_FIFO_FLUSH_COUNTER	500000		/* flush "timeout" */
+#define I2C_SCL_FREQ		100000		/* I2C bus clock frequency.*/
+#define I2C_INPUT_FREQ		48000000	/* Input clock frequency.*/
+#define TX_FIFO_THRESHOLD	0x4
+#define RX_FIFO_THRESHOLD	0x4
+#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
+
+#define WRITE_FIELD(var, mask, shift, value) \
+			(var = ((var & ~(mask)) | ((value) << (shift))))
+
+static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
+static unsigned int i2c_bus_num;
+static unsigned int i2c_bus_speed[] = {
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
+};
+static struct u8500_i2c_regs *i2c_dev[] = {
+	(struct u8500_i2c_regs *)CONFIG_SYS_I2C0_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_I2C1_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_I2C2_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_I2C3_BASE,
+};
+
+static struct {
+	int periph;
+	int pcken;
+	int kcken;
+} i2c_clock_bits[] = {
+	{3, 3, 3}, /* I2C0 */
+	{1, 2, 2}, /* I2C1 */
+	{1, 6, 6}, /* I2C2 */
+	{2, 0, 0}, /* I2C3 */
+};
+
+static void i2c_set_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) | mask, reg);
+}
+
+static void i2c_clr_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) & ~mask, reg);
+}
+
+static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
+{
+	writel((readl(reg) & ~mask) | (value << shift), reg);
+}
+
+static int __i2c_set_bus_speed(unsigned int speed)
+{
+	u32 value;
+	struct u8500_i2c_regs *i2c_regs;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Select standard (100 kbps) speed mode */
+	i2c_write_field(&i2c_regs->cr, I2C_CR_SM, I2C_CR_SHIFT_SM, 0x0);
+
+	/*
+	 * Set the Baud Rate Counter 2 value
+	 * Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
+	 * Foncycle = 0 (no digital filtering)
+	 */
+	value = (u32) (I2C_INPUT_FREQ / (speed * 2));
+	i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT2,
+			I2C_BRCR_SHIFT_BRCNT2, value);
+
+	/* ensure that BRCNT value is zero */
+	i2c_write_field(&i2c_regs->brcr, I2C_BRCR_BRCNT1,
+			I2C_BRCR_SHIFT_BRCNT1, 0);
+
+	return I2C_INPUT_FREQ/(value * 2);
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *
+ *	speed: bus speed (in HZ)
+ *	slaveaddr: address of device in slave mode
+ *
+ *	Slave mode is not implemented.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+	struct u8500_i2c_regs *i2c_regs;
+
+	debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
+
+	u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
+			   i2c_clock_bits[i2c_bus_num].pcken,
+			   i2c_clock_bits[i2c_bus_num].kcken);
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Disable the controller */
+	i2c_clr_bit(&i2c_regs->cr, I2C_CR_PE);
+
+	/* Clear registers */
+	writel(0, &i2c_regs->cr);
+	writel(0, &i2c_regs->scr);
+	writel(0, &i2c_regs->hsmcr);
+	writel(0, &i2c_regs->tftr);
+	writel(0, &i2c_regs->rftr);
+	writel(0, &i2c_regs->dmar);
+
+	i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
+
+	/*
+	 * Set our own address.
+	 * Set slave address mode to 7 bit addressing mode
+	 */
+	i2c_clr_bit(&i2c_regs->cr, I2C_CR_SAM);
+	i2c_write_field(&i2c_regs->scr, I2C_SCR_ADDR, I2C_SCR_SHIFT_ADDR,
+			slaveaddr);
+	/* Slave Data Set up Time */
+	i2c_write_field(&i2c_regs->scr, I2C_SCR_DATA_SETUP_TIME,
+			I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
+
+	/* Disable the DMA sync logic */
+	i2c_write_field(&i2c_regs->cr, I2C_CR_DMA_SLE,
+			I2C_CR_SHIFT_DMA_SLE, 0);
+
+	/* Disable interrupts */
+	writel(0, &i2c_regs->imscr);
+
+	/* Configure bus master mode */
+	i2c_write_field(&i2c_regs->cr, I2C_CR_OM, I2C_CR_SHIFT_OM,
+							I2C_BUS_MASTER_MODE);
+	/* Set FIFO threshold values */
+	writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
+	writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
+
+	/* Enable the I2C Controller */
+	i2c_set_bit(&i2c_regs->cr, I2C_CR_PE);
+
+	bus_initialized[i2c_bus_num] = 1;
+}
+
+
+/*
+ * loop_till_bit_clear - polls on a bit till it clears
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) == 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_clear timed out\n");
+	return -1;
+}
+
+/*
+ * loop_till_bit_set - polls on a bit till it is set.
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) != 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_set timed out\n");
+	return -1;
+}
+
+/*
+ * flush_fifo - flush the I2C TX and RX FIFOs
+ */
+static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
+{
+	int counter = I2C_FIFO_FLUSH_COUNTER;
+
+	/* Flush Tx FIFO */
+	i2c_set_bit(&i2c_regs->cr, I2C_CR_FTX);
+	/* Flush Rx FIFO */
+	i2c_set_bit(&i2c_regs->cr, I2C_CR_FRX);
+	while (counter--) {
+		if (!(readl(&i2c_regs->cr) & (I2C_CR_FTX | I2C_CR_FRX)))
+			break;
+	}
+	return;
+}
+
+#ifdef DEBUG
+static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
+{
+	int cause;
+
+	printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
+	cause = (readl(&i2c_regs->sr) & I2C_SR_CAUSE) >> I2C_SR_SHIFT_CAUSE;
+	switch (cause) {
+	case I2C_NACK_ADDR:
+		printf("No Ack received after Slave Address xmission\n");
+		break;
+	case I2C_NACK_DATA:
+		printf("Valid for MASTER_WRITE: No Ack received "
+				"during data phase\n");
+		break;
+	case I2C_ACK_MCODE:
+		printf("Master recv ack after xmission of master code"
+				"in hs mode\n");
+		break;
+	case I2C_ARB_LOST:
+		printf("Master Lost arbitration\n");
+		break;
+	case I2C_BERR_START:
+		printf("Slave restarts\n");
+		break;
+	case I2C_BERR_STOP:
+		printf("Slave reset\n");
+		break;
+	case I2C_OVFL:
+		printf("Overflow\n");
+		break;
+	default:
+		printf("Unknown error type\n");
+	}
+}
+#endif
+
+/*
+ * i2c_abort - called when a I2C transaction failed
+ */
+static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
+{
+#ifdef DEBUG
+	print_abort_reason(i2c_regs);
+#endif
+	/* flush RX and TX fifos */
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
+
+	i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
+}
+
+/*
+ * write addr, alias index, to I2C bus.
+ */
+static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
+{
+	while (alen--) {
+		/* Wait until the Tx Fifo is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					I2C_INT_TXFF, I2C_ENDAD_COUNTER)) {
+			i2c_abort(i2c_regs);
+			return -1;
+		}
+
+		/* MSB first */
+		writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
+	}
+
+	return 0;
+}
+
+/*
+ * Internal simplified read function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   value:	Where to put the data
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
+		uint addr, int alen, uchar *value)
+{
+	u32   mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);
+
+	if (alen != 0) {
+		/* Master write operation */
+		mcr &= ~(I2C_MCR_OP);
+
+		/* Configure the Frame length to one byte */
+		WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);
+
+		/* Repeated start, no stop */
+		mcr &= ~(I2C_MCR_STOP);
+
+		/* Write Master Control Register */
+		writel(mcr, &i2c_regs->mcr);
+
+		/* send addr/index */
+		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+			return -1;
+
+		/* Check for the Master Transaction Done Without Stop */
+		if (loop_till_bit_set((void *)&i2c_regs->risr,
+					I2C_INT_MTDWS, I2C_ENDAD_COUNTER)) {
+			return -1;
+		}
+
+		/* Acknowledge the Master Transaction Done Without Stop */
+		i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
+	}
+
+	/* Master control configuration for read operation  */
+	mcr |= I2C_MCR_OP;
+
+	/* Configure the STOP condition, we read only one byte */
+	mcr |= I2C_MCR_STOP;
+
+	/* Set the frame length to one byte, we support only 1 byte reads */
+	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);
+
+	i2c_write_field(&i2c_regs->mcr, I2C_MCR_LENGTH_STOP_OP,
+			I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
+
+	/*
+	 * receive_data_polling
+	 */
+
+	/* Wait until the Rx FIFO is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr, I2C_INT_RXFE,
+			I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Read the data byte from Rx FIFO */
+	*value = readb(&i2c_regs->rfr);
+
+	/* Wait until the work is done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
+				I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);
+
+	/* If MTD is set, Master Transaction Done Without Stop is set too */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Internal simplified write function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   data:	Where to read the data
+ *   len:	How many bytes to write
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
+		int alen, u8 *data, int len)
+{
+	int i;
+	u32 mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, I2C_MCR_A7, I2C_MCR_SHIFT_A7, chip);
+
+	/* Write operation */
+	mcr &= ~(I2C_MCR_OP);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= I2C_MCR_STOP;
+
+	/* Frame length: addr byte + len */
+	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, (alen + len));
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+		return -1;
+
+	for (i = 0; i < len; i++) {
+		/* Wait until the Tx FIFO is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					I2C_INT_TXFF, I2C_ENDAD_COUNTER))
+			return -1;
+
+		/* it is a 32 bit register with upper 24 reserved R/O */
+		writeb(data[i], &i2c_regs->tfr);
+	}
+
+	/* Check for Master Transaction Done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr, I2C_INT_MTD,
+				I2C_ENDAD_COUNTER)) {
+		printf("i2c_write_byte error2: risr %08x\n",
+				i2c_regs->risr);
+		return -1;
+	}
+
+	/* Acknowledge Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);
+
+	/* Acknowledge Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Probe the given I2C chip address. Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(uchar chip)
+{
+	u32 mcr = 0;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (chip == CONFIG_SYS_I2C_SLAVE)
+		return 1;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, I2C_MCR_AM, I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, I2C_MCR_A10, I2C_MCR_SHIFT_A7, chip);
+
+	/* Read operation */
+	mcr |= I2C_MCR_OP;
+
+	/* Set the frame length to one byte */
+	WRITE_FIELD(mcr, I2C_MCR_LENGTH, I2C_MCR_SHIFT_LENGTH, 1);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= I2C_MCR_STOP;
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	/* Wait until the Rx Fifo is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr, I2C_INT_RXFE,
+			I2C_ENDAD_COUNTER)) {
+		i2c_abort(i2c_regs);
+		return -1;
+	}
+
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Read/Write interface:
+ *   chip:    I2C chip address, range 0..127
+ *   addr:    Memory (register) address within the chip
+ *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:  Where to read/write the data
+ *   len:     How many bytes to read/write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int i;
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (alen > 2) {
+		debug("I2C read: addr len %d not supported\n", alen);
+		return 1;
+	}
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	for (i = 0; i < len; i++) {
+		rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
+		if (rc != 0) {
+			debug("I2C read: I/O error: %d\n", rc);
+			i2c_abort(i2c_regs);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
+			len);
+	if (rc != 0) {
+		debug("I2C write: I/O error\n");
+		i2c_abort(i2c_regs);
+		return rc;
+	}
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if (bus > ARRAY_SIZE(i2c_dev) - 1) {
+		debug("i2c_set_bus_num: only up to bus %d supported\n",
+				ARRAY_SIZE(i2c_dev)-1);
+		return -1;
+	}
+
+	i2c_bus_num = bus;
+
+	if (!bus_initialized[i2c_bus_num])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+
+	if (speed > I2C_MAX_STANDARD_SCL) {
+		debug("i2c_set_bus_speed: only up to %d supported\n",
+				I2C_MAX_STANDARD_SCL);
+		return -1;
+	}
+
+	/* sets as side effect i2c_bus_speed[i2c_bus_num] */
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return i2c_bus_num;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+	return i2c_bus_speed[i2c_bus_num];
+}
diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
new file mode 100644
index 0000000..8ef6667
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _U8500_I2C_H_
+#define _U8500_I2C_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+//#include "common.h"
+#include <asm/arch/u8500.h>
+
+/* Generic macros */
+
+#define I2C_WRITE_FIELD(reg_name, mask, shift, value) \
+		(reg_name = ((reg_name & ~mask) | (value << shift)))
+#define I2C_READ_FIELD(reg_name, mask, shift)    ((reg_name & mask) >> shift)
+
+struct u8500_i2c_regs {
+	u32 cr;			/* Control Register                      0x00 */
+	u32 scr;		/* Slave Address Register                0x04 */
+	u32 hsmcr;		/* HS Master code Register               0x08 */
+	u32 mcr;		/* Master Control Register               0x0C */
+	u32 tfr;		/* Transmit Fifo Register                0x10 */
+	u32 sr;			/* Status Register                       0x14 */
+	u32 rfr;		/* Receiver Fifo Register                0x18 */
+	u32 tftr;		/* Transmit Fifo Threshold Register      0x1C */
+	u32 rftr;		/* Receiver Fifo Threshold Register      0x20 */
+	u32 dmar;		/* DMA register                          0x24 */
+	u32 brcr;		/* Baud Rate Counter Register            0x28 */
+	u32 imscr;		/* Interrupt Mask Set and Clear Register 0x2C */
+	u32 risr;		/* Raw interrupt status register         0x30 */
+	u32 misr;		/* Masked interrupt status register      0x34 */
+	u32 icr;		/* Interrupt Set and Clear Register      0x38 */
+	u32 reserved_1[(0xFE0 - 0x3c) >> 2];	/* Reserved 0x03C to 0xFE0 */
+	u32 periph_id_0;	/* peripheral ID 0	0xFE0 */
+	u32 periph_id_1;	/* peripheral ID 1	0xFE4 */
+	u32 periph_id_2;	/* peripheral ID 2	0xFE8 */
+	u32 periph_id_3;	/* peripheral ID 3	0xFEC */
+	u32 cell_id_0;		/* I2C cell   ID 0	0xFF0 */
+	u32 cell_id_1;		/* I2C cell   ID 1	0xFF4 */
+	u32 cell_id_2;		/* I2C cell   ID 2	0xFF8 */
+	u32 cell_id_3;		/* I2C cell   ID 3	0xFFC */
+};
+
+
+/* Control Register */
+
+/* Mask values for control register mask */
+#define I2C_CR_PE          MASK_BIT0	/* Peripheral enable */
+#define I2C_CR_OM          0x6		/* Operation mode */
+#define I2C_CR_SAM         MASK_BIT3	/* Slave Addressing mode */
+#define I2C_CR_SM          0x30		/* Speed mode */
+#define I2C_CR_SGCM        MASK_BIT6	/* Slave General call mode */
+#define I2C_CR_FTX         MASK_BIT7	/* Flush Transmit */
+#define I2C_CR_FRX         MASK_BIT8	/* Flush Receive */
+#define I2C_CR_DMA_TX_EN   MASK_BIT9	/* DMA TX Enable */
+#define I2C_CR_DMA_RX_EN   MASK_BIT10	/* DMA Rx Enable */
+#define I2C_CR_DMA_SLE     MASK_BIT11	/* DMA Synchronization Logic enable */
+#define I2C_CR_LM          MASK_BIT12	/* Loop back mode */
+#define I2C_CR_FON         0x6000	/* Filtering On */
+
+/* shift valus for control register bit fields */
+#define I2C_CR_SHIFT_PE		0	/* Peripheral enable */
+#define I2C_CR_SHIFT_OM		1	/* Operation mode */
+#define I2C_CR_SHIFT_SAM	3	/* Slave Addressing mode */
+#define I2C_CR_SHIFT_SM		4	/* Speed mode */
+#define I2C_CR_SHIFT_SGCM	6	/* Slave General call mode */
+#define I2C_CR_SHIFT_FTX	7	/* Flush Transmit */
+#define I2C_CR_SHIFT_FRX	8	/* Flush Receive */
+#define I2C_CR_SHIFT_DMA_TX_EN	9	/* DMA TX Enable */
+#define I2C_CR_SHIFT_DMA_RX_EN	10	/* DMA Rx Enable */
+#define I2C_CR_SHIFT_DMA_SLE	11	/* DMA Synch Logic enable */
+#define I2C_CR_SHIFT_LM		12	/* Loop back mode */
+#define I2C_CR_SHIFT_FON	13	/* Filtering On */
+
+/* bus operation modes */
+#define I2C_BUS_SLAVE_MODE		0
+#define I2C_BUS_MASTER_MODE		1
+#define I2C_BUS_MASTER_SLAVE_MODE	2
+
+
+/* Slave control register*/
+
+/* Mask values slave control register */
+#define I2C_SCR_ADDR                   0x3FF
+#define I2C_SCR_DATA_SETUP_TIME        0xFFFF0000
+
+/* Shift values for Slave control register */
+#define I2C_SCR_SHIFT_ADDR               0
+#define I2C_SCR_SHIFT_DATA_SETUP_TIME    16
+
+
+/* Master Control Register */
+
+/* Mask values for Master control register */
+#define I2C_MCR_OP	MASK_BIT0	/* Operation */
+#define I2C_MCR_A7	0xFE		/* LSB bits of the Address(7-bit ) */
+#define I2C_MCR_EA10	0x700		/* Extended Address */
+#define I2C_MCR_SB	MASK_BIT11	/* Start byte procedure */
+#define I2C_MCR_AM	0x3000		/* Address type */
+#define I2C_MCR_STOP	MASK_BIT14	/* stop condition */
+#define I2C_MCR_LENGTH	0x3FF8000	/* Frame length */
+#define I2C_MCR_A10	0x7FE		/* Define to set the 10 bit address */
+/* mask for length field,stop and operation  */
+#define I2C_MCR_LENGTH_STOP_OP	0x3FFC001
+
+/* Shift values for Master control values */
+#define I2C_MCR_SHIFT_OP	0	/* Operation */
+#define I2C_MCR_SHIFT_A7	1	/* LSB bits of the Address(7-bit ) */
+#define I2C_MCR_SHIFT_EA10	8	/* Extended Address */
+#define I2C_MCR_SHIFT_SB	11	/* Start byte procedure */
+#define I2C_MCR_SHIFT_AM	12	/* Address type */
+#define I2C_MCR_SHIFT_STOP	14	/* stop condition */
+#define I2C_MCR_SHIFT_LENGTH	15	/* Frame length */
+#define I2C_MCR_SHIFT_A10	1	/* define to set the 10 bit addres */
+
+#define I2C_MCR_SHIFT_LENGTH_STOP_OP	0
+
+
+/* Status Register */
+
+/* Mask values for Status register */
+#define I2C_SR_OP		0x3	/* Operation */
+#define I2C_SR_STATUS		0xC	/* Controller Status */
+#define I2C_SR_CAUSE		0x70	/* Abort Cause */
+#define I2C_SR_TYPE		0x180	/* Receive Type */
+#define I2C_SR_LENGTH		0xFF700	/* Transfer length */
+
+/* Shift values for Status register */
+#define I2C_SR_SHIFT_OP		0	/* Operation */
+#define I2C_SR_SHIFT_STATUS	2	/* Controller Status */
+#define I2C_SR_SHIFT_CAUSE	4	/* Abort Cause */
+#define I2C_SR_SHIFT_TYPE	7	/* Receive Type */
+#define I2C_SR_SHIFT_LENGTH	9	/* Transfer length */
+
+/* abort cause */
+#define	I2C_NACK_ADDR	0
+#define	I2C_NACK_DATA	1
+#define	I2C_ACK_MCODE	2
+#define	I2C_ARB_LOST	3
+#define	I2C_BERR_START	4
+#define	I2C_BERR_STOP	5
+#define	I2C_OVFL	6
+
+
+/* Baud rate counter registers */
+
+/* Mask values for Baud rate counter register */
+#define I2C_BRCR_BRCNT2	0xFFFF		/* Baud Rate Counter for HS mode */
+#define I2C_BRCR_BRCNT1	0xFFFF0000	/* counter for Standard and Fast mode */
+
+/* Shift values for the Baud rate counter register */
+#define I2C_BRCR_SHIFT_BRCNT2	0
+#define I2C_BRCR_SHIFT_BRCNT1	16
+
+
+/* Interrupt Register  */
+
+/* Mask values for Interrupt registers */
+#define I2C_INT_TXFE	MASK_BIT0	/* Tx fifo empty */
+#define I2C_INT_TXFNE	MASK_BIT1	/* Tx Fifo nearly empty */
+#define I2C_INT_TXFF	MASK_BIT2	/* Tx Fifo Full */
+#define I2C_INT_TXFOVR	MASK_BIT3	/* Tx Fifo over run */
+#define I2C_INT_RXFE	MASK_BIT4	/* Rx Fifo Empty */
+#define I2C_INT_RXFNF	MASK_BIT5	/* Rx Fifo nearly empty */
+#define I2C_INT_RXFF	MASK_BIT6	/* Rx Fifo Full  */
+#define I2C_INT_RFSR	MASK_BIT16	/* Read From slave request */
+#define I2C_INT_RFSE	MASK_BIT17	/* Read from slave empty */
+#define I2C_INT_WTSR	MASK_BIT18	/* Write to Slave request */
+#define I2C_INT_MTD	MASK_BIT19	/* Master Transcation Done*/
+#define I2C_INT_STD	MASK_BIT20	/* Slave Transaction Done */
+#define I2C_INT_MAL	MASK_BIT24	/* Master Arbitation Lost */
+#define I2C_INT_BERR	MASK_BIT25	/* Bus Error */
+#define I2C_INT_MTDWS	MASK_BIT28	/* Master Transaction Done wo/ Stop */
+
+/* Shift values for Interrupt registers */
+#define I2C_INT_SHIFT_TXFE	0	/* Tx fifo empty */
+#define I2C_INT_SHIFT_TXFNE	1	/* Tx Fifo nearly empty */
+#define I2C_INT_SHIFT_TXFF	2	/* Tx Fifo Full */
+#define I2C_INT_SHIFT_TXFOVR	3	/* Tx Fifo over run */
+#define I2C_INT_SHIFT_RXFE	4	/* Rx Fifo Empty */
+#define I2C_INT_SHIFT_RXFNF	5	/* Rx Fifo nearly empty */
+#define I2C_INT_SHIFT_RXFF	6	/* Rx Fifo Full  */
+#define I2C_INT_SHIFT_RFSR	16	/* Read From slave request */
+#define I2C_INT_SHIFT_RFSE	17	/* Read from slave empty */
+#define I2C_INT_SHIFT_WTSR	18	/* Write to Slave request */
+#define I2C_INT_SHIFT_MTD	19	/* Master Transcation Done */
+#define I2C_INT_SHIFT_STD	20	/* Slave Transaction Done */
+#define I2C_INT_SHIFT_MAL	24	/* Master Arbitation Lost */
+#define I2C_INT_SHIFT_BERR	25	/* Bus Error */
+#define I2C_INT_SHIFT_MTDWS	28	/* Master Transcation Done wo/ Stop */
+
+
+/* Misc defines */
+#define I2C_MAX_STANDARD_SCL	100000	/* Max clock (Hz) for Standard Mode */
+#define I2C_MAX_FAST_SCL	400000	/* Max clock (Hz) for Fast Mode */
+#define I2C_MAX_HIGH_SPEED_SCL	3400000	/* Max clock (Hz) for HS Mode */
+
+#endif	/* _U8500_I2C_H_ */
-- 
1.7.1

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

* [U-Boot] [PATCH 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (2 preceding siblings ...)
  2011-03-22 20:40 ` [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
@ 2011-03-22 20:40 ` John Rigby
  2011-03-22 20:46 ` [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:40 UTC (permalink / raw)
  To: u-boot

Based on ST-Ericsson private git repo.
Plus changes to use arm_pl180_mmci driver.

Signed-off-by: John Rigby <john.rigby@linaro.org>
---
 board/st-ericsson/u8500/Makefile           |   50 +++
 board/st-ericsson/u8500/gpio.c             |  346 +++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw-defs_v1.h |  578 ++++++++++++++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h         |  182 +++++++++
 board/st-ericsson/u8500/prcmu.c            |  167 ++++++++
 board/st-ericsson/u8500/u8500_href.c       |  540 ++++++++++++++++++++++++++
 boards.cfg                                 |    1 +
 include/configs/u8500_href.h               |  243 ++++++++++++
 8 files changed, 2107 insertions(+), 0 deletions(-)
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw-defs_v1.h
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 include/configs/u8500_href.h

diff --git a/board/st-ericsson/u8500/Makefile b/board/st-ericsson/u8500/Makefile
new file mode 100644
index 0000000..91c2abf
--- /dev/null
+++ b/board/st-ericsson/u8500/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= u8500_href.o gpio.o prcmu.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/st-ericsson/u8500/gpio.c b/board/st-ericsson/u8500/gpio.c
new file mode 100644
index 0000000..ad49e0f
--- /dev/null
+++ b/board/st-ericsson/u8500/gpio.c
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+	(void *)U8500_GPIO_0_BASE,
+	(void *)U8500_GPIO_1_BASE,
+	(void *)U8500_GPIO_2_BASE,
+	(void *)U8500_GPIO_3_BASE,
+	(void *)U8500_GPIO_4_BASE,
+	(void *)U8500_GPIO_5_BASE,
+	(void *)U8500_GPIO_6_BASE,
+	(void *)U8500_GPIO_7_BASE,
+	(void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+	{
+		.altfun = GPIO_ALT_I2C_0,
+		.start = 147,
+		.end = 148,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_1,
+		.start = 16,
+		.end = 17,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_2,
+		.start = 10,
+		.end = 11,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_3,
+		.start = 229,
+		.end = 230,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 0,
+		.end = 3,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_1,
+		.start = 4,
+		.end = 7,
+		.cont = 0,
+		.type =
+			GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 18,
+		.end = 19,
+		.cont = 1,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 29,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 12,
+		.end = 17,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 21,
+		.end = 21,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_1,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_2,
+		.start = 192,
+		.end = 196,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 64,
+		.end = 93,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 150,
+		.end = 171,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_SD_CARD0,
+		.start = 18,
+		.end = 28,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MM_CARD0,
+		.start = 18,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_USB_OTG,
+		.start = 256,
+		.end = 267,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_EMMC,
+		.start = 197,
+		.end = 207,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_POP_EMMC,
+		.start = 128,
+		.end = 138,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	switch (config->mode) {
+	case GPIO_ALTF_A:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_B:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_C:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_MODE_SOFTWARE:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+		switch (config->direction) {
+		case GPIO_DIR_INPUT:
+			writel(mask, &p_gpio_register->gpio_dirc);
+			break;
+		case GPIO_DIR_OUTPUT:
+			writel(mask, &p_gpio_register->gpio_dirs);
+			break;
+		case GPIO_DIR_LEAVE_UNCHANGED:
+			break;
+		default:
+			return GPIO_INVALID_PARAMETER;
+		}
+
+		break;
+	case GPIO_MODE_LEAVE_UNCHANGED:
+		break;
+	default:
+		return GPIO_INVALID_PARAMETER;
+	}
+	return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	temp_reg = readl(&p_gpio_register->gpio_afsa);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsa);
+	temp_reg = readl(&p_gpio_register->gpio_afsb);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsb);
+	writel(mask, &p_gpio_register->gpio_dirc);
+
+	return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+			    int which_altfunc, char *dev_name)
+{
+	int i, j, start, end;
+	enum gpio_error error = -1;
+
+	for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+		if (altfun_table[i].altfun != alt_func)
+			continue;
+
+		start = altfun_table[i].start;
+		end = altfun_table[i].end;
+		for (j = start; j <= end; j++) {
+			if (which_altfunc == GPIO_ALTF_FIND)
+				altfun_pinconfig.mode = altfun_table[i].type;
+			else
+				altfun_pinconfig.mode = which_altfunc;
+			altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+			altfun_pinconfig.dev_name = dev_name;
+
+			if (which_altfunc != GPIO_ALTF_DISABLE)
+				error = gpio_setpinconfig(j, &altfun_pinconfig);
+			else
+				error = gpio_resetgpiopin(j, dev_name);
+			if (!error)
+				continue;
+			printf("GPIO %d configuration failure (nmdk_error:%d)",
+				j, error);
+			error = GPIO_INVALID_PARAMETER;
+			return error;
+		}
+
+		if (!altfun_table[i].cont)
+			break;
+	}
+	return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	switch (value) {
+	case GPIO_DATA_HIGH:
+		writel(mask, &p_gpio_register->gpio_dats);
+		break;
+	case GPIO_DATA_LOW:
+		writel(mask, &p_gpio_register->gpio_datc);
+		break;
+	default:
+		nmdk_error("Invalid value passed in %s", __FUNCTION__);
+		return GPIO_INVALID_PARAMETER;
+	}
+	return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+		*rv = GPIO_DATA_HIGH;
+	else
+		*rv = GPIO_DATA_LOW;
+	return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}
diff --git a/board/st-ericsson/u8500/prcmu-fw-defs_v1.h b/board/st-ericsson/u8500/prcmu-fw-defs_v1.h
new file mode 100644
index 0000000..bb0995b
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu-fw-defs_v1.h
@@ -0,0 +1,578 @@
+/*
+ * Copyright (c) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef __MACH_PRCMU_FW_DEFS_V1_H
+#define __MACH_PRCMU_FW_DEFS_V1_H
+
+/**
+ * enum state_t - ON/OFF state definition
+ * @OFF: State is ON
+ * @ON: State is OFF
+ *
+ */
+enum state_t {
+	OFF = 0x0,
+	ON  = 0x1,
+};
+
+/**
+ * enum ret_state_t - general purpose On/Off/Retention states
+ *
+ */
+enum ret_state_t {
+	OFFST = 0,
+	ONST  = 1,
+	RETST = 2
+};
+
+
+/**
+ * enum clk_arm_t - ARM Cortex A9 clock schemes
+ * @A9_OFF:
+ * @A9_BOOT:
+ * @A9_OPPT1:
+ * @A9_OPPT2:
+ * @A9_EXTCLK:
+ */
+enum clk_arm_t {
+	A9_OFF,
+	A9_BOOT,
+	A9_OPPT1,
+	A9_OPPT2,
+	A9_EXTCLK
+};
+
+/**
+ * enum clk_gen_t - GEN#0/GEN#1 clock schemes
+ * @GEN_OFF:
+ * @GEN_BOOT:
+ * @GEN_OPPT1:
+ */
+enum clk_gen_t {
+	GEN_OFF,
+	GEN_BOOT,
+	GEN_OPPT1,
+};
+
+/* some information between arm and xp70 */
+
+/**
+ * enum romcode_write_t - Romcode message written by A9 AND read by XP70
+ * @RDY_2_DS: Value set when ApDeepSleep state can be executed by XP70
+ * @RDY_2_XP70_RST: Value set when 0x0F has been successfully polled by the
+ *                 romcode. The xp70 will go into self-reset
+ */
+enum romcode_write_t {
+	RDY_2_DS = 0x09,
+	RDY_2_XP70_RST = 0x10
+};
+
+/**
+ * enum romcode_read_t - Romcode message written by XP70 and read by A9
+ * @INIT: Init value when romcode field is not used
+ * @FS_2_DS: Value set when power state is going from ApExecute to
+ *          ApDeepSleep
+ * @END_DS: Value set when ApDeepSleep power state is reached coming from
+ *         ApExecute state
+ * @DS_TO_FS: Value set when power state is going from ApDeepSleep to
+ *           ApExecute
+ * @END_FS: Value set when ApExecute power state is reached coming from
+ *         ApDeepSleep state
+ * @SWR: Value set when power state is going to ApReset
+ * @END_SWR: Value set when the xp70 finished executing ApReset actions and
+ *          waits for romcode acknowledgment to go to self-reset
+ */
+enum romcode_read_t {
+	INIT = 0x00,
+	FS_2_DS = 0x0A,
+	END_DS = 0x0B,
+	DS_TO_FS = 0x0C,
+	END_FS = 0x0D,
+	SWR = 0x0E,
+	END_SWR = 0x0F
+};
+
+/**
+ * enum wkup_reason_fdst_t
+ * @EVTWR: event has been read by ARM
+ * @EVTST: event has been sent by PRCMU FW
+ * @EVTRD: event has been written by PRCMU FW
+ */
+enum wkup_reason_fdst_t {
+	/* WRF has been written but neither sent nor read by the arm */
+	EVTWR = 1,
+	/* WRF has been written and sent, but not yet read by the arm */
+	EVTST = 2,
+	/* WRF has been written, sent and read by the arm */
+	EVTRD = 0
+}; /* Wake-up reason Field State */
+
+/**
+ * enum ap_pwrst_t - current power states defined in PRCMU firmware
+ * @NO_PWRST: Current power state init
+ * @AP_BOOT: Current power state is apBoot
+ * @AP_EXECUTE: Current power state is apExecute
+ * @AP_DEEP_SLEEP: Current power state is apDeepSleep
+ * @AP_SLEEP: Current power state is apSleep
+ * @AP_IDLE: Current power state is apIdle
+ * @AP_RESET: Current power state is apReset
+ */
+enum ap_pwrst_t {
+	NO_PWRST = 0x00,
+	AP_BOOT = 0x01,
+	AP_EXECUTE = 0x02,
+	AP_DEEP_SLEEP = 0x03,
+	AP_SLEEP = 0x04,
+	AP_IDLE = 0x05,
+	AP_RESET = 0x06
+};
+
+/**
+ * enum ap_pwrst_trans_t - Transition states defined in PRCMU firmware
+ * @NO_TRANSITION: No power state transition
+ * @APEXECUTE_TO_APSLEEP: Power state transition from ApExecute to ApSleep
+ * @APIDLE_TO_APSLEEP: Power state transition from ApIdle to ApSleep
+ * @APBOOT_TO_APEXECUTE: Power state transition from ApBoot to ApExecute
+ * @APEXECUTE_TO_APDEEPSLEEP: Power state transition from ApExecute to
+ *                          ApDeepSleep
+ * @APEXECUTE_TO_APIDLE: Power state transition from ApExecute to ApIdle
+ */
+enum ap_pwrst_trans_t {
+	NO_TRANSITION = 0x00,
+	APEXECUTE_TO_APSLEEP = 0x01,
+	APIDLE_TO_APSLEEP = 0x02,
+	APBOOT_TO_APEXECUTE = 0x03,
+	APEXECUTE_TO_APDEEPSLEEP = 0x04,
+	APEXECUTE_TO_APIDLE = 0x05
+};
+
+/**
+ * enum ddr_pwrst_t - DDR power states definition
+ * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
+ * @DDR_PWR_STATE_ON:
+ * @DDR_PWR_STATE_OFFLOWLAT:
+ * @DDR_PWR_STATE_OFFHIGHLAT:
+ */
+enum ddr_pwrst_t {
+	DDR_PWR_STATE_UNCHANGED     = 0x00,
+	DDR_PWR_STATE_ON            = 0x01,
+	DDR_PWR_STATE_OFFLOWLAT     = 0x02,
+	DDR_PWR_STATE_OFFHIGHLAT    = 0x03
+};
+
+/**
+ * enum arm_opp_t - ARM OPP states definition
+ * @ARM_NO_CHANGE: The ARM operating point is unchanged
+ * @ARM_100_OPP: The new ARM operating point is arm100opp
+ * @ARM_50_OPP: The new ARM operating point is arm100opp
+ * @ARM_EXTCLK: The new ARM operating point is armExtClk
+ */
+enum arm_opp_t {
+	ARM_NO_CHANGE = 0x00,
+	ARM_100_OPP = 0x02,
+	ARM_50_OPP = 0x03,
+	ARM_EXTCLK = 0x07
+};
+
+/**
+ * enum ape_opp_t - APE OPP states definition
+ * @APE_NO_CHANGE: The APE operating point is unchanged
+ * @APE_100_OPP: The new APE operating point is ape100opp
+ */
+enum ape_opp_t {
+	APE_NO_CHANGE = 0x00,
+	APE_100_OPP = 0x02,
+	APE_50_OPP = 0x03
+};
+
+/**
+ * enum hw_accst_t - State definition for hardware accelerator
+ * @HW_NO_CHANGE: The hardware accelerator state must remain unchanged
+ * @HW_OFF: The hardware accelerator must be switched off
+ * @HW_OFF_RAMRET: The hardware accelerator must be switched off with its
+ *               internal RAM in retention
+ * @HW_ON: The hwa hadware accelerator hwa must be switched on
+ */
+enum hw_accst_t {
+	HW_NO_CHANGE = 0x00,
+	HW_OFF = 0x01,
+	HW_OFF_RAMRET = 0x02,
+	HW_ON = 0x03
+};
+
+/**
+ * enum  mbox_2_arm_stat_t - Status messages definition for mbox_arm
+ * @BOOT_TO_EXECUTEOK: The apBoot to apExecute state transition has been
+ *                    completed
+ * @DEEPSLEEPOK: The apExecute to apDeepSleep state transition has been
+ *              completed
+ * @SLEEPOK: The apExecute to apSleep state transition has been completed
+ * @IDLEOK: The apExecute to apIdle state transition has been completed
+ * @SOFTRESETOK: The A9 watchdog/ SoftReset state has been completed
+ * @SOFTRESETGO : The A9 watchdog/SoftReset state is on going
+ * @BOOT_TO_EXECUTE: The apBoot to apExecute state transition is on going
+ * @EXECUTE_TO_DEEPSLEEP: The apExecute to apDeepSleep state transition is on
+ *                       going
+ * @DEEPSLEEP_TO_EXECUTE: The apDeepSleep to apExecute state transition is on
+ *                       going
+ * @DEEPSLEEP_TO_EXECUTEOK: The apDeepSleep to apExecute state transition has
+ *                         been completed
+ * @EXECUTE_TO_SLEEP: The apExecute to apSleep state transition is on going
+ * @SLEEP_TO_EXECUTE: The apSleep to apExecute state transition is on going
+ * @SLEEP_TO_EXECUTEOK: The apSleep to apExecute state transition has been
+ *                     completed
+ * @EXECUTE_TO_IDLE: The apExecute to apIdle state transition is on going
+ * @IDLE_TO_EXECUTE: The apIdle to apExecute state transition is on going
+ * @IDLE_TO_EXECUTEOK: The apIdle to apExecute state transition has been
+ *                    completed
+ * @INIT_STATUS: Status init
+ */
+enum ap_pwrsttr_status_t {
+	BOOT_TO_EXECUTEOK = 0xFF,
+	DEEPSLEEPOK = 0xFE,
+	SLEEPOK = 0xFD,
+	IDLEOK = 0xFC,
+	SOFTRESETOK = 0xFB,
+	SOFTRESETGO = 0xFA,
+	BOOT_TO_EXECUTE = 0xF9,
+	EXECUTE_TO_DEEPSLEEP = 0xF8,
+	DEEPSLEEP_TO_EXECUTE = 0xF7,
+	DEEPSLEEP_TO_EXECUTEOK = 0xF6,
+	EXECUTE_TO_SLEEP = 0xF5,
+	SLEEP_TO_EXECUTE = 0xF4,
+	SLEEP_TO_EXECUTEOK = 0xF3,
+	EXECUTE_TO_IDLE = 0xF2,
+	IDLE_TO_EXECUTE = 0xF1,
+	IDLE_TO_EXECUTEOK = 0xF0,
+	RDYTODS_RETURNTOEXE    = 0xEF,
+	NORDYTODS_RETURNTOEXE  = 0xEE,
+	EXETOSLEEP_RETURNTOEXE = 0xED,
+	EXETOIDLE_RETURNTOEXE  = 0xEC,
+	INIT_STATUS = 0xEB,
+
+	/*error messages */
+	INITERROR                     = 0x00,
+	PLLARMLOCKP_ER                = 0x01,
+	PLLDDRLOCKP_ER                = 0x02,
+	PLLSOCLOCKP_ER                = 0x03,
+	PLLSOCK1LOCKP_ER              = 0x04,
+	ARMWFI_ER                     = 0x05,
+	SYSCLKOK_ER                   = 0x06,
+	I2C_NACK_DATA_ER              = 0x07,
+	BOOT_ER                       = 0x08,
+	I2C_STATUS_ALWAYS_1           = 0x0A,
+	I2C_NACK_REG_ADDR_ER          = 0x0B,
+	I2C_NACK_DATA0123_ER          = 0x1B,
+	I2C_NACK_ADDR_ER              = 0x1F,
+	CURAPPWRSTISNOT_BOOT          = 0x20,
+	CURAPPWRSTISNOT_EXECUTE       = 0x21,
+	CURAPPWRSTISNOT_SLEEPMODE     = 0x22,
+	CURAPPWRSTISNOT_CORRECTFORIT10 = 0x23,
+	FIFO4500WUISNOT_WUPEVENT      = 0x24,
+	PLL32KLOCKP_ER                = 0x29,
+	DDRDEEPSLEEPOK_ER             = 0x2A,
+	ROMCODEREADY_ER               = 0x50,
+	WUPBEFOREDS                   = 0x51,
+	DDRCONFIG_ER                  = 0x52,
+	WUPBEFORESLEEP                = 0x53,
+	WUPBEFOREIDLE                 = 0x54
+};  /* earlier called as  mbox_2_arm_stat_t */
+
+
+/**
+ * enum dvfs_stat_t - DVFS status messages definition
+ * @DVFS_GO: A state transition DVFS is on going
+ * @DVFS_ARM100OPPOK: The state transition DVFS has been completed for 100OPP
+ * @DVFS_ARM50OPPOK: The state transition DVFS has been completed for 50OPP
+ * @DVFS_ARMEXTCLKOK: The state transition DVFS has been completed for EXTCLK
+ * @DVFS_NOCHGTCLKOK: The state transition DVFS has been completed for
+ *                   NOCHGCLK
+ * @DVFS_INITSTATUS: Value init
+ */
+enum dvfs_stat_t {
+	DVFS_GO = 0xFF,
+	DVFS_ARM100OPPOK = 0xFE,
+	DVFS_ARM50OPPOK = 0xFD,
+	DVFS_ARMEXTCLKOK = 0xFC,
+	DVFS_NOCHGTCLKOK = 0xFB,
+	DVFS_INITSTATUS = 0x00
+};
+
+/**
+ * enum mbox_2_arm_hwacc_pwr_stat_t - Hardware Accelarator status message
+ * @HWACC_PWRST_GO: A state transition on hardware accelerator is on going
+ * @HWACC_PWRST_OK: The state transition on hardware accelerator has been
+ *                 completed
+ * @HWACC_PWRSTATUS_INIT: Value init
+ */
+enum mbox_2_arm_hwacc_pwr_stat_t {
+	HWACC_PWRST_GO = 0xFF,
+	HWACC_PWRST_OK = 0xFE,
+	HWACC_PWRSTATUS_INIT = 0x00
+};
+
+/**
+ * enum sva_mmdsp_stat_t - SVA MMDSP status messages
+ * @SVA_MMDSP_GO: SVAMMDSP interrupt has happened
+ * @SVA_MMDSP_INIT: Status init
+ */
+enum sva_mmdsp_stat_t {
+	SVA_MMDSP_GO = 0xFF,
+	SVA_MMDSP_INIT = 0x00
+};
+
+/**
+ * enum sia_mmdsp_stat_t - SIA MMDSP status messages
+ * @SIA_MMDSP_GO: SIAMMDSP interrupt has happened
+ * @SIA_MMDSP_INIT: Status init
+ */
+enum sia_mmdsp_stat_t {
+	SIA_MMDSP_GO = 0xFF,
+	SIA_MMDSP_INIT = 0x00
+};
+
+/**
+ * enum intr_wakeup_t - Configure STW4500 FIFO interrupt as wake-up
+ * @NTR_NOT_AS_WAKEUP: The 4500 fifo interrupt is not configured as a
+ *                     wake-up event
+ * @INTR_AS_WAKEUP: The 4500 fifo interrupt is configured as a wake-up event
+ */
+enum intr_wakeup_t {
+	INTR_NOT_AS_WAKEUP = 0x0,
+	INTR_AS_WAKEUP = 0x1
+};
+
+/**
+ * enum  mbox_to_arm_err_t - Error messages definition
+ * @INIT_ERR: Init value
+ * @PLLARMLOCKP_ERR: PLLARM has not been correctly locked in given time
+ * @PLLDDRLOCKP_ERR: PLLDDR has not been correctly locked in the given time
+ * @PLLSOC0LOCKP_ERR: PLLSOC0 has not been correctly locked in the given time
+ * @PLLSOC1LOCKP_ERR: PLLSOC1 has not been correctly locked in the given time
+ * @ARMWFI_ERR: The ARM WFI has not been correctly executed in the given time
+ * @SYSCLKOK_ERR: The SYSCLK is not available in the given time
+ * @BOOT_ERR: Romcode has not validated the XP70 self reset in the given time
+ * @ROMCODESAVECONTEXT: The Romcode didn.t correctly save it secure context
+ * @VARMHIGHSPEEDVALTO_ERR: The ARM high speed supply value transfered
+ *          through I2C has not been correctly executed in the given time
+ * @VARMHIGHSPEEDACCESS_ERR: The command value of VarmHighSpeedVal transfered
+ *             through I2C has not been correctly executed in the given time
+ * @VARMLOWSPEEDVALTO_ERR:The ARM low speed supply value transfered through
+ *                     I2C has not been correctly executed in the given time
+ * @VARMLOWSPEEDACCESS_ERR: The command value of VarmLowSpeedVal transfered
+ *             through I2C has not been correctly executed in the given time
+ * @VARMRETENTIONVALTO_ERR: The ARM retention supply value transfered through
+ *                     I2C has not been correctly executed in the given time
+ * @VARMRETENTIONACCESS_ERR: The command value of VarmRetentionVal transfered
+ *             through I2C has not been correctly executed in the given time
+ * @VAPEHIGHSPEEDVALTO_ERR: The APE highspeed supply value transfered through
+ *                     I2C has not been correctly executed in the given time
+ * @VSAFEHPVALTO_ERR: The SAFE high power supply value transfered through I2C
+ *                         has not been correctly executed in the given time
+ * @VMODSEL1VALTO_ERR: The MODEM sel1 supply value transfered through I2C has
+ *                             not been correctly executed in the given time
+ * @VMODSEL2VALTO_ERR: The MODEM sel2 supply value transfered through I2C has
+ *                             not been correctly executed in the given time
+ * @VARMOFFACCESS_ERR: The command value of Varm ON/OFF transfered through
+ *                     I2C has not been correctly executed in the given time
+ * @VAPEOFFACCESS_ERR: The command value of Vape ON/OFF transfered through
+ *                     I2C has not been correctly executed in the given time
+ * @VARMRETACCES_ERR: The command value of Varm retention ON/OFF transfered
+ *             through I2C has not been correctly executed in the given time
+ * @CURAPPWRSTISNOTBOOT:Generated when Arm want to do power state transition
+ *             ApBoot to ApExecute but the power current state is not Apboot
+ * @CURAPPWRSTISNOTEXECUTE: Generated when Arm want to do power state
+ *              transition from ApExecute to others power state but the
+ *              power current state is not ApExecute
+ * @CURAPPWRSTISNOTSLEEPMODE: Generated when wake up events are transmitted
+ *             but the power current state is not ApDeepSleep/ApSleep/ApIdle
+ * @CURAPPWRSTISNOTCORRECTDBG:  Generated when wake up events are transmitted
+ *              but the power current state is not correct
+ * @ARMREGU1VALTO_ERR:The ArmRegu1 value transferred through I2C has not
+ *                    been correctly executed in the given time
+ * @ARMREGU2VALTO_ERR: The ArmRegu2 value transferred through I2C has not
+ *                    been correctly executed in the given time
+ * @VAPEREGUVALTO_ERR: The VApeRegu value transfered through I2C has not
+ *                    been correctly executed in the given time
+ * @VSMPS3REGUVALTO_ERR: The VSmps3Regu value transfered through I2C has not
+ *                      been correctly executed in the given time
+ * @VMODREGUVALTO_ERR: The VModemRegu value transfered through I2C has not
+ *                    been correctly executed in the given time
+ */
+enum mbox_to_arm_err_t {
+	INIT_ERR = 0x00,
+	PLLARMLOCKP_ERR = 0x01,
+	PLLDDRLOCKP_ERR = 0x02,
+	PLLSOC0LOCKP_ERR = 0x03,
+	PLLSOC1LOCKP_ERR = 0x04,
+	ARMWFI_ERR = 0x05,
+	SYSCLKOK_ERR = 0x06,
+	BOOT_ERR = 0x07,
+	ROMCODESAVECONTEXT = 0x08,
+	VARMHIGHSPEEDVALTO_ERR = 0x10,
+	VARMHIGHSPEEDACCESS_ERR = 0x11,
+	VARMLOWSPEEDVALTO_ERR = 0x12,
+	VARMLOWSPEEDACCESS_ERR = 0x13,
+	VARMRETENTIONVALTO_ERR = 0x14,
+	VARMRETENTIONACCESS_ERR = 0x15,
+	VAPEHIGHSPEEDVALTO_ERR = 0x16,
+	VSAFEHPVALTO_ERR = 0x17,
+	VMODSEL1VALTO_ERR = 0x18,
+	VMODSEL2VALTO_ERR = 0x19,
+	VARMOFFACCESS_ERR = 0x1A,
+	VAPEOFFACCESS_ERR = 0x1B,
+	VARMRETACCES_ERR = 0x1C,
+	CURAPPWRSTISNOTBOOT = 0x20,
+	CURAPPWRSTISNOTEXECUTE = 0x21,
+	CURAPPWRSTISNOTSLEEPMODE = 0x22,
+	CURAPPWRSTISNOTCORRECTDBG = 0x23,
+	ARMREGU1VALTO_ERR = 0x24,
+	ARMREGU2VALTO_ERR = 0x25,
+	VAPEREGUVALTO_ERR = 0x26,
+	VSMPS3REGUVALTO_ERR = 0x27,
+	VMODREGUVALTO_ERR = 0x28
+};
+
+enum hw_acc_t {
+	SVAMMDSP = 0,
+	SVAPIPE = 1,
+	SIAMMDSP = 2,
+	SIAPIPE = 3,
+	SGA = 4,
+	B2R2MCDE = 5,
+	ESRAM1 = 6,
+	ESRAM2 = 7,
+	ESRAM3 = 8,
+	ESRAM4 = 9
+};
+
+enum reqmb0_header_t {
+	PWRSTTRH	 = 0,
+	WKUPCFG_EXEH	 = 1,
+	WKUP_EXEH	 = 2,
+	RDWKUPACKH	 = 3,
+	WKUPCFG_SLEEPH	 = 4,
+	WKUP_SLEEPH	 = 5,
+};
+
+enum cs_pwrmgt_t {
+	PWRDNCS0  = 0,
+	WKUPCS0   = 1,
+	PWRDNCS1  = 2,
+	WKUPCS1   = 3
+};
+
+enum reqmb2_header_t {
+	DPS_H   = 0,
+	HW_ACCT_AUTO_PWR_H = 1,
+};
+
+
+/* Defs related to autonomous power management */
+
+/**
+ * enum sia_sva_pwr_policy_t - Power policy
+ * @NO_CHGT:	No change
+ * @DSPOFF_HWPOFF:
+ * @DSPOFFRAMRET_HWPOFF:
+ * @DSPCLKOFF_HWPOFF:
+ * @DSPCLKOFF_HWPCLKOFF:
+ *
+ */
+enum sia_sva_pwr_policy_t {
+	NO_CHGT			= 0x0,
+	DSPOFF_HWPOFF		= 0x1,
+	DSPOFFRAMRET_HWPOFF	= 0x2,
+	DSPCLKOFF_HWPOFF	= 0x3,
+	DSPCLKOFF_HWPCLKOFF	= 0x4,
+};
+
+/**
+ * enum auto_enable_t - Auto Power enable
+ * @AUTO_OFF:
+ * @AUTO_ON:
+ *
+ */
+enum auto_enable_t {
+	AUTO_OFF	= 0x0,
+	AUTO_ON		= 0x1,
+};
+
+
+/**
+ * enum reqmb4_header_t -Header type for mail box 4
+ * @MEMSTH:   The ARM can set what are the expected memory states depending on
+ * the AP power states.
+ * @PARTIALREFRESHH: ARM has to update MR16 & MR17 of SDRAM register, for
+ * partial-refresh of SDRAM, via this mailbox
+ * @AUTOREFRESHH:  Enable to change cycle count before enabling automatic
+ * DDR self-refresh
+ * @CSPWRDNH:  Enables to lock/unlock one of SDRAM memory cut in self-refresh
+ * In V2,this service will enable to put CS in pwrdn
+ * @SYSCLKH:  Enables to switch SYSCLK ON/OFF on the AP side
+ * @USBWKUPH:  Used to enable USB wakeup event of PRCMU
+ */
+enum reqmb4_header_t {
+	MEM_ST_H = 0,
+	PARTIAL_S_REFRESH_H = 1,
+	AUTO_REFRESH_H = 2,
+	CS_PWRDN_H = 3,
+	SYSCLK_H = 5,
+	AUTO_PWR_H = 6,
+	USB_WKUP_H = 7
+};
+
+enum ack_mb4_status_t {
+	ACKMB4_INIT  = 0,
+	SYSCLKON_OK = 1,
+	DDRON_OK    = 2
+};
+
+enum I2C_op_t {
+	I2CWRITE = 0,
+	I2CREAD  = 1
+};
+
+enum ack_mb5_status_t {
+	ACKMB5_INIT  = 0x00,
+	I2C_WR_OK   = 0x01,
+	I2C_RD_OK   = 0x02,
+	SYSCLK_OK   = 0x03,
+	I2C_TIMEOUT = 0x11,
+	SYSCLK_ER   = 0x12,
+	/*Error Status resent by PRCM_HWI2C_SR*/
+	I2CWR_NACK_DATA_ER		= 0x07,
+	I2CWR_NACK_REG_ADDR_ER		= 0x0B,
+	I2CRDWR_NACK_DATA0123_ER	= 0x1B,
+	I2CWR_NACK_ADDR_ER		= 0x1F,
+	I2CRD_NACK_ADDR_INIT_ER		= 0x0F,
+	I2CRD_NACK_REG_ADDR_INIT_ER	= 0x13,
+	I2CRD_NACK_ADDR_ER		= 0x17
+};
+
+enum ack_mb7_status_t {
+	MOD_SW_RESET_REQ = 0x03,
+	CA_SLEEP_REQ    = 0x02,
+	HOST_PORT_ACK   = 0x01,
+	ACKMB7_INIT    = 0x00
+};
+
+#endif /* __MACH_PRCMU_FW_DEFS_V1_H */
diff --git a/board/st-ericsson/u8500/prcmu-fw.h b/board/st-ericsson/u8500/prcmu-fw.h
new file mode 100644
index 0000000..1484d5f
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu-fw.h
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __MACH_PRCMU_FW_V1_H
+#define __MACH_PRCMU_FW_V1_H
+
+#include "prcmu-fw-defs_v1.h"
+
+#define _PRCMU_TCDM_BASE    U8500_PRCMU_TCDM_BASE
+#define PRCM_BOOT_STATUS    (_PRCMU_TCDM_BASE + 0xFFF)
+#define PRCM_ROMCODE_A2P    (_PRCMU_TCDM_BASE + 0xFFE)
+#define PRCM_ROMCODE_P2A    (_PRCMU_TCDM_BASE + 0xFFD)
+#define PRCM_XP70_CUR_PWR_STATE (_PRCMU_TCDM_BASE + 0xFFC)      /* 4 BYTES */
+
+
+#define _PRCM_MBOX_HEADER		(_PRCMU_TCDM_BASE + 0xFE8)/*16 bytes*/
+#define PRCM_MBOX_HEADER_REQ_MB0	(_PRCM_MBOX_HEADER + 0x0)
+#define PRCM_MBOX_HEADER_REQ_MB1	(_PRCM_MBOX_HEADER + 0x1)
+#define PRCM_MBOX_HEADER_REQ_MB2	(_PRCM_MBOX_HEADER + 0x2)
+#define PRCM_MBOX_HEADER_REQ_MB3	(_PRCM_MBOX_HEADER + 0x3)
+#define PRCM_MBOX_HEADER_REQ_MB4	(_PRCM_MBOX_HEADER + 0x4)
+#define PRCM_MBOX_HEADER_REQ_MB5	(_PRCM_MBOX_HEADER + 0x5)
+#define PRCM_MBOX_HEADER_REQ_MB6	(_PRCM_MBOX_HEADER + 0x6)
+#define PRCM_MBOX_HEADER_REQ_MB7	(_PRCM_MBOX_HEADER + 0x7)
+#define PRCM_MBOX_HEADER_ACK_MB0	(_PRCM_MBOX_HEADER + 0x8)
+#define PRCM_MBOX_HEADER_ACK_MB1	(_PRCM_MBOX_HEADER + 0x9)
+#define PRCM_MBOX_HEADER_ACK_MB2	(_PRCM_MBOX_HEADER + 0xA)
+#define PRCM_MBOX_HEADER_ACK_MB3	(_PRCM_MBOX_HEADER + 0xB)
+#define PRCM_MBOX_HEADER_ACK_MB4	(_PRCM_MBOX_HEADER + 0xC)
+#define PRCM_MBOX_HEADER_ACK_MB5	(_PRCM_MBOX_HEADER + 0xD)
+#define PRCM_MBOX_HEADER_ACK_MB6	(_PRCM_MBOX_HEADER + 0xE)
+#define PRCM_MBOX_HEADER_ACK_MB7	(_PRCM_MBOX_HEADER + 0xF)
+
+/*Req Mailboxes */
+#define PRCM_REQ_MB0        (_PRCMU_TCDM_BASE + 0xFDC)    /* 12 bytes  */
+#define PRCM_REQ_MB1        (_PRCMU_TCDM_BASE + 0xFD0)    /* 12 bytes  */
+#define PRCM_REQ_MB2        (_PRCMU_TCDM_BASE + 0xFC0)    /* 16 bytes  */
+#define PRCM_REQ_MB3        (_PRCMU_TCDM_BASE + 0xE4C)    /* 372 bytes  */
+#define PRCM_REQ_MB4        (_PRCMU_TCDM_BASE + 0xE48)    /* 4 bytes  */
+#define PRCM_REQ_MB5        (_PRCMU_TCDM_BASE + 0xE44)    /* 4 bytes  */
+#define PRCM_REQ_MB6        (_PRCMU_TCDM_BASE + 0xE40)    /* 4 bytes  */
+#define PRCM_REQ_MB7        (_PRCMU_TCDM_BASE + 0xE3C)    /* 4 bytes  */
+
+/*Ack Mailboxes */
+#define PRCM_ACK_MB0        (_PRCMU_TCDM_BASE + 0xE08)    /* 52 bytes  */
+#define PRCM_ACK_MB1        (_PRCMU_TCDM_BASE + 0xE04)    /* 4 bytes */
+#define PRCM_ACK_MB2        (_PRCMU_TCDM_BASE + 0xE00)    /* 4 bytes */
+#define PRCM_ACK_MB3        (_PRCMU_TCDM_BASE + 0xDFC)    /* 4 bytes */
+#define PRCM_ACK_MB4        (_PRCMU_TCDM_BASE + 0xDF8)    /* 4 bytes */
+#define PRCM_ACK_MB5        (_PRCMU_TCDM_BASE + 0xDF4)    /* 4 bytes */
+#define PRCM_ACK_MB6        (_PRCMU_TCDM_BASE + 0xDF0)    /* 4 bytes */
+#define PRCM_ACK_MB7	    (_PRCMU_TCDM_BASE + 0xDEC)    /* 4 bytes  */
+
+/* Mailbox 0 REQs */
+#define PRCM_REQ_MB0_PWRSTTRH		(PRCM_REQ_MB0 + 0x0)
+#define PRCM_REQ_MB0_PWRSTTRH_APPWRST	(PRCM_REQ_MB0 + 0x0)
+#define PRCM_REQ_MB0_PWRSTTRH_APPLLST	(PRCM_REQ_MB0 + 0x1)
+#define PRCM_REQ_MB0_PWRSTTRH_ULPCLKST	(PRCM_REQ_MB0 + 0x2)
+#define PRCM_REQ_MB0_PWRSTTRH_BYTEFILL	(PRCM_REQ_MB0 + 0x3)
+#define PRCM_REQ_MB0_WKUP_8500	(PRCM_REQ_MB0 + 0x4)
+#define PRCM_REQ_MB0_WKUP_4500	(PRCM_REQ_MB0 + 0x8)
+
+
+/* Mailbox 0 ACKs */
+#define PRCM_ACK_MB0_AP_PWRST_STATUS	(PRCM_ACK_MB0 + 0x0)
+#define PRCM_ACK_MB0_PINGPONG_RDP	(PRCM_ACK_MB0 + 0x1)
+#define PRCM_ACK_MB0_PINGPONG_WKUP_RST_0 (PRCM_ACK_MB0 + 0x2)
+#define PRCM_ACK_MB0_PINGPONG_WKUP_RST_1 (PRCM_ACK_MB0 + 0x3)
+#define PRCM_ACK_MB0_WK0_EVENT_8500     (_PRCMU_TCDM_BASE + 0xE0C)
+#define PRCM_ACK_MB0_WK0_EVENT_4500     (_PRCMU_TCDM_BASE + 0xE10)
+#define PRCM_ACK_MB0_WK1_EVENT_8500     (_PRCMU_TCDM_BASE + 0xE24)
+#define PRCM_ACK_MB0_WK1_EVENT_4500     (_PRCMU_TCDM_BASE + 0xE28)
+#define PRCM_ACK_MB0_EVENT_4500_NUMBERS	20
+
+
+/* Mailbox 1 Requests */
+#define PRCM_REQ_MB1_ARMOPP     (PRCM_REQ_MB1 + 0x0)
+#define PRCM_REQ_MB1_APEOPP     (PRCM_REQ_MB1 + 0x1)
+#define PRCM_REQ_MB1_BOOSTOPP   (PRCM_REQ_MB1 + 0x2)
+
+/* Mailbox 1 ACKs */
+#define PRCM_ACK_MB1_CURR_ARMOPP        (PRCM_ACK_MB1 + 0x0)
+#define PRCM_ACK_MB1_CURR_APEOPP        (PRCM_ACK_MB1 + 0x1)
+#define PRCM_ACK_MB1_CURR_BOOSTOPP      (PRCM_ACK_MB1 + 0x2)
+#define PRCM_ACK_MB1_CURR_DVFS_STATUS   (PRCM_ACK_MB1 + 0x3)
+
+/* Mailbox 2 REQs */
+#define PRCM_REQ_MB2_DPS_SVAMMDSP        (PRCM_REQ_MB2 + 0x0)
+#define PRCM_REQ_MB2_DPS_SVAPIPE         (PRCM_REQ_MB2 + 0x1)
+#define PRCM_REQ_MB2_DPS_SIAMMDSP        (PRCM_REQ_MB2 + 0x2)
+#define PRCM_REQ_MB2_DPS_SIAPIPE         (PRCM_REQ_MB2 + 0x3)
+#define PRCM_REQ_MB2_DPS_SGA             (PRCM_REQ_MB2 + 0x4)
+#define PRCM_REQ_MB2_DPS_B2R2MCDE        (PRCM_REQ_MB2 + 0x5)
+#define PRCM_REQ_MB2_DPS_ESRAM12         (PRCM_REQ_MB2 + 0x6)
+#define PRCM_REQ_MB2_DPS_ESRAM34         (PRCM_REQ_MB2 + 0x7)
+#define PRCM_REQ_MB2_AUTOPWR_APSLEEP     (PRCM_REQ_MB2 + 0x8)
+#define PRCM_REQ_MB2_AUTOPWR_APSLEEP_SIA_PWRON_ENABLE     (PRCM_REQ_MB2 + 0x9)
+#define PRCM_REQ_MB2_AUTOPWR_APSLEEP_SVA_PWRON_ENABLE     (PRCM_REQ_MB2 + 0xA)
+#define PRCM_REQ_MB2_AUTOPWR_APSLEEP_AUTO_PWRON_ENABLE     (PRCM_REQ_MB2 + 0xB)
+#define PRCM_REQ_MB2_AUTOPWR_APIDLE     (PRCM_REQ_MB2 + 0xC)
+#define PRCM_REQ_MB2_AUTOPWR_APIDLE_SIA_PWRON_ENABLE     (PRCM_REQ_MB2 + 0xD)
+#define PRCM_REQ_MB2_AUTOPWR_APIDLE_SVA_PWRON_ENABLE     (PRCM_REQ_MB2 + 0xE)
+#define PRCM_REQ_MB2_AUTOPWR_APIDLE_AUTO_PWRON_ENABLE     (PRCM_REQ_MB2 + 0xF)
+
+/* Mailbox 2 ACKs */
+#define PRCM_ACK_MB2_DPS_STATUS          (PRCM_ACK_MB2 + 0x0)
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2COPTYPE_REG	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_BIT_FIELDS		(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2CSLAVE		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2CVAL		(PRCM_REQ_MB5 + 0x3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_SLAVE	(PRCM_ACK_MB5 + 0x2)
+#define PRCM_ACK_MB5_VAL	(PRCM_ACK_MB5 + 0x3)
+
+#define LOW_POWER_WAKEUP	1
+#define EXE_WAKEUP		0
+
+/* FIXME : Need to Cleanup Code */
+
+#define PRCM_SVAMMDSPSTATUS PRCM_REQ_MB6
+#define PRCM_SIAMMDSPSTATUS PRCM_REQ_MB7
+
+
+#define PRCM_XP70_TRIG_IT10	(1 << 0)
+#define PRCM_XP70_TRIG_IT11	(1 << 1)
+#define PRCM_XP70_TRIG_IT12	(1 << 2)
+#define PRCM_XP70_TRIG_IT14	(1 << 4)
+#define PRCM_XP70_TRIG_IT17	(1 << 5)
+
+enum mailbox_t {
+	REQ_MB0 = 0,	/* Uses XP70_IT_EVENT_10 */
+	REQ_MB1 = 1,	/* Uses XP70_IT_EVENT_11 */
+	REQ_MB2 = 2,	/* Uses XP70_IT_EVENT_12 */
+	REQ_MB5 = 5,	/* Uses XP70_IT_EVENT_17 */
+};
+
+/* Union declaration */
+
+
+
+/* ARM to XP70 mailbox definition */
+union req_mb0_t {
+	struct {
+		enum ap_pwrst_trans_t ap_pwrst_trans:8;
+		enum intr_wakeup_t fifo_4500wu:8;
+		enum ddr_pwrst_t ddr_pwrst:8;
+		unsigned int unused:8;
+	} req_field;
+	unsigned int complete_field;
+};
+
+/* mailbox definition for ARM/APE operation */
+union req_mb1_t {
+	struct {
+		enum arm_opp_t arm_opp:8;
+		enum ape_opp_t ape_opp:8;
+	} req_field;
+	unsigned short complete_field;
+};
+
+#endif /* __MACH_PRCMU_FW_V1_H */
diff --git a/board/st-ericsson/u8500/prcmu.c b/board/st-ericsson/u8500/prcmu.c
new file mode 100644
index 0000000..1706ec8
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Adapted from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This currently does not support the I2C workaround access method.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include <asm/arch/ab8500.h>
+
+#include "prcmu-fw.h"
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+
+static int prcmu_is_ready(void)
+{
+	int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
+	if (!ready)
+		printf("PRCMU firmware not ready\n");
+	return ready;
+}
+
+static int _wait_for_req_complete(enum mailbox_t num)
+{
+	int timeout = 1000;
+
+	/* checking any already on-going transaction */
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	timeout = 1000;
+
+	/* Set an interrupt to XP70 */
+	writel(1 << num, PRCM_MBOX_CPU_SET);
+
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	if (!timeout) {
+		printf("PRCMU operation timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db8500 register to be accessed
+ * Returns: ACK_MB5  value containing the status
+ */
+int prcmu_i2c_read(u8 reg, u16 slave)
+{
+	uint8_t i2c_status;
+	uint8_t i2c_val;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(0, PRCM_REQ_MB5_I2CVAL);
+
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	i2c_val = readb(PRCM_ACK_MB5_VAL);
+
+	if (i2c_status == I2C_RD_OK)
+		return i2c_val;
+	else {
+
+		printf("prcmu_i2c_read:read return status= %d\n",
+				i2c_status);
+		return -1;
+	}
+
+}
+
+/**
+ * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db800 register to be written to
+ * @reg_data: - the data to write
+ * Returns: ACK_MB5 value containing the status
+ */
+int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
+{
+	uint8_t i2c_status;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
+
+	debug("\ncpu_is_u8500v11\n");
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	debug("\ni2c_status = %x\n", i2c_status);
+	if (i2c_status == I2C_WR_OK)
+		return 0;
+	else {
+		printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
+		return -1;
+	}
+}
diff --git a/board/st-ericsson/u8500/u8500_href.c b/board/st-ericsson/u8500/u8500_href.c
new file mode 100644
index 0000000..de9f310
--- /dev/null
+++ b/board/st-ericsson/u8500/u8500_href.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/common.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/ab8500.h>
+#include <asm/arch/gpio.h>
+
+#define NOMADIK_PER4_BASE	(0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+/* Power, Reset, Clock Management Unit */
+/*
+ * SVA: Smart Video Accelerator
+ * SIA: Smart Imaging Accelerator
+ * SGA: Smart Graphic accelerator
+ * B2R2: Graphic blitter
+ */
+#define PRCMU_BASE	CFG_PRCMU_BASE	/* 0x80157000 for U8500 */
+#define PRCM_ARMCLKFIX_MGT_REG		(PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG		(PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG		(PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG		(PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG		(PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG		(PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG		(PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG		(PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG		(PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG		(PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG		(PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG		(PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG		(PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG		(PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG		(PRCMU_BASE + 0x074)
+#define PRCM_B2R2CLK_MGT_REG		(PRCMU_BASE + 0x078)
+
+#define PRCM_PLLSOC0_FREQ_REG		(PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ_REG		(PRCMU_BASE + 0x084)
+#define PRCM_PLLARM_FREQ_REG		(PRCMU_BASE + 0x088)
+#define PRCM_PLLDDR_FREQ_REG		(PRCMU_BASE + 0x08C)
+#define PRCM_ARM_CHGCLKREQ_REG		(PRCMU_BASE + 0x114)
+
+#define PRCM_TCR			(PRCMU_BASE + 0x1C8)
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR			0x80156000
+#define DMC_CTL_97			(DMC_BASE_ADDR + 0x184)
+
+int board_id;	/* set in board_late_init() */
+
+/* PLLs for clock management registers */
+enum {
+	GATED = 0,
+	PLLSOC0,	/* pllsw = 001, ffs() = 1 */
+	PLLSOC1,	/* pllsw = 010, ffs() = 2 */
+	PLLDDR,		/* pllsw = 100, ffs() = 3 */
+	PLLARM,
+};
+
+static struct pll_freq_regs {
+	int idx;	/* index fror pll_name and pll_khz arrays */
+	uint32_t addr;
+} pll_freq_regs[] = {
+	{PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
+	{PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
+	{PLLDDR, PRCM_PLLDDR_FREQ_REG},
+	{PLLARM, PRCM_PLLARM_FREQ_REG},
+	{0, 0},
+};
+
+static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
+static uint32_t pll_khz[5];	/* use ffs(pllsw(reg)) as index for 0..3 */
+
+static struct clk_mgt_regs {
+	uint32_t addr;
+	uint32_t val;
+	const char *descr;
+} clk_mgt_regs[] = {
+	/* register content taken from bootrom settings */
+	{PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+	{PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+	{PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+	{PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+	{PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},	/* dis, SOC0/4, 200 MHz */
+	{PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},	/* ena, GATED, CLK38 */
+	{PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},	/* dis, GATED, CLK38 */
+	{PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},	/* ena, SOC0/16, 50 MHz */
+	{PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+	{PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},	/* ena, SOC0/8, 100 MHz */
+	{PRCM_DMACLK_MGT_REG, 0x125, "DMA"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},	/* dis, SOC0/5, 160 MHz */
+	{0, 0, NULL},
+};
+
+static void init_regs(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+static unsigned int read_asicid(void)
+{
+	unsigned int *address = (void *)U8500_BOOTROM_BASE
+				+ U8500_BOOTROM_ASIC_ID_OFFSET;
+	return readl(address);
+}
+
+int cpu_is_u8500v11(void)
+{
+	return read_asicid() == 0x008500A1;
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_early_init_f(void)
+{
+	init_regs();
+	return 0;
+}
+
+int board_init(void)
+{
+	uint32_t unused_cols_rows;
+	unsigned int nrows;
+	unsigned int ncols;
+
+	gd->bd->bi_arch_number = 0x1A4;
+	gd->bd->bi_boot_params = 0x00000100;
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+
+	/*
+	 * Assumption: 2 CS active, both CS have same layout.
+	 *             15 rows max, 11 cols max (controller spec).
+	 *             memory chip has 8 banks, I/O width 32 bit.
+	 * The correct way would be to read MR#8: I/O width and density,
+	 * but this requires locking against the PRCMU firmware.
+	 * Simplified approach:
+	 * Read number of unused rows and columns from mem controller.
+	 * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+	 */
+	unused_cols_rows = readl(DMC_CTL_97);
+	nrows = 15 - (unused_cols_rows & 0x07);
+	ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+	gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+	icache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+	return 0;
+}
+
+unsigned int addr_vall_arr[] = {
+	0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8011F008, 0x00001CFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8000F000, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x8000F008, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x80157020, 0x00000150, /* I2C 48MHz clock */
+	0x8012F000, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0x8012F008, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0xA03DF000, 0x0000000D, /* Clock for MTU Timers */
+	0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */
+	0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */
+	0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */
+	0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x801571E4, 0x0000000C, /* PRCMU settings for B2R2,
+				   PRCM_APE_RESETN_SET_REG */
+	0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */
+	0xA03FF000, 0x00000003, /* USB */
+	0xA03FF008, 0x00000001, /* USB */
+	0xA03FE00C, 0x00000000, /* USB */
+	0xA03FE020, 0x00000FFF, /* USB */
+	0xA03FE024, 0x00000000	/* USB */
+};
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_MASK		0x3
+#define LDO_VAUX3_ENABLE	0x1
+#define VAUX3_VOLTAGE_2_9V	0xd
+
+static int hrefplus_mmc_power_init(void)
+{
+	int ret;
+	int val;
+
+	if (!cpu_is_u8500v11())
+		return 0;
+
+	/*
+	 * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
+	 * card to work.  This is done by enabling the regulators in the AB8500
+	 * via PRCMU I2C transactions.
+	 *
+	 * This code is derived from the handling of AB8500_LDO_VAUX3 in
+	 * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+	 *
+	 * Turn off and delay is required to have it work across soft reboots.
+	 */
+
+	ret = ab8500_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+	if (ret < 0)
+		goto out;
+
+	val = ret;
+
+	/* Turn off */
+	ret = ab8500_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+				val & ~LDO_VAUX3_MASK);
+	if (ret < 0)
+		goto out;
+
+	udelay(10 * 1000);
+
+	/* Set the voltage to 2.9V */
+	ret = ab8500_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_SEL_REG,
+				VAUX3_VOLTAGE_2_9V);
+	if (ret < 0)
+		goto out;
+
+	val = val & ~LDO_VAUX3_MASK;
+	val = val | LDO_VAUX3_ENABLE;
+
+	/* Turn on the supply */
+	ret = ab8500_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+
+out:
+	return ret;
+}
+#endif
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+	uchar byte;
+
+	/*
+	 * Determine and set board_id environment variable
+	 * 0: mop500, 1: href500
+	 * Above boards have different GPIO expander chips which we can
+	 * distinguish by the chip id.
+	 *
+	 * The board_id environment variable is needed for the Linux bootargs.
+	 */
+	(void) i2c_set_bus_num(0);
+	(void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
+	if (byte == 0x01) {
+		board_id = 0;
+		setenv("board_id", "0");
+	} else {
+		board_id = 1;
+		setenv("board_id", "1");
+	}
+#ifdef CONFIG_MMC
+	hrefplus_mmc_power_init();
+
+	/*
+	 * config extended GPIO pins for level shifter and
+	 * SDMMC_ENABLE
+	 */
+	if (board_id == 0) {
+		/* MOP500 */
+		byte = 0x0c;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
+	} else {
+		/* HREF */
+		/* set the direction of GPIO KPY9 and KPY10 */
+		byte = 0x06;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
+		/* must be a multibyte access */
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
+						(uchar []) {0x06, 0x06}, 2);
+	}
+#endif /* CONFIG_MMC */
+	/*
+	 * Create a memargs variable which points uses either the memargs256 or
+	 * memargs512 environment variable, depending on the memory size.
+	 * memargs is used to build the bootargs, memargs256 and memargs512 are
+	 * stored in the environment.
+	 */
+	if (gd->bd->bi_dram[0].size == 0x10000000) {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
+		setenv("mem", "256M");
+	} else {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
+		setenv("mem", "512M");
+	}
+
+	return 0;
+}
+#endif /* BOARD_LATE_INIT */
+
+static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
+{
+	writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
+	writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
+}
+
+static void init_regs(void)
+{
+	/* FIXME Remove magic register array settings for ED also */
+	struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
+
+	/* Enable timers */
+	writel(1 << 17, &prcmu->tcr);
+
+	u8500_prcmu_enable(&prcmu->per1clk_mgt);
+	u8500_prcmu_enable(&prcmu->per2clk_mgt);
+	u8500_prcmu_enable(&prcmu->per3clk_mgt);
+	u8500_prcmu_enable(&prcmu->per5clk_mgt);
+	u8500_prcmu_enable(&prcmu->per6clk_mgt);
+	u8500_prcmu_enable(&prcmu->per7clk_mgt);
+
+	u8500_prcmu_enable(&prcmu->uartclk_mgt);
+	u8500_prcmu_enable(&prcmu->i2cclk_mgt);
+
+	u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
+
+	u8500_clock_enable(1, 9, -1);	/* GPIO0 */
+
+	u8500_clock_enable(2, 11, -1);	/* GPIO1 */
+
+	u8500_clock_enable(3, 8, -1);	/* GPIO2 */
+	u8500_clock_enable(5, 1, -1);	/* GPIO3 */
+
+	u8500_clock_enable(3, 6, 6);	/* UART2 */
+
+	gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
+	u8500_clock_enable(3, 3, 3);	/* I2C0 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
+	gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
+
+	u8500_clock_enable(1, 5, 5);	/* SDI0 */
+	u8500_clock_enable(2, 4, 2);	/* SDI4 */
+
+	u8500_clock_enable(6, 7, -1);	/* MTU0 */
+	u8500_clock_enable(3, 4, 4);	/* SDI2 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
+	gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+
+	/*
+	 * Enabling clocks for all devices which are AMBA devices in the
+	 * kernel.  Otherwise they will not get probe()'d because the
+	 * peripheral ID register will not be powered.
+	 */
+
+	/* XXX: some of these differ between ED/V1 */
+
+	u8500_clock_enable(1, 1, 1);	/* UART1 */
+	u8500_clock_enable(1, 0, 0);	/* UART0 */
+
+	u8500_clock_enable(3, 2, 2);	/* SSP1 */
+	u8500_clock_enable(3, 1, 1);	/* SSP0 */
+
+	u8500_clock_enable(2, 8, -1);	/* SPI0 */
+	u8500_clock_enable(2, 5, 3);	/* MSP2 */
+}
+
+#ifdef CONFIG_MMC
+static int u8500_mmci_board_init(void)
+{
+	enum gpio_error error;
+	struct gpio_register *gpio_base_address;
+
+	gpio_base_address = (void *) IO_ADDRESS(U8500_GPIO_0_BASE);
+	gpio_base_address->gpio_dats |= 0xFFC0000;
+	gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+	/* save the GPIO0 AFSELA register */
+	error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+	if (error != GPIO_OK) {
+		printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int board_mmc_init(bd_t *bd)
+{
+	if (u8500_mmci_board_init())
+		return -ENODEV;
+
+	arm_pl180_mmci_init();
+	return 0;
+}
+#endif
+
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+	uint32_t idf, ldf, odf, seldiv, phi;
+
+	/*
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+	 * where:
+	 * IDF=R(2:0) (when R=000, IDF=1d)
+	 * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+	 * ODF = N(5:0) (when N=000000, 0DF=1d)
+	 */
+
+	idf = (freq_reg & 0x70000) >> 16;
+	ldf = (freq_reg & 0xff) * 2;
+	odf = (freq_reg & 0x3f00) >> 8;
+	seldiv = (freq_reg & 0x01000000) >> 24;
+	phi = (inclk_khz * ldf) / (2 * odf * idf);
+	if (seldiv)
+		phi = phi/2;
+
+	return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t inclk_khz;
+	uint32_t reg, phi;
+	uint32_t clk_khz;
+	unsigned int clk_sel;
+	struct clk_mgt_regs *clks = clk_mgt_regs;
+	struct pll_freq_regs *plls = pll_freq_regs;
+
+	/*
+	 * Go through list of PLLs.
+	 * Initialise pll out frequency array (pll_khz) and print frequency.
+	 */
+	inclk_khz = 38400;	/* 38.4 MHz */
+	while (plls->addr) {
+		reg = readl(plls->addr);
+		phi = get_pll_freq_khz(inclk_khz, reg);
+		pll_khz[plls->idx] = phi;
+		printf("%s PLL out frequency: %d.%d Mhz\n",
+				pll_name[plls->idx], phi/1000, phi % 1000);
+		plls++;
+	}
+
+	/* check ARM clock source */
+	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
+	printf("A9 running on ");
+	if (reg & 1)
+		printf("external clock");
+	else
+		printf("ARM PLL");
+	printf("\n");
+
+	/* go through list of clk_mgt_reg */
+	printf("\n%19s %9s %7s %9s enabled\n",
+			"name(addr)", "value", "PLL", "CLK[MHz]");
+	while (clks->addr) {
+		reg = readl(clks->addr);
+		/* convert bit position into array index */
+		clk_sel = ffs((reg >> 5) & 0x7);	/* PLLSW[2:0] */
+		printf("%9s(%08x): %08x", clks->descr, clks->addr, reg);
+		printf(", %6s", pll_name[clk_sel]);
+		if (reg & 0x200)
+			clk_khz = 38400;	/* CLK38 is set */
+		else if ((reg & 0x1f) == 0)
+			/* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+			clk_khz = 0;
+		else
+			clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
+		printf(", %4d.%03d", clk_khz / 1000, clk_khz % 1000);
+		printf(", %s\n", (reg & 0x100) ? "ena" : "dis");
+		clks++;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clkinfo,	1,	1,	do_clkinfo,
+	"print clock info",
+	""
+);
diff --git a/boards.cfg b/boards.cfg
index 999c473..9e5c068 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -132,6 +132,7 @@ smdkc100                     arm         armv7       smdkc100            samsung
 s5pc210_universal            arm         armv7       universal_c210      samsung        s5pc2xx
 harmony                      arm         armv7       harmony             nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
+u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 actux1                       arm         ixp
 actux2                       arm         ixp
 actux3                       arm         ixp
diff --git a/include/configs/u8500_href.h b/include/configs/u8500_href.h
new file mode 100644
index 0000000..38125d5
--- /dev/null
+++ b/include/configs/u8500_href.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_U8500		1
+#define CONFIG_L2_OFF		1
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF
+#define CONFIG_SYS_HZ		1000		/* must be 1000 */
+
+#define CONFIG_BOARD_EARLY_INIT_F	1
+#define BOARD_LATE_INIT		1
+
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE		(32*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE		(128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* for initial data */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE		0x80120000
+#define CFG_UART1_BASE		0x80121000
+#define CFG_UART2_BASE		0x80007000
+#define CFG_SERIAL0		CFG_UART0_BASE
+#define CFG_SERIAL1		CFG_UART1_BASE
+#define CFG_SERIAL2		CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK	38400000
+#define CONFIG_PL01x_PORTS	{ (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+				  (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC		1
+#define CONFIG_GENERIC_MMC	1
+#define CONFIG_DOS_PARTITION	1
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY	1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=n\0"							\
+	"loadaddr=0x00100000\0"						\
+	"console=ttyAMA2,115200n8\0"					\
+	"memargs256=mem=96M at 0 mem_modem=32M at 96M mem=30M at 128M "		\
+		"pmem=22M at 158M pmem_hwb=44M at 180M mem_mali=32 at 224M\0"	\
+	"memargs512=mem=96M at 0 mem_modem=32M at 96M mem=44M at 128M "		\
+		"pmem=22M at 172M mem=30M at 194M mem_mali=32M at 224M "		\
+		"pmem_hwb=54M at 256M mem=202M at 310M\0"			\
+	"commonargs=setenv bootargs cachepolicy=writealloc noinitrd "	\
+		"init=init "						\
+		"board_id=${board_id} "					\
+		"logo.${logo} "						\
+		"startup_graphics=${startup_graphics}\0"		\
+	"emmcargs=setenv bootargs ${bootargs} "				\
+		"root=/dev/mmcblk0p2 "					\
+		"rootdelay=1\0"						\
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console}\0"					\
+	"emmcboot=echo Booting from eMMC ...; "				\
+		"run commonargs emmcargs addcons memargs;"		\
+		"mmc read 0 ${loadaddr} 0xA0000 0x4000;"		\
+		"bootm ${loadaddr}\0"					\
+	"flash=mmc init 1;fatload mmc 1 ${loadaddr} flash.scr;"		\
+		"source ${loadaddr}\0"					\
+	"loaduimage=mmc init 1;fatload mmc 1 ${loadaddr} uImage\0"	\
+	"usbtty=cdc_acm\0"						\
+	"stdout=serial,usbtty\0"					\
+	"stdin=serial,usbtty\0"						\
+	"stderr=serial,usbtty\0"
+
+/*
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory     */
+#define CONFIG_SYS_PROMPT	"U8500 $ "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O Buffer Size  */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef	CONFIG_SYS_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR		0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE	1
+
+#define CONFIG_SYS_HUSH_PARSER		1
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS	2
+#define CONFIG_INITRD_TAG		1
+#define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs  */
+
+/*
+ * I2C
+ */
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support */
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0	/* slave addr of controller */
+#define CONFIG_SYS_I2C0_BASE		0x80004000
+#define CONFIG_SYS_I2C1_BASE		0x80122000
+#define CONFIG_SYS_I2C2_BASE		0x80128000
+#define CONFIG_SYS_I2C3_BASE		0x80110000
+#define CONFIG_SYS_I2C_BUS_MAX		4
+#define CONFIG_DRIVER_U8500_I2C		1
+
+#define CONFIG_SYS_I2C_GPIOE_ADDR	0x42	/* GPIO expander chip addr */
+#define CONFIG_TC35892_GPIO
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ		(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ		(4*1024)	/* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1		0x20000000	/* 512 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE            0x0
+#endif
+
+/*
+ * MMC related configs
+ * NB Only externa SD slot is currently supported
+ */
+#define MMC_BLOCK_SIZE			512
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x80126000	/* MMC base for 8500  */
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
+#define CONFIG_MMC_DEV_NUM		1
+
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_SAVEENV	/* CMD_ENV is obsolete but used in env_emmc.c */
+#define CONFIG_ENV_IS_IN_MMC		1
+#define CONFIG_ENV_OFFSET		0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV          0               /* SLOT2: eMMC */
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   management unit */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+#endif	/* __CONFIG_H */
-- 
1.7.1

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

* [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (3 preceding siblings ...)
  2011-03-22 20:40 ` [U-Boot] [PATCH 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
@ 2011-03-22 20:46 ` John Rigby
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-03-22 20:46 UTC (permalink / raw)
  To: u-boot

On Tue, Mar 22, 2011 at 2:40 PM, John Rigby <john.rigby@linaro.org> wrote:
> Add support for ST-Ericsson U8500 SoC and HREF platform
>
> John Rigby (1):
> ?armv7: Add support for ST-Ericsson U8500 href platform

I failed to mention that this board uses the mmc driver as vexpress
submitted a few weeks ago.

[U-Boot] [PATCH V3 0/3] Add support for the MMC device to the vexpress

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

* [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c
  2011-03-22 20:40 ` [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
@ 2011-03-23  7:00   ` Heiko Schocher
  0 siblings, 0 replies; 42+ messages in thread
From: Heiko Schocher @ 2011-03-23  7:00 UTC (permalink / raw)
  To: u-boot

Hello John,

John Rigby wrote:
> From: Michael Brandt <michael.brandt@stericsson.com>
> 
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> ---
>  drivers/i2c/Makefile    |    1 +
>  drivers/i2c/u8500_i2c.c |  603 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/u8500_i2c.h |  220 +++++++++++++++++
>  3 files changed, 824 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/i2c/u8500_i2c.c
>  create mode 100644 drivers/i2c/u8500_i2c.h
> 
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 052fe36..ac9c00f 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
>  COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
>  COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
>  COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
> +COBJS-$(CONFIG_DRIVER_U8500_I2C) += u8500_i2c.o

please without "_DRIVER". (you also need to sort lists
alphabetically)

>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
> new file mode 100644
> index 0000000..8965100
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.c
> @@ -0,0 +1,603 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2010
> + *
> + * Basic U-Boot I2C interface for STn8500/DB8500
> + * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +/*
> + * Only 7-bit I2C device addresses are supported.
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +
> +#include "u8500_i2c.h"
> +#include <asm/io.h>
> +#include <asm/arch/common.h>
> +#include <asm/arch/clock.h>
> +
> +#define I2C_ENDAD_COUNTER	(CONFIG_SYS_HZ/100)	/* I2C bus timeout */
> +#define I2C_FIFO_FLUSH_COUNTER	500000		/* flush "timeout" */
> +#define I2C_SCL_FREQ		100000		/* I2C bus clock frequency.*/
> +#define I2C_INPUT_FREQ		48000000	/* Input clock frequency.*/
> +#define TX_FIFO_THRESHOLD	0x4
> +#define RX_FIFO_THRESHOLD	0x4
> +#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
> +
> +#define WRITE_FIELD(var, mask, shift, value) \
> +			(var = ((var & ~(mask)) | ((value) << (shift))))
> +
> +static unsigned int bus_initialized[CONFIG_SYS_I2C_BUS_MAX];
> +static unsigned int i2c_bus_num;
> +static unsigned int i2c_bus_speed[] = {
> +	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
> +	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
> +};

All busses with the same speed? Also please use something
like "CONFIG_SYS_I2C_U8500_SPEED"

> +static struct u8500_i2c_regs *i2c_dev[] = {
> +	(struct u8500_i2c_regs *)CONFIG_SYS_I2C0_BASE,
> +	(struct u8500_i2c_regs *)CONFIG_SYS_I2C1_BASE,
> +	(struct u8500_i2c_regs *)CONFIG_SYS_I2C2_BASE,
> +	(struct u8500_i2c_regs *)CONFIG_SYS_I2C3_BASE,

Could we use for example "CONFIG_SYS_I2C_U8500_BASEx"?

> +};
> +
> +static struct {
> +	int periph;
> +	int pcken;
> +	int kcken;
> +} i2c_clock_bits[] = {
> +	{3, 3, 3}, /* I2C0 */
> +	{1, 2, 2}, /* I2C1 */
> +	{1, 6, 6}, /* I2C2 */
> +	{2, 0, 0}, /* I2C3 */
> +};
[...]
> diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
> new file mode 100644
> index 0000000..8ef6667
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.h
> @@ -0,0 +1,220 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2009
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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
> + */
> +
> +#ifndef _U8500_I2C_H_
> +#define _U8500_I2C_H_
> +
> +#include <asm/types.h>
> +#include <asm/io.h>
> +#include <asm/errno.h>
> +
> +//#include "common.h"

No C99 comments please. If it is dead code, please remove.

> +#include <asm/arch/u8500.h>
> +
> +/* Generic macros */
> +
> +#define I2C_WRITE_FIELD(reg_name, mask, shift, value) \
> +		(reg_name = ((reg_name & ~mask) | (value << shift)))
> +#define I2C_READ_FIELD(reg_name, mask, shift)    ((reg_name & mask) >> shift)
> +
> +struct u8500_i2c_regs {
> +	u32 cr;			/* Control Register                      0x00 */
> +	u32 scr;		/* Slave Address Register                0x04 */
> +	u32 hsmcr;		/* HS Master code Register               0x08 */
> +	u32 mcr;		/* Master Control Register               0x0C */
> +	u32 tfr;		/* Transmit Fifo Register                0x10 */
> +	u32 sr;			/* Status Register                       0x14 */
> +	u32 rfr;		/* Receiver Fifo Register                0x18 */
> +	u32 tftr;		/* Transmit Fifo Threshold Register      0x1C */
> +	u32 rftr;		/* Receiver Fifo Threshold Register      0x20 */
> +	u32 dmar;		/* DMA register                          0x24 */
> +	u32 brcr;		/* Baud Rate Counter Register            0x28 */
> +	u32 imscr;		/* Interrupt Mask Set and Clear Register 0x2C */
> +	u32 risr;		/* Raw interrupt status register         0x30 */
> +	u32 misr;		/* Masked interrupt status register      0x34 */
> +	u32 icr;		/* Interrupt Set and Clear Register      0x38 */
> +	u32 reserved_1[(0xFE0 - 0x3c) >> 2];	/* Reserved 0x03C to 0xFE0 */
> +	u32 periph_id_0;	/* peripheral ID 0	0xFE0 */
> +	u32 periph_id_1;	/* peripheral ID 1	0xFE4 */
> +	u32 periph_id_2;	/* peripheral ID 2	0xFE8 */
> +	u32 periph_id_3;	/* peripheral ID 3	0xFEC */
> +	u32 cell_id_0;		/* I2C cell   ID 0	0xFF0 */
> +	u32 cell_id_1;		/* I2C cell   ID 1	0xFF4 */
> +	u32 cell_id_2;		/* I2C cell   ID 2	0xFF8 */
> +	u32 cell_id_3;		/* I2C cell   ID 3	0xFFC */
> +};
> +
> +
> +/* Control Register */
> +
> +/* Mask values for control register mask */
> +#define I2C_CR_PE          MASK_BIT0	/* Peripheral enable */
> +#define I2C_CR_OM          0x6		/* Operation mode */
> +#define I2C_CR_SAM         MASK_BIT3	/* Slave Addressing mode */
> +#define I2C_CR_SM          0x30		/* Speed mode */
> +#define I2C_CR_SGCM        MASK_BIT6	/* Slave General call mode */
> +#define I2C_CR_FTX         MASK_BIT7	/* Flush Transmit */
> +#define I2C_CR_FRX         MASK_BIT8	/* Flush Receive */
> +#define I2C_CR_DMA_TX_EN   MASK_BIT9	/* DMA TX Enable */
> +#define I2C_CR_DMA_RX_EN   MASK_BIT10	/* DMA Rx Enable */
> +#define I2C_CR_DMA_SLE     MASK_BIT11	/* DMA Synchronization Logic enable */
> +#define I2C_CR_LM          MASK_BIT12	/* Loop back mode */
> +#define I2C_CR_FON         0x6000	/* Filtering On */
> +
> +/* shift valus for control register bit fields */
> +#define I2C_CR_SHIFT_PE		0	/* Peripheral enable */
> +#define I2C_CR_SHIFT_OM		1	/* Operation mode */
> +#define I2C_CR_SHIFT_SAM	3	/* Slave Addressing mode */
> +#define I2C_CR_SHIFT_SM		4	/* Speed mode */
> +#define I2C_CR_SHIFT_SGCM	6	/* Slave General call mode */
> +#define I2C_CR_SHIFT_FTX	7	/* Flush Transmit */
> +#define I2C_CR_SHIFT_FRX	8	/* Flush Receive */
> +#define I2C_CR_SHIFT_DMA_TX_EN	9	/* DMA TX Enable */
> +#define I2C_CR_SHIFT_DMA_RX_EN	10	/* DMA Rx Enable */
> +#define I2C_CR_SHIFT_DMA_SLE	11	/* DMA Synch Logic enable */
> +#define I2C_CR_SHIFT_LM		12	/* Loop back mode */
> +#define I2C_CR_SHIFT_FON	13	/* Filtering On */
> +
> +/* bus operation modes */
> +#define I2C_BUS_SLAVE_MODE		0
> +#define I2C_BUS_MASTER_MODE		1
> +#define I2C_BUS_MASTER_SLAVE_MODE	2
> +
> +
> +/* Slave control register*/
> +
> +/* Mask values slave control register */
> +#define I2C_SCR_ADDR                   0x3FF
> +#define I2C_SCR_DATA_SETUP_TIME        0xFFFF0000
> +
> +/* Shift values for Slave control register */
> +#define I2C_SCR_SHIFT_ADDR               0
> +#define I2C_SCR_SHIFT_DATA_SETUP_TIME    16
> +
> +
> +/* Master Control Register */
> +
> +/* Mask values for Master control register */
> +#define I2C_MCR_OP	MASK_BIT0	/* Operation */
> +#define I2C_MCR_A7	0xFE		/* LSB bits of the Address(7-bit ) */
> +#define I2C_MCR_EA10	0x700		/* Extended Address */
> +#define I2C_MCR_SB	MASK_BIT11	/* Start byte procedure */
> +#define I2C_MCR_AM	0x3000		/* Address type */
> +#define I2C_MCR_STOP	MASK_BIT14	/* stop condition */
> +#define I2C_MCR_LENGTH	0x3FF8000	/* Frame length */
> +#define I2C_MCR_A10	0x7FE		/* Define to set the 10 bit address */
> +/* mask for length field,stop and operation  */
> +#define I2C_MCR_LENGTH_STOP_OP	0x3FFC001
> +
> +/* Shift values for Master control values */
> +#define I2C_MCR_SHIFT_OP	0	/* Operation */
> +#define I2C_MCR_SHIFT_A7	1	/* LSB bits of the Address(7-bit ) */
> +#define I2C_MCR_SHIFT_EA10	8	/* Extended Address */
> +#define I2C_MCR_SHIFT_SB	11	/* Start byte procedure */
> +#define I2C_MCR_SHIFT_AM	12	/* Address type */
> +#define I2C_MCR_SHIFT_STOP	14	/* stop condition */
> +#define I2C_MCR_SHIFT_LENGTH	15	/* Frame length */
> +#define I2C_MCR_SHIFT_A10	1	/* define to set the 10 bit addres */
> +
> +#define I2C_MCR_SHIFT_LENGTH_STOP_OP	0
> +
> +
> +/* Status Register */
> +
> +/* Mask values for Status register */
> +#define I2C_SR_OP		0x3	/* Operation */
> +#define I2C_SR_STATUS		0xC	/* Controller Status */
> +#define I2C_SR_CAUSE		0x70	/* Abort Cause */
> +#define I2C_SR_TYPE		0x180	/* Receive Type */
> +#define I2C_SR_LENGTH		0xFF700	/* Transfer length */
> +
> +/* Shift values for Status register */
> +#define I2C_SR_SHIFT_OP		0	/* Operation */
> +#define I2C_SR_SHIFT_STATUS	2	/* Controller Status */
> +#define I2C_SR_SHIFT_CAUSE	4	/* Abort Cause */
> +#define I2C_SR_SHIFT_TYPE	7	/* Receive Type */
> +#define I2C_SR_SHIFT_LENGTH	9	/* Transfer length */
> +
> +/* abort cause */
> +#define	I2C_NACK_ADDR	0
> +#define	I2C_NACK_DATA	1
> +#define	I2C_ACK_MCODE	2
> +#define	I2C_ARB_LOST	3
> +#define	I2C_BERR_START	4
> +#define	I2C_BERR_STOP	5
> +#define	I2C_OVFL	6
> +
> +
> +/* Baud rate counter registers */
> +
> +/* Mask values for Baud rate counter register */
> +#define I2C_BRCR_BRCNT2	0xFFFF		/* Baud Rate Counter for HS mode */
> +#define I2C_BRCR_BRCNT1	0xFFFF0000	/* counter for Standard and Fast mode */
> +
> +/* Shift values for the Baud rate counter register */
> +#define I2C_BRCR_SHIFT_BRCNT2	0
> +#define I2C_BRCR_SHIFT_BRCNT1	16
> +
> +
> +/* Interrupt Register  */
> +
> +/* Mask values for Interrupt registers */
> +#define I2C_INT_TXFE	MASK_BIT0	/* Tx fifo empty */
> +#define I2C_INT_TXFNE	MASK_BIT1	/* Tx Fifo nearly empty */
> +#define I2C_INT_TXFF	MASK_BIT2	/* Tx Fifo Full */
> +#define I2C_INT_TXFOVR	MASK_BIT3	/* Tx Fifo over run */
> +#define I2C_INT_RXFE	MASK_BIT4	/* Rx Fifo Empty */
> +#define I2C_INT_RXFNF	MASK_BIT5	/* Rx Fifo nearly empty */
> +#define I2C_INT_RXFF	MASK_BIT6	/* Rx Fifo Full  */
> +#define I2C_INT_RFSR	MASK_BIT16	/* Read From slave request */
> +#define I2C_INT_RFSE	MASK_BIT17	/* Read from slave empty */
> +#define I2C_INT_WTSR	MASK_BIT18	/* Write to Slave request */
> +#define I2C_INT_MTD	MASK_BIT19	/* Master Transcation Done*/
> +#define I2C_INT_STD	MASK_BIT20	/* Slave Transaction Done */
> +#define I2C_INT_MAL	MASK_BIT24	/* Master Arbitation Lost */
> +#define I2C_INT_BERR	MASK_BIT25	/* Bus Error */
> +#define I2C_INT_MTDWS	MASK_BIT28	/* Master Transaction Done wo/ Stop */
> +
> +/* Shift values for Interrupt registers */
> +#define I2C_INT_SHIFT_TXFE	0	/* Tx fifo empty */
> +#define I2C_INT_SHIFT_TXFNE	1	/* Tx Fifo nearly empty */
> +#define I2C_INT_SHIFT_TXFF	2	/* Tx Fifo Full */
> +#define I2C_INT_SHIFT_TXFOVR	3	/* Tx Fifo over run */
> +#define I2C_INT_SHIFT_RXFE	4	/* Rx Fifo Empty */
> +#define I2C_INT_SHIFT_RXFNF	5	/* Rx Fifo nearly empty */
> +#define I2C_INT_SHIFT_RXFF	6	/* Rx Fifo Full  */
> +#define I2C_INT_SHIFT_RFSR	16	/* Read From slave request */
> +#define I2C_INT_SHIFT_RFSE	17	/* Read from slave empty */
> +#define I2C_INT_SHIFT_WTSR	18	/* Write to Slave request */
> +#define I2C_INT_SHIFT_MTD	19	/* Master Transcation Done */
> +#define I2C_INT_SHIFT_STD	20	/* Slave Transaction Done */
> +#define I2C_INT_SHIFT_MAL	24	/* Master Arbitation Lost */
> +#define I2C_INT_SHIFT_BERR	25	/* Bus Error */
> +#define I2C_INT_SHIFT_MTDWS	28	/* Master Transcation Done wo/ Stop */
> +
> +
> +/* Misc defines */
> +#define I2C_MAX_STANDARD_SCL	100000	/* Max clock (Hz) for Standard Mode */
> +#define I2C_MAX_FAST_SCL	400000	/* Max clock (Hz) for Fast Mode */
> +#define I2C_MAX_HIGH_SPEED_SCL	3400000	/* Max clock (Hz) for HS Mode */
> +
> +#endif	/* _U8500_I2C_H_ */

Hmm... all your defines use "general" names, there is no "U8500" or
"ST" or something in it. How about prefixing the macros in this file
as U8500_I2C or ST_I2C instead of I2C?

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCHv2 0/4] ST-Ericsson U8500 support
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (4 preceding siblings ...)
  2011-03-22 20:46 ` [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
@ 2011-04-02 16:19 ` John Rigby
  2011-04-11 17:33   ` John Rigby
                     ` (10 more replies)
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500 John Rigby
                   ` (3 subsequent siblings)
  9 siblings, 11 replies; 42+ messages in thread
From: John Rigby @ 2011-04-02 16:19 UTC (permalink / raw)
  To: u-boot

Add support for ST-Ericsson U8500 SoC and HREF platform

John Rigby (2):
  armv7: Add ST-Ericsson u8500 arch
  armv7: Add support for ST-Ericsson U8500 href platform

Michael Brandt (1):
  I2C: add driver of st-ericsson u8500 i2c

Rabin Vincent (1):
  p101x: extra init for u8500

 arch/arm/cpu/armv7/u8500/Makefile           |   46 ++
 arch/arm/cpu/armv7/u8500/clock.c            |   56 +++
 arch/arm/cpu/armv7/u8500/lowlevel.S         |   33 ++
 arch/arm/cpu/armv7/u8500/timer.c            |  167 ++++++++
 arch/arm/include/asm/arch-u8500/clock.h     |   72 ++++
 arch/arm/include/asm/arch-u8500/gpio.h      |  247 +++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h  |   83 ++++
 arch/arm/include/asm/arch-u8500/sys_proto.h |   29 ++
 arch/arm/include/asm/arch-u8500/u8500.h     |   47 ++
 board/st-ericsson/u8500/Makefile            |   50 +++
 board/st-ericsson/u8500/gpio.c              |  347 +++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h          |   52 +++
 board/st-ericsson/u8500/prcmu.c             |  165 +++++++
 board/st-ericsson/u8500/u8500_href.c        |  546 ++++++++++++++++++++++++
 boards.cfg                                  |    1 +
 drivers/i2c/Makefile                        |    1 +
 drivers/i2c/u8500_i2c.c                     |  613 +++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h                     |  194 +++++++++
 drivers/serial/serial_pl01x.c               |   10 +
 drivers/serial/serial_pl01x.h               |    4 +
 include/configs/u8500_href.h                |  243 +++++++++++
 21 files changed, 3006 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h
 create mode 100644 include/configs/u8500_href.h

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

* [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (5 preceding siblings ...)
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
@ 2011-04-02 16:19 ` John Rigby
  2011-04-11 17:48   ` Wolfgang Denk
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-02 16:19 UTC (permalink / raw)
  To: u-boot

From: Rabin Vincent <rabin.vincent@stericsson.com>

empty fifo on init
program receive line control register on u8500

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v2: no changes

 drivers/serial/serial_pl01x.c |   10 ++++++++++
 drivers/serial/serial_pl01x.h |    4 ++++
 2 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 5dfcde8..22ada8f 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -112,6 +112,12 @@ int serial_init (void)
 	unsigned int remainder;
 	unsigned int fraction;
 
+	/* Empty RX fifo if necessary */
+	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+			readl(&regs->dr);
+	}
+
 	/* First, disable everything */
 	writel(0, &regs->pl011_cr);
 
@@ -134,6 +140,10 @@ int serial_init (void)
 	writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN,
 	       &regs->pl011_lcrh);
 
+#ifdef CONFIG_U8500
+	/* program receive line control register */
+	writel(0x70, &regs->pl011_rlcr);
+#endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
 	       &regs->pl011_cr);
diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h
index b670c24..fdd3911 100644
--- a/drivers/serial/serial_pl01x.h
+++ b/drivers/serial/serial_pl01x.h
@@ -43,7 +43,11 @@ struct pl01x_regs {
 	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
 	u32	pl010_cr;	/* 0x14 Control register */
 	u32	fr;		/* 0x18 Flag register (Read only) */
+#ifdef CONFIG_U8500
+	u32	pl011_rlcr;	/* 0x1c Receive line control register */
+#else
 	u32	reserved;
+#endif
 	u32	ilpr;		/* 0x20 IrDA low-power counter register */
 	u32	pl011_ibrd;	/* 0x24 Integer baud rate register */
 	u32	pl011_fbrd;	/* 0x28 Fractional baud rate register */
-- 
1.7.1

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

* [U-Boot] [PATCHv2 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (6 preceding siblings ...)
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500 John Rigby
@ 2011-04-02 16:19 ` John Rigby
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
  9 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-04-02 16:19 UTC (permalink / raw)
  To: u-boot

Based on ST-Ericsson internal git repo.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
v2: cleanup, mostly removal of unused defines

 arch/arm/cpu/armv7/u8500/Makefile           |   46 +++++
 arch/arm/cpu/armv7/u8500/clock.c            |   56 ++++++
 arch/arm/cpu/armv7/u8500/lowlevel.S         |   33 ++++
 arch/arm/cpu/armv7/u8500/timer.c            |  167 ++++++++++++++++++
 arch/arm/include/asm/arch-u8500/clock.h     |   72 ++++++++
 arch/arm/include/asm/arch-u8500/gpio.h      |  247 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h  |   83 +++++++++
 arch/arm/include/asm/arch-u8500/sys_proto.h |   29 +++
 arch/arm/include/asm/arch-u8500/u8500.h     |   47 +++++
 9 files changed, 780 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h

diff --git a/arch/arm/cpu/armv7/u8500/Makefile b/arch/arm/cpu/armv7/u8500/Makefile
new file mode 100644
index 0000000..270aa40
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	= timer.o clock.o
+SOBJS	= lowlevel.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/u8500/clock.c b/arch/arm/cpu/armv7/u8500/clock.c
new file mode 100644
index 0000000..9e3b873
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/clock.c
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2009 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clkrst {
+	unsigned int pcken;
+	unsigned int pckdis;
+	unsigned int kcken;
+	unsigned int kckdis;
+};
+
+static unsigned int clkrst_base[] = {
+	U8500_CLKRST1_BASE,
+	U8500_CLKRST2_BASE,
+	U8500_CLKRST3_BASE,
+	0,
+	U8500_CLKRST5_BASE,
+	U8500_CLKRST6_BASE,
+	U8500_CLKRST7_BASE,	/* ED only */
+};
+
+/* Turn on peripheral clock at PRCC level */
+void u8500_clock_enable(int periph, int cluster, int kern)
+{
+	struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1];
+
+	if (kern != -1)
+		writel(1 << kern, &clkrst->kcken);
+
+	if (cluster != -1)
+		writel(1 << cluster, &clkrst->pcken);
+}
diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S
new file mode 100644
index 0000000..0e3f8fc
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/lowlevel.S
@@ -0,0 +1,33 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+.globl lowlevel_init
+lowlevel_init:
+	mov	pc, lr
+
+	.align	5
+.globl reset_cpu
+reset_cpu:
+        ldr r0, =CFG_PRCMU_BASE
+        ldr r1, =0x1
+        str r1, [r0, #0x228]
+_loop_forever:
+	b	_loop_forever
diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c
new file mode 100644
index 0000000..8850fd5
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/timer.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ * John Rigby <john.rigby@linaro.org>
+ *
+ * Based on original from Linux kernel source and
+ * internal ST-Ericsson U-Boot source.
+ * (C) Copyright 2009 Alessandro Rubini
+ * (C) Copyright 2010 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * The MTU device has some interrupt control registers
+ * followed by 4 timers.
+ */
+
+/* The timers */
+struct u8500_mtu_timer {
+	u32 lr;			/* Load value */
+	u32 cv;			/* Current value */
+	u32 cr;			/* Control reg */
+	u32 bglr;		/* ??? */
+};
+
+/* The MTU that contains the timers */
+struct u8500_mtu {
+	u32 imsc;		/* Interrupt mask set/clear */
+	u32 ris;		/* Raw interrupt status */
+	u32 mis;		/* Masked interrupt status */
+	u32 icr;		/* Interrupt clear register */
+	struct u8500_mtu_timer pt[4];
+};
+
+/* bits for the control register */
+#define MTU_CR_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR */
+#define MTU_CR_32BITS		0x02
+
+#define MTU_CR_PRESCALE_1	0x00
+#define MTU_CR_PRESCALE_16	0x04
+#define MTU_CR_PRESCALE_256	0x08
+#define MTU_CR_PRESCALE_MASK	0x0c
+
+#define MTU_CR_PERIODIC		0x40	/* if 0 = free-running */
+#define MTU_CR_ENA		0x80
+
+/*
+ * The MTU is clocked at 133 MHz by default. (V1 and later)
+ */
+#define TIMER_CLOCK		(133 * 1000 * 1000 / 16)
+#define COUNT_TO_USEC(x)	((x) * 16 / 133)
+#define USEC_TO_COUNT(x)	((x) * 133 / 16)
+#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
+#define TIMER_LOAD_VAL		0xffffffff
+
+/*
+ * MTU timer to use (from 0 to 3).
+ * Linux ux500 timer0 on MTU0 and timer0 on MTU1
+ */
+#define MTU_TIMER 2
+
+static struct u8500_mtu_timer *timer_base =
+	&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
+
+/* macro to read the 32 bit timer: since it decrements, we invert read value */
+#define READ_TIMER() (~readl(&timer_base->cv))
+
+/* Configure a free-running, auto-wrap counter with /16 prescaler */
+int timer_init(void)
+{
+	writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
+	       &timer_base->cr);
+	reset_timer();
+	return 0;
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = TICKS_TO_HZ(READ_TIMER());
+
+	if (now >= gd->lastinc)	/* normal (non rollover) */
+		gd->tbl += (now - gd->lastinc);
+	else			/* rollover */
+		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->tbl;
+}
+
+/* Delay x useconds */
+void __udelay(ulong usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	ulong now, last = READ_TIMER();
+
+	while (tmo > 0) {
+		now = READ_TIMER();
+		if (now > last)	/* normal (non rollover) */
+			tmo -= now - last;
+		else		/* rollover */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+void reset_timer_masked(void)
+{
+	gd->lastinc = TICKS_TO_HZ(READ_TIMER());
+	gd->tbl = 0;		/* reset ticks to 0 */
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+/*
+ * Emulation of Power architecture long long timebase.
+ *
+ * TODO: Support gd->tbu for real long long timebase.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * Emulation of Power architecture timebase.
+ * NB: Low resolution compared to Power tbclk.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/include/asm/arch-u8500/clock.h b/arch/arm/include/asm/arch-u8500/clock.h
new file mode 100644
index 0000000..b00ab0d
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/clock.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_CLOCK
+#define __ASM_ARCH_CLOCK
+
+struct prcmu {
+	unsigned int armclkfix_mgt;
+	unsigned int armclk_mgt;
+	unsigned int svammdspclk_mgt;
+	unsigned int siammdspclk_mgt;
+	unsigned int reserved;
+	unsigned int sgaclk_mgt;
+	unsigned int uartclk_mgt;
+	unsigned int msp02clk_mgt;
+	unsigned int i2cclk_mgt;
+	unsigned int sdmmcclk_mgt;
+	unsigned int slimclk_mgt;
+	unsigned int per1clk_mgt;
+	unsigned int per2clk_mgt;
+	unsigned int per3clk_mgt;
+	unsigned int per5clk_mgt;
+	unsigned int per6clk_mgt;
+	unsigned int per7clk_mgt;
+	unsigned int lcdclk_mgt;
+	unsigned int reserved1;
+	unsigned int bmlclk_mgt;
+	unsigned int hsitxclk_mgt;
+	unsigned int hsirxclk_mgt;
+	unsigned int hdmiclk_mgt;
+	unsigned int apeatclk_mgt;
+	unsigned int apetraceclk_mgt;
+	unsigned int mcdeclk_mgt;
+	unsigned int ipi2cclk_mgt;
+	unsigned int dsialtclk_mgt;
+	unsigned int spare2clk_mgt;
+	unsigned int dmaclk_mgt;
+	unsigned int b2r2clk_mgt;
+	unsigned int tvclk_mgt;
+	unsigned int unused[82];
+	unsigned int tcr;
+	unsigned int unused1[23];
+	unsigned int ape_softrst;
+};
+
+extern void u8500_clock_enable(int periph, int kern, int cluster);
+
+static inline void u8500_prcmu_enable(unsigned int *reg)
+{
+	writel(readl(reg) | (1 << 8), reg);
+}
+
+#endif /* __ASM_ARCH_CLOCK */
diff --git a/arch/arm/include/asm/arch-u8500/gpio.h b/arch/arm/include/asm/arch-u8500/gpio.h
new file mode 100644
index 0000000..769def1
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/gpio.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _UX500_GPIO_h
+#define _UX500_GPIO_h
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/u8500.h>
+
+#define GPIO_TOTAL_PINS                 268
+
+#define GPIO_PINS_PER_BLOCK	32
+#define GPIO_BLOCKS_COUNT       (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK + 1)
+#define GPIO_BLOCK(pin)		(((pin + GPIO_PINS_PER_BLOCK) >> 5) - 1)
+
+
+struct gpio_register {
+	u32 gpio_dat;	/* data register *//*0x000 */
+	u32 gpio_dats;	/* data Set register *//*0x004 */
+	u32 gpio_datc;	/* data Clear register *//*0x008 */
+	u32 gpio_pdis;	/* Pull disable register *//*0x00C */
+	u32 gpio_dir;	/* data direction register *//*0x010 */
+	u32 gpio_dirs;	/* data dir Set register *//*0x014 */
+	u32 gpio_dirc;	/* data dir Clear register *//*0x018 */
+	u32 gpio_slpm;	/* Sleep mode register *//*0x01C */
+	u32 gpio_afsa;	/* AltFun A Select reg *//*0x020 */
+	u32 gpio_afsb;	/* AltFun B Select reg *//*0x024 */
+	u32 gpio_lowemi;/* low EMI Select reg *//*0x028 */
+	u32 reserved_1[(0x040 - 0x02C) >> 2];	/*0x028-0x3C Reserved*/
+	u32 gpio_rimsc;	/* rising edge intr set/clear *//*0x040 */
+	u32 gpio_fimsc;	/* falling edge intr set/clear register *//*0x044 */
+	u32 gpio_mis;	/* masked interrupt status register *//*0x048 */
+	u32 gpio_ic;	/* Interrupt Clear register *//*0x04C */
+	u32 gpio_rwimsc;/* Rising-edge Wakeup IMSC register *//*0x050 */
+	u32 gpio_fwimsc;/* Falling-edge Wakeup IMSC register *//*0x054 */
+	u32 gpio_wks;	/* Wakeup Status register *//*0x058 */
+};
+
+/* Error values returned by functions */
+enum gpio_error {
+	GPIO_OK = 0,
+	GPIO_UNSUPPORTED_HW = -2,
+	GPIO_UNSUPPORTED_FEATURE = -3,
+	GPIO_INVALID_PARAMETER = -4,
+	GPIO_REQUEST_NOT_APPLICABLE = -5,
+	GPIO_REQUEST_PENDING = -6,
+	GPIO_NOT_CONFIGURED = -7,
+	GPIO_INTERNAL_ERROR = -8,
+	GPIO_INTERNAL_EVENT = 1,
+	GPIO_REMAINING_EVENT = 2,
+	GPIO_NO_MORE_PENDING_EVENT = 3,
+	GPIO_INVALID_CLIENT = -25,
+	GPIO_INVALID_PIN = -26,
+	GPIO_PIN_BUSY = -27,
+	GPIO_PIN_NOT_ALLOCATED = -28,
+	GPIO_WRONG_CLIENT = -29,
+	GPIO_UNSUPPORTED_ALTFUNC = -30,
+};
+
+/*GPIO DEVICE ID */
+enum gpio_device_id {
+	GPIO_DEVICE_ID_0,
+	GPIO_DEVICE_ID_1,
+	GPIO_DEVICE_ID_2,
+	GPIO_DEVICE_ID_3,
+	GPIO_DEVICE_ID_INVALID
+};
+
+/*
+ * Alternate Function:
+ *  refered in altfun_table to pointout particular altfun to be enabled
+ *  when using GPIO_ALT_FUNCTION A/B/C enable/disable operation
+ */
+enum gpio_alt_function {
+	GPIO_ALT_UART_0_MODEM,
+	GPIO_ALT_UART_0_NO_MODEM,
+	GPIO_ALT_UART_1,
+	GPIO_ALT_UART_2,
+	GPIO_ALT_I2C_0,
+	GPIO_ALT_I2C_1,
+	GPIO_ALT_I2C_2,
+	GPIO_ALT_I2C_3,
+	GPIO_ALT_MSP_0,
+	GPIO_ALT_MSP_1,
+	GPIO_ALT_MSP_2,
+	GPIO_ALT_MSP_3,
+	GPIO_ALT_MSP_4,
+	GPIO_ALT_MSP_5,
+	GPIO_ALT_SSP_0,
+	GPIO_ALT_SSP_1,
+	GPIO_ALT_MM_CARD0,
+	GPIO_ALT_SD_CARD0,
+	GPIO_ALT_DMA_0,
+	GPIO_ALT_DMA_1,
+	GPIO_ALT_HSI0,
+	GPIO_ALT_CCIR656_INPUT,
+	GPIO_ALT_CCIR656_OUTPUT,
+	GPIO_ALT_LCD_PANEL,
+	GPIO_ALT_MDIF,
+	GPIO_ALT_SDRAM,
+	GPIO_ALT_HAMAC_AUDIO_DBG,
+	GPIO_ALT_HAMAC_VIDEO_DBG,
+	GPIO_ALT_CLOCK_RESET,
+	GPIO_ALT_TSP,
+	GPIO_ALT_IRDA,
+	GPIO_ALT_USB_MINIMUM,
+	GPIO_ALT_USB_I2C,
+	GPIO_ALT_OWM,
+	GPIO_ALT_PWL,
+	GPIO_ALT_FSMC,
+	GPIO_ALT_COMP_FLASH,
+	GPIO_ALT_SRAM_NOR_FLASH,
+	GPIO_ALT_FSMC_ADDLINE_0_TO_15,
+	GPIO_ALT_SCROLL_KEY,
+	GPIO_ALT_MSHC,
+	GPIO_ALT_HPI,
+	GPIO_ALT_USB_OTG,
+	GPIO_ALT_SDIO,
+	GPIO_ALT_HSMMC,
+	GPIO_ALT_FSMC_ADD_DATA_0_TO_25,
+	GPIO_ALT_HSI1,
+	GPIO_ALT_NOR,
+	GPIO_ALT_NAND,
+	GPIO_ALT_KEYPAD,
+	GPIO_ALT_VPIP,
+	GPIO_ALT_CAM,
+	GPIO_ALT_CCP1,
+	GPIO_ALT_EMMC,
+	GPIO_ALT_POP_EMMC,
+	GPIO_ALT_FUNMAX		/* Add new alt func before this */
+};
+
+/* Defines pin assignment(Software mode or Alternate mode) */
+enum gpio_mode {
+	GPIO_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_MODE_SOFTWARE,	/* Pin connected to GPIO (SW controlled) */
+	GPIO_ALTF_A,		/* Pin connected to altfunc 1 (HW periph 1) */
+	GPIO_ALTF_B,		/* Pin connected to altfunc 2 (HW periph 2) */
+	GPIO_ALTF_C,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_FIND,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_DISABLE	/* Pin connected to altfunc 3 (HW periph 3) */
+};
+
+/* Defines GPIO pin direction */
+enum gpio_direction {
+	GPIO_DIR_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_DIR_INPUT,		/* GPIO set as input */
+	GPIO_DIR_OUTPUT		/* GPIO set as output */
+};
+
+/* Interrupt trigger mode */
+enum gpio_trig {
+	GPIO_TRIG_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_TRIG_DISABLE,	/* Trigger no IT */
+	GPIO_TRIG_RISING_EDGE,	/* Trigger an IT on rising edge */
+	GPIO_TRIG_FALLING_EDGE,	/* Trigger an IT on falling edge */
+	GPIO_TRIG_BOTH_EDGES,	/* Trigger an IT on rising and falling edge */
+	GPIO_TRIG_HIGH_LEVEL,	/* Trigger an IT on high level */
+	GPIO_TRIG_LOW_LEVEL	/* Trigger an IT on low level */
+};
+
+/* Configuration parameters for one GPIO pin.*/
+struct gpio_config {
+	enum gpio_mode mode;
+	enum gpio_direction direction;
+	enum gpio_trig trig;
+	char *dev_name;		/* Who owns the gpio pin */
+};
+
+/* GPIO pin data*/
+enum gpio_data {
+	GPIO_DATA_LOW,
+	GPIO_DATA_HIGH
+};
+
+/* GPIO behaviour in sleep mode */
+enum gpio_sleep_mode {
+	GPIO_SLEEP_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,	/* GPIO is an input with pull
+						   up/down enabled when in sleep
+						   mode. */
+	GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO	/* GPIO pin is controlled by
+						   GPIO IP. So mode, direction
+						   and data values for GPIO pin
+						   in sleep mode are determined
+						   by configuration set to GPIO
+						   pin before entering to sleep
+						   mode. */
+};
+
+/* GPIO ability to wake the system up from sleep mode.*/
+enum gpio_wake {
+	GPIO_WAKE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_WAKE_DISABLE,	/* No wake of system from sleep mode. */
+	GPIO_WAKE_LOW_LEVEL,	/* Wake the system up on a LOW level. */
+	GPIO_WAKE_HIGH_LEVEL,	/* Wake the system up on a HIGH level. */
+	GPIO_WAKE_RISING_EDGE,	/* Wake the system up on a RISING edge. */
+	GPIO_WAKE_FALLING_EDGE,	/* Wake the system up on a FALLING edge. */
+	GPIO_WAKE_BOTH_EDGES	/* Wake the system up on both RISE and FALL. */
+};
+
+/* Configuration parameters for one GPIO pin in sleep mode.*/
+struct gpio_sleep_config {
+	enum gpio_sleep_mode sleep_mode;/* GPIO behaviour in sleep mode. */
+	enum gpio_wake wake;		/* GPIO ability to wake up system. */
+};
+
+extern int gpio_setpinconfig(int pin_id, struct gpio_config *pin_config);
+extern int gpio_resetpinconfig(int pin_id, char *dev_name);
+extern int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name);
+extern int gpio_readpin(int pin_id, enum gpio_data *value);
+extern int gpio_altfuncenable(enum gpio_alt_function altfunc,
+				      char *dev_name);
+extern int gpio_altfuncdisable(enum gpio_alt_function altfunc,
+				       char *dev_name);
+
+struct gpio_altfun_data {
+	u16 altfun;
+	u16 start;
+	u16 end;
+	u16 cont;
+	u8 type;
+};
+#endif
diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h
new file mode 100644
index 0000000..6bb95ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/hardware.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Peripheral clusters */
+
+#define U8500_PER3_BASE		0x80000000
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_PER4_BASE		0x80150000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER7_BASE		0xa03d0000
+#define U8500_PER5_BASE		0xa03e0000
+
+/* GPIO */
+
+#define U8500_GPIO0_BASE	(U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO2_BASE	(U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xE000 + 0x80)
+#define U8500_GPIO4_BASE	(U8500_PER3_BASE + 0xE000 + 0x100)
+#define U8500_GPIO5_BASE	(U8500_PER3_BASE + 0xE000 + 0x180)
+
+#define U8500_GPIO6_BASE	(U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO7_BASE	(U8500_PER2_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO8_BASE	(U8500_PER5_BASE + 0x1E000)
+
+/* Per7 */
+#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* Per6 */
+#define U8500_MTU0_BASE_V1	(U8500_PER6_BASE + 0x6000)
+#define U8500_MTU1_BASE_V1	(U8500_PER6_BASE + 0x7000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+
+/* Per5 */
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+
+/* Per4 */
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x0f000)
+
+/* Per3 */
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+
+/* Per2 */
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* Per1 */
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+
+/* Last page of Boot ROM */
+#define U8500_BOOTROM_BASE      0x9001f000
+#define U8500_BOOTROM_ASIC_ID_OFFSET    0x0ff4
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-u8500/sys_proto.h b/arch/arm/include/asm/arch-u8500/sys_proto.h
new file mode 100644
index 0000000..eb9c782
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void gpio_init(void);
+void arm_pl180_mmci_init(void);
+
+
+#endif  /* _SYS_PROTO_H_ */
diff --git a/arch/arm/include/asm/arch-u8500/u8500.h b/arch/arm/include/asm/arch-u8500/u8500.h
new file mode 100644
index 0000000..0d6dbb7
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/u8500.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __U8500_H
+#define __U8500_H
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   Management Unit */
+#define CFG_SDRAMC_BASE		0x903CF000	/* SDRAMC cnf registers */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+/*
+ * U8500 GPIO register base for 9 banks
+ */
+#define U8500_GPIO_0_BASE			0x8012E000
+#define U8500_GPIO_1_BASE			0x8012E080
+#define U8500_GPIO_2_BASE			0x8000E000
+#define U8500_GPIO_3_BASE			0x8000E080
+#define U8500_GPIO_4_BASE			0x8000E100
+#define U8500_GPIO_5_BASE			0x8000E180
+#define U8500_GPIO_6_BASE			0x8011E000
+#define U8500_GPIO_7_BASE			0x8011E080
+#define U8500_GPIO_8_BASE			0xA03FE000
+
+#endif	/* __U8500_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (7 preceding siblings ...)
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-04-02 16:19 ` John Rigby
  2011-04-04  5:45   ` Heiko Schocher
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
  9 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-02 16:19 UTC (permalink / raw)
  To: u-boot

From: Michael Brandt <michael.brandt@stericsson.com>

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Heiko Schocher <hs@denx.de>
---
v2: Incorporate suggestions from Heiko Schocher

 drivers/i2c/Makefile    |    1 +
 drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
 3 files changed, 808 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..43507fc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
new file mode 100644
index 0000000..ea8a71d
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Basic U-Boot I2C interface for STn8500/DB8500
+ * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Only 7-bit I2C device addresses are supported.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "u8500_i2c.h"
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#define U8500_I2C_ENDAD_COUNTER	(CONFIG_SYS_HZ/100)	/* I2C bus timeout */
+#define U8500_I2C_FIFO_FLUSH_COUNTER	500000		/* flush "timeout" */
+#define U8500_I2C_SCL_FREQ		100000		/* I2C bus clock freq */
+#define U8500_I2C_INPUT_FREQ		48000000	/* Input clock freq */
+#define TX_FIFO_THRESHOLD	0x4
+#define RX_FIFO_THRESHOLD	0x4
+#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
+
+#define WRITE_FIELD(var, mask, shift, value) \
+			(var = ((var & ~(mask)) | ((value) << (shift))))
+
+static unsigned int bus_initialized[CONFIG_SYS_U8500_I2C_BUS_MAX];
+static unsigned int i2c_bus_num;
+static unsigned int i2c_bus_speed[] = {
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
+};
+static struct u8500_i2c_regs *i2c_dev[] = {
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C0_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C1_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C2_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C3_BASE,
+};
+
+static struct {
+	int periph;
+	int pcken;
+	int kcken;
+} i2c_clock_bits[] = {
+	{3, 3, 3}, /* I2C0 */
+	{1, 2, 2}, /* I2C1 */
+	{1, 6, 6}, /* I2C2 */
+	{2, 0, 0}, /* I2C3 */
+};
+
+static void i2c_set_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) | mask, reg);
+}
+
+static void i2c_clr_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) & ~mask, reg);
+}
+
+static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
+{
+	writel((readl(reg) & ~mask) | (value << shift), reg);
+}
+
+static int __i2c_set_bus_speed(unsigned int speed)
+{
+	u32 value;
+	struct u8500_i2c_regs *i2c_regs;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Select standard (100 kbps) speed mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_SM,
+			U8500_I2C_CR_SHIFT_SM, 0x0);
+
+	/*
+	 * Set the Baud Rate Counter 2 value
+	 * Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
+	 * Foncycle = 0 (no digital filtering)
+	 */
+	value = (u32) (U8500_I2C_INPUT_FREQ / (speed * 2));
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT2,
+			U8500_I2C_BRCR_SHIFT_BRCNT2, value);
+
+	/* ensure that BRCNT value is zero */
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT1,
+			U8500_I2C_BRCR_SHIFT_BRCNT1, 0);
+
+	return U8500_I2C_INPUT_FREQ/(value * 2);
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *
+ *	speed: bus speed (in HZ)
+ *	slaveaddr: address of device in slave mode
+ *
+ *	Slave mode is not implemented.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+	struct u8500_i2c_regs *i2c_regs;
+
+	debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
+
+	u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
+			   i2c_clock_bits[i2c_bus_num].pcken,
+			   i2c_clock_bits[i2c_bus_num].kcken);
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Disable the controller */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	/* Clear registers */
+	writel(0, &i2c_regs->cr);
+	writel(0, &i2c_regs->scr);
+	writel(0, &i2c_regs->hsmcr);
+	writel(0, &i2c_regs->tftr);
+	writel(0, &i2c_regs->rftr);
+	writel(0, &i2c_regs->dmar);
+
+	i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
+
+	/*
+	 * Set our own address.
+	 * Set slave address mode to 7 bit addressing mode
+	 */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_SAM);
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_ADDR,
+			U8500_I2C_SCR_SHIFT_ADDR, slaveaddr);
+	/* Slave Data Set up Time */
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_DATA_SETUP_TIME,
+			U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
+
+	/* Disable the DMA sync logic */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_DMA_SLE,
+			U8500_I2C_CR_SHIFT_DMA_SLE, 0);
+
+	/* Disable interrupts */
+	writel(0, &i2c_regs->imscr);
+
+	/* Configure bus master mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_OM, U8500_I2C_CR_SHIFT_OM,
+			U8500_I2C_BUS_MASTER_MODE);
+	/* Set FIFO threshold values */
+	writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
+	writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
+
+	/* Enable the I2C Controller */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	bus_initialized[i2c_bus_num] = 1;
+}
+
+
+/*
+ * loop_till_bit_clear - polls on a bit till it clears
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) == 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_clear timed out\n");
+	return -1;
+}
+
+/*
+ * loop_till_bit_set - polls on a bit till it is set.
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) != 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_set timed out\n");
+	return -1;
+}
+
+/*
+ * flush_fifo - flush the I2C TX and RX FIFOs
+ */
+static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
+{
+	int counter = U8500_I2C_FIFO_FLUSH_COUNTER;
+
+	/* Flush Tx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FTX);
+	/* Flush Rx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FRX);
+	while (counter--) {
+		if (!(readl(&i2c_regs->cr) &
+				(U8500_I2C_CR_FTX | U8500_I2C_CR_FRX)))
+			break;
+	}
+	return;
+}
+
+#ifdef DEBUG
+static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
+{
+	int cause;
+
+	printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
+	cause = (readl(&i2c_regs->sr) & U8500_I2C_SR_CAUSE) >>
+				U8500_I2C_SR_SHIFT_CAUSE;
+	switch (cause) {
+	case U8500_I2C_NACK_ADDR:
+		printf("No Ack received after Slave Address xmission\n");
+		break;
+	case U8500_I2C_NACK_DATA:
+		printf("Valid for MASTER_WRITE: No Ack received "
+				"during data phase\n");
+		break;
+	case U8500_I2C_ACK_MCODE:
+		printf("Master recv ack after xmission of master code"
+				"in hs mode\n");
+		break;
+	case U8500_I2C_ARB_LOST:
+		printf("Master Lost arbitration\n");
+		break;
+	case U8500_I2C_BERR_START:
+		printf("Slave restarts\n");
+		break;
+	case U8500_I2C_BERR_STOP:
+		printf("Slave reset\n");
+		break;
+	case U8500_I2C_OVFL:
+		printf("Overflow\n");
+		break;
+	default:
+		printf("Unknown error type\n");
+	}
+}
+#endif
+
+/*
+ * i2c_abort - called when a I2C transaction failed
+ */
+static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
+{
+#ifdef DEBUG
+	print_abort_reason(i2c_regs);
+#endif
+	/* flush RX and TX fifos */
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
+}
+
+/*
+ * write addr, alias index, to I2C bus.
+ */
+static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
+{
+	while (alen--) {
+		/* Wait until the Tx Fifo is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER)) {
+			i2c_abort(i2c_regs);
+			return -1;
+		}
+
+		/* MSB first */
+		writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
+	}
+
+	return 0;
+}
+
+/*
+ * Internal simplified read function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   value:	Where to put the data
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
+		uint addr, int alen, uchar *value)
+{
+	u32   mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	if (alen != 0) {
+		/* Master write operation */
+		mcr &= ~(U8500_I2C_MCR_OP);
+
+		/* Configure the Frame length to one byte */
+		WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH,
+				U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+		/* Repeated start, no stop */
+		mcr &= ~(U8500_I2C_MCR_STOP);
+
+		/* Write Master Control Register */
+		writel(mcr, &i2c_regs->mcr);
+
+		/* send addr/index */
+		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+			return -1;
+
+		/* Check for the Master Transaction Done Without Stop */
+		if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTDWS,
+					U8500_I2C_ENDAD_COUNTER)) {
+			return -1;
+		}
+
+		/* Acknowledge the Master Transaction Done Without Stop */
+		i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+	}
+
+	/* Master control configuration for read operation  */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Configure the STOP condition, we read only one byte */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Set the frame length to one byte, we support only 1 byte reads */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	i2c_write_field(&i2c_regs->mcr, U8500_I2C_MCR_LENGTH_STOP_OP,
+			U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
+
+	/*
+	 * receive_data_polling
+	 */
+
+	/* Wait until the Rx FIFO is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Read the data byte from Rx FIFO */
+	*value = readb(&i2c_regs->rfr);
+
+	/* Wait until the work is done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr, U8500_I2C_INT_MTD,
+				U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* If MTD is set, Master Transaction Done Without Stop is set too */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Internal simplified write function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   data:	Where to read the data
+ *   len:	How many bytes to write
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
+		int alen, u8 *data, int len)
+{
+	int i;
+	u32 mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Write operation */
+	mcr &= ~(U8500_I2C_MCR_OP);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Frame length: addr byte + len */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH,
+			(alen + len));
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+		return -1;
+
+	for (i = 0; i < len; i++) {
+		/* Wait until the Tx FIFO is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER))
+			return -1;
+
+		/* it is a 32 bit register with upper 24 reserved R/O */
+		writeb(data[i], &i2c_regs->tfr);
+	}
+
+	/* Check for Master Transaction Done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTD,
+					U8500_I2C_ENDAD_COUNTER)) {
+		printf("i2c_write_byte error2: risr %08x\n",
+				i2c_regs->risr);
+		return -1;
+	}
+
+	/* Acknowledge Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Probe the given I2C chip address. Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(uchar chip)
+{
+	u32 mcr = 0;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (chip == CONFIG_SYS_I2C_SLAVE)
+		return 1;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A10, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Read operation */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Set the frame length to one byte */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	/* Wait until the Rx Fifo is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER)) {
+		i2c_abort(i2c_regs);
+		return -1;
+	}
+
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Read/Write interface:
+ *   chip:    I2C chip address, range 0..127
+ *   addr:    Memory (register) address within the chip
+ *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:  Where to read/write the data
+ *   len:     How many bytes to read/write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int i;
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (alen > 2) {
+		debug("I2C read: addr len %d not supported\n", alen);
+		return 1;
+	}
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	for (i = 0; i < len; i++) {
+		rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
+		if (rc != 0) {
+			debug("I2C read: I/O error: %d\n", rc);
+			i2c_abort(i2c_regs);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
+			len);
+	if (rc != 0) {
+		debug("I2C write: I/O error\n");
+		i2c_abort(i2c_regs);
+		return rc;
+	}
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if (bus > ARRAY_SIZE(i2c_dev) - 1) {
+		debug("i2c_set_bus_num: only up to bus %d supported\n",
+				ARRAY_SIZE(i2c_dev)-1);
+		return -1;
+	}
+
+	i2c_bus_num = bus;
+
+	if (!bus_initialized[i2c_bus_num])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+
+	if (speed > U8500_I2C_MAX_STANDARD_SCL) {
+		debug("i2c_set_bus_speed: only up to %d supported\n",
+				U8500_I2C_MAX_STANDARD_SCL);
+		return -1;
+	}
+
+	/* sets as side effect i2c_bus_speed[i2c_bus_num] */
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return i2c_bus_num;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+	return i2c_bus_speed[i2c_bus_num];
+}
diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
new file mode 100644
index 0000000..881dcc5
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _U8500_I2C_H_
+#define _U8500_I2C_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/u8500.h>
+
+struct u8500_i2c_regs {
+	u32 cr;			/* Control Register                      0x00 */
+	u32 scr;		/* Slave Address Register                0x04 */
+	u32 hsmcr;		/* HS Master code Register               0x08 */
+	u32 mcr;		/* Master Control Register               0x0C */
+	u32 tfr;		/* Transmit Fifo Register                0x10 */
+	u32 sr;			/* Status Register                       0x14 */
+	u32 rfr;		/* Receiver Fifo Register                0x18 */
+	u32 tftr;		/* Transmit Fifo Threshold Register      0x1C */
+	u32 rftr;		/* Receiver Fifo Threshold Register      0x20 */
+	u32 dmar;		/* DMA register                          0x24 */
+	u32 brcr;		/* Baud Rate Counter Register            0x28 */
+	u32 imscr;		/* Interrupt Mask Set and Clear Register 0x2C */
+	u32 risr;		/* Raw interrupt status register         0x30 */
+	u32 misr;		/* Masked interrupt status register      0x34 */
+	u32 icr;		/* Interrupt Set and Clear Register      0x38 */
+	u32 reserved_1[(0xFE0 - 0x3c) >> 2];	/* Reserved 0x03C to 0xFE0 */
+	u32 periph_id_0;	/* peripheral ID 0			0xFE0 */
+	u32 periph_id_1;	/* peripheral ID 1			0xFE4 */
+	u32 periph_id_2;	/* peripheral ID 2			0xFE8 */
+	u32 periph_id_3;	/* peripheral ID 3			0xFEC */
+	u32 cell_id_0;		/* I2C cell   ID 0			0xFF0 */
+	u32 cell_id_1;		/* I2C cell   ID 1			0xFF4 */
+	u32 cell_id_2;		/* I2C cell   ID 2			0xFF8 */
+	u32 cell_id_3;		/* I2C cell   ID 3			0xFFC */
+};
+
+
+/* Control Register */
+
+/* Mask values for control register mask */
+#define U8500_I2C_CR_PE          0x0001	/* Peripheral enable */
+#define U8500_I2C_CR_OM          0x0006	/* Operation mode */
+#define U8500_I2C_CR_SAM         0x0008	/* Slave Addressing mode */
+#define U8500_I2C_CR_SM          0x0030	/* Speed mode */
+#define U8500_I2C_CR_SGCM        0x0040	/* Slave General call mode */
+#define U8500_I2C_CR_FTX         0x0080	/* Flush Transmit */
+#define U8500_I2C_CR_FRX         0x0100	/* Flush Receive */
+#define U8500_I2C_CR_DMA_TX_EN   0x0200	/* DMA TX Enable */
+#define U8500_I2C_CR_DMA_RX_EN   0x0400	/* DMA Rx Enable */
+#define U8500_I2C_CR_DMA_SLE     0x0800	/* DMA Synchronization Logic enable */
+#define U8500_I2C_CR_LM          0x1000	/* Loop back mode */
+#define U8500_I2C_CR_FON         0x6000	/* Filtering On */
+
+/* shift valus for control register bit fields */
+#define U8500_I2C_CR_SHIFT_PE		0	/* Peripheral enable */
+#define U8500_I2C_CR_SHIFT_OM		1	/* Operation mode */
+#define U8500_I2C_CR_SHIFT_SAM		3	/* Slave Addressing mode */
+#define U8500_I2C_CR_SHIFT_SM		4	/* Speed mode */
+#define U8500_I2C_CR_SHIFT_SGCM		6	/* Slave General call mode */
+#define U8500_I2C_CR_SHIFT_FTX		7	/* Flush Transmit */
+#define U8500_I2C_CR_SHIFT_FRX		8	/* Flush Receive */
+#define U8500_I2C_CR_SHIFT_DMA_TX_EN	9	/* DMA TX Enable */
+#define U8500_I2C_CR_SHIFT_DMA_RX_EN	10	/* DMA Rx Enable */
+#define U8500_I2C_CR_SHIFT_DMA_SLE	11	/* DMA Synch Logic enable */
+#define U8500_I2C_CR_SHIFT_LM		12	/* Loop back mode */
+#define U8500_I2C_CR_SHIFT_FON		13	/* Filtering On */
+
+/* bus operation modes */
+#define U8500_I2C_BUS_SLAVE_MODE		0
+#define U8500_I2C_BUS_MASTER_MODE		1
+#define U8500_I2C_BUS_MASTER_SLAVE_MODE	2
+
+
+/* Slave control register*/
+
+/* Mask values slave control register */
+#define U8500_I2C_SCR_ADDR                   0x3FF
+#define U8500_I2C_SCR_DATA_SETUP_TIME        0xFFFF0000
+
+/* Shift values for Slave control register */
+#define U8500_I2C_SCR_SHIFT_ADDR               0
+#define U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME    16
+
+
+/* Master Control Register */
+
+/* Mask values for Master control register */
+#define U8500_I2C_MCR_OP	0x00000001	/* Operation */
+#define U8500_I2C_MCR_A7	0x000000FE	/* LSB bits of Address */
+#define U8500_I2C_MCR_EA10	0x00000700	/* Extended Address */
+#define U8500_I2C_MCR_SB	0x00000800	/* Start byte procedure */
+#define U8500_I2C_MCR_AM	0x00003000	/* Address type */
+#define U8500_I2C_MCR_STOP	0x00004000	/* stop condition */
+#define U8500_I2C_MCR_LENGTH	0x03FF8000	/* Frame length */
+#define U8500_I2C_MCR_A10	0x000007FE	/* Enable 10 bit address */
+/* mask for length field,stop and operation  */
+#define U8500_I2C_MCR_LENGTH_STOP_OP	0x3FFC001
+
+/* Shift values for Master control values */
+#define U8500_I2C_MCR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_MCR_SHIFT_A7		1	/* LSB bits of Address */
+#define U8500_I2C_MCR_SHIFT_EA10	8	/* Extended Address */
+#define U8500_I2C_MCR_SHIFT_SB		11	/* Start byte procedure */
+#define U8500_I2C_MCR_SHIFT_AM		12	/* Address type */
+#define U8500_I2C_MCR_SHIFT_STOP	14	/* stop condition */
+#define U8500_I2C_MCR_SHIFT_LENGTH	15	/* Frame length */
+#define U8500_I2C_MCR_SHIFT_A10		1	/* Enable 10 bit address */
+
+#define U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP	0
+
+
+/* Status Register */
+
+/* Mask values for Status register */
+#define U8500_I2C_SR_OP	0x00000003	/* Operation */
+#define U8500_I2C_SR_STATUS	0x0000000C	/* Controller Status */
+#define U8500_I2C_SR_CAUSE	0x00000070	/* Abort Cause */
+#define U8500_I2C_SR_TYPE	0x00000180	/* Receive Type */
+#define U8500_I2C_SR_LENGTH	0x000FF700	/* Transfer length */
+
+/* Shift values for Status register */
+#define U8500_I2C_SR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_SR_SHIFT_STATUS	2	/* Controller Status */
+#define U8500_I2C_SR_SHIFT_CAUSE	4	/* Abort Cause */
+#define U8500_I2C_SR_SHIFT_TYPE	7	/* Receive Type */
+#define U8500_I2C_SR_SHIFT_LENGTH	9	/* Transfer length */
+
+/* abort cause */
+#define	U8500_I2C_NACK_ADDR	0
+#define	U8500_I2C_NACK_DATA	1
+#define	U8500_I2C_ACK_MCODE	2
+#define	U8500_I2C_ARB_LOST	3
+#define	U8500_I2C_BERR_START	4
+#define	U8500_I2C_BERR_STOP	5
+#define	U8500_I2C_OVFL	6
+
+
+/* Baud rate counter registers */
+
+/* Mask values for Baud rate counter register */
+#define U8500_I2C_BRCR_BRCNT2	0xFFFF		/* Baud Rate Cntr BRCR for HS */
+#define U8500_I2C_BRCR_BRCNT1	0xFFFF0000	/* BRCR for Standard and Fast */
+
+/* Shift values for the Baud rate counter register */
+#define U8500_I2C_BRCR_SHIFT_BRCNT2	0
+#define U8500_I2C_BRCR_SHIFT_BRCNT1	16
+
+
+/* Interrupt Register  */
+
+/* Mask values for Interrupt registers */
+#define U8500_I2C_INT_TXFE	0x00000001	/* Tx fifo empty */
+#define U8500_I2C_INT_TXFNE	0x00000002	/* Tx Fifo nearly empty */
+#define U8500_I2C_INT_TXFF	0x00000004	/* Tx Fifo Full */
+#define U8500_I2C_INT_TXFOVR	0x00000008	/* Tx Fifo over run */
+#define U8500_I2C_INT_RXFE	0x00000010	/* Rx Fifo Empty */
+#define U8500_I2C_INT_RXFNF	0x00000020	/* Rx Fifo nearly empty */
+#define U8500_I2C_INT_RXFF	0x00000040	/* Rx Fifo Full  */
+#define U8500_I2C_INT_RFSR	0x00010000	/* Read From slave request */
+#define U8500_I2C_INT_RFSE	0x00020000	/* Read from slave empty */
+#define U8500_I2C_INT_WTSR	0x00040000	/* Write to Slave request */
+#define U8500_I2C_INT_MTD	0x00080000	/* Master Transcation Done*/
+#define U8500_I2C_INT_STD	0x00100000	/* Slave Transaction Done */
+#define U8500_I2C_INT_MAL	0x01000000	/* Master Arbitation Lost */
+#define U8500_I2C_INT_BERR	0x02000000	/* Bus Error */
+#define U8500_I2C_INT_MTDWS	0x10000000	/* Master Transaction Done wo/ Stop */
+
+/* Max clocks (Hz) */
+#define U8500_I2C_MAX_STANDARD_SCL	100000
+#define U8500_I2C_MAX_FAST_SCL		400000
+#define U8500_I2C_MAX_HIGH_SPEED_SCL	3400000
+
+#endif	/* _U8500_I2C_H_ */
-- 
1.7.1

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

* [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
                   ` (8 preceding siblings ...)
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
@ 2011-04-02 16:19 ` John Rigby
  2011-04-11 18:09   ` Wolfgang Denk
  9 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-02 16:19 UTC (permalink / raw)
  To: u-boot

Based on ST-Ericsson private git repo.
Plus changes to use arm_pl180_mmci driver.

This board support requires the vexpress mmc driver patch set from
Matt Waddel.

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
v2: cleanup, mostly removal of unused defines and include files

 board/st-ericsson/u8500/Makefile     |   50 +++
 board/st-ericsson/u8500/gpio.c       |  347 +++++++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h   |   52 ++++
 board/st-ericsson/u8500/prcmu.c      |  165 ++++++++++
 board/st-ericsson/u8500/u8500_href.c |  546 ++++++++++++++++++++++++++++++++++
 boards.cfg                           |    1 +
 include/configs/u8500_href.h         |  243 +++++++++++++++
 7 files changed, 1404 insertions(+), 0 deletions(-)
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 include/configs/u8500_href.h

diff --git a/board/st-ericsson/u8500/Makefile b/board/st-ericsson/u8500/Makefile
new file mode 100644
index 0000000..91c2abf
--- /dev/null
+++ b/board/st-ericsson/u8500/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= u8500_href.o gpio.o prcmu.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/st-ericsson/u8500/gpio.c b/board/st-ericsson/u8500/gpio.c
new file mode 100644
index 0000000..96b2461
--- /dev/null
+++ b/board/st-ericsson/u8500/gpio.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+	(void *)U8500_GPIO_0_BASE,
+	(void *)U8500_GPIO_1_BASE,
+	(void *)U8500_GPIO_2_BASE,
+	(void *)U8500_GPIO_3_BASE,
+	(void *)U8500_GPIO_4_BASE,
+	(void *)U8500_GPIO_5_BASE,
+	(void *)U8500_GPIO_6_BASE,
+	(void *)U8500_GPIO_7_BASE,
+	(void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+	{
+		.altfun = GPIO_ALT_I2C_0,
+		.start = 147,
+		.end = 148,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_1,
+		.start = 16,
+		.end = 17,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_2,
+		.start = 10,
+		.end = 11,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_3,
+		.start = 229,
+		.end = 230,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 0,
+		.end = 3,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_1,
+		.start = 4,
+		.end = 7,
+		.cont = 0,
+		.type =
+			GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 18,
+		.end = 19,
+		.cont = 1,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 29,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 12,
+		.end = 17,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 21,
+		.end = 21,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_1,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_2,
+		.start = 192,
+		.end = 196,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 64,
+		.end = 93,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 150,
+		.end = 171,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_SD_CARD0,
+		.start = 18,
+		.end = 28,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MM_CARD0,
+		.start = 18,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_USB_OTG,
+		.start = 256,
+		.end = 267,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_EMMC,
+		.start = 197,
+		.end = 207,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_POP_EMMC,
+		.start = 128,
+		.end = 138,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	switch (config->mode) {
+	case GPIO_ALTF_A:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_B:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_C:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_MODE_SOFTWARE:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+		switch (config->direction) {
+		case GPIO_DIR_INPUT:
+			writel(mask, &p_gpio_register->gpio_dirc);
+			break;
+		case GPIO_DIR_OUTPUT:
+			writel(mask, &p_gpio_register->gpio_dirs);
+			break;
+		case GPIO_DIR_LEAVE_UNCHANGED:
+			break;
+		default:
+			return GPIO_INVALID_PARAMETER;
+		}
+
+		break;
+	case GPIO_MODE_LEAVE_UNCHANGED:
+		break;
+	default:
+		return GPIO_INVALID_PARAMETER;
+	}
+	return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	temp_reg = readl(&p_gpio_register->gpio_afsa);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsa);
+	temp_reg = readl(&p_gpio_register->gpio_afsb);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsb);
+	writel(mask, &p_gpio_register->gpio_dirc);
+
+	return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+			    int which_altfunc, char *dev_name)
+{
+	int i, j, start, end;
+	enum gpio_error error = -1;
+
+	for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+		if (altfun_table[i].altfun != alt_func)
+			continue;
+
+		start = altfun_table[i].start;
+		end = altfun_table[i].end;
+		for (j = start; j <= end; j++) {
+			if (which_altfunc == GPIO_ALTF_FIND)
+				altfun_pinconfig.mode = altfun_table[i].type;
+			else
+				altfun_pinconfig.mode = which_altfunc;
+			altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+			altfun_pinconfig.dev_name = dev_name;
+
+			if (which_altfunc != GPIO_ALTF_DISABLE)
+				error = gpio_setpinconfig(j, &altfun_pinconfig);
+			else
+				error = gpio_resetgpiopin(j, dev_name);
+			if (!error)
+				continue;
+			printf("GPIO %d configuration failure (nmdk_error:%d)",
+				j, error);
+			error = GPIO_INVALID_PARAMETER;
+			return error;
+		}
+
+		if (!altfun_table[i].cont)
+			break;
+	}
+	return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	switch (value) {
+	case GPIO_DATA_HIGH:
+		writel(mask, &p_gpio_register->gpio_dats);
+		break;
+	case GPIO_DATA_LOW:
+		writel(mask, &p_gpio_register->gpio_datc);
+		break;
+	default:
+		printf("Invalid value passed in %s", __FUNCTION__);
+		return GPIO_INVALID_PARAMETER;
+	}
+	return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+		*rv = GPIO_DATA_HIGH;
+	else
+		*rv = GPIO_DATA_LOW;
+	return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}
diff --git a/board/st-ericsson/u8500/prcmu-fw.h b/board/st-ericsson/u8500/prcmu-fw.h
new file mode 100644
index 0000000..59198f7
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu-fw.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __MACH_PRCMU_FW_V1_H
+#define __MACH_PRCMU_FW_V1_H
+
+#define AP_EXECUTE	2
+#define I2CREAD		1
+#define I2C_WR_OK	1
+#define I2C_RD_OK	2
+#define I2CWRITE	0
+
+#define _PRCMU_TCDM_BASE    U8500_PRCMU_TCDM_BASE
+#define PRCM_XP70_CUR_PWR_STATE (_PRCMU_TCDM_BASE + 0xFFC)      /* 4 BYTES */
+
+#define PRCM_REQ_MB5        (_PRCMU_TCDM_BASE + 0xE44)    /* 4 bytes  */
+#define PRCM_ACK_MB5        (_PRCMU_TCDM_BASE + 0xDF4)    /* 4 bytes */
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2COPTYPE_REG	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_BIT_FIELDS		(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2CSLAVE		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2CVAL		(PRCM_REQ_MB5 + 0x3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_SLAVE	(PRCM_ACK_MB5 + 0x2)
+#define PRCM_ACK_MB5_VAL	(PRCM_ACK_MB5 + 0x3)
+
+#define LOW_POWER_WAKEUP	1
+#define EXE_WAKEUP		0
+
+#define REQ_MB5			5
+
+#endif /* __MACH_PRCMU_FW_V1_H */
diff --git a/board/st-ericsson/u8500/prcmu.c b/board/st-ericsson/u8500/prcmu.c
new file mode 100644
index 0000000..6f9302f
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Adapted from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This currently does not support the I2C workaround access method.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "prcmu-fw.h"
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+
+static int prcmu_is_ready(void)
+{
+	int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
+	if (!ready)
+		printf("PRCMU firmware not ready\n");
+	return ready;
+}
+
+static int _wait_for_req_complete(int num)
+{
+	int timeout = 1000;
+
+	/* checking any already on-going transaction */
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	timeout = 1000;
+
+	/* Set an interrupt to XP70 */
+	writel(1 << num, PRCM_MBOX_CPU_SET);
+
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	if (!timeout) {
+		printf("PRCMU operation timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db8500 register to be accessed
+ * Returns: ACK_MB5  value containing the status
+ */
+int prcmu_i2c_read(u8 reg, u16 slave)
+{
+	uint8_t i2c_status;
+	uint8_t i2c_val;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(0, PRCM_REQ_MB5_I2CVAL);
+
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	i2c_val = readb(PRCM_ACK_MB5_VAL);
+
+	if (i2c_status == I2C_RD_OK)
+		return i2c_val;
+	else {
+
+		printf("prcmu_i2c_read:read return status= %d\n",
+				i2c_status);
+		return -1;
+	}
+
+}
+
+/**
+ * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db800 register to be written to
+ * @reg_data: - the data to write
+ * Returns: ACK_MB5 value containing the status
+ */
+int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
+{
+	uint8_t i2c_status;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
+
+	debug("\ncpu_is_u8500v11\n");
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	debug("\ni2c_status = %x\n", i2c_status);
+	if (i2c_status == I2C_WR_OK)
+		return 0;
+	else {
+		printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
+		return -1;
+	}
+}
diff --git a/board/st-ericsson/u8500/u8500_href.c b/board/st-ericsson/u8500/u8500_href.c
new file mode 100644
index 0000000..6663129
--- /dev/null
+++ b/board/st-ericsson/u8500/u8500_href.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+
+#define NOMADIK_PER4_BASE	(0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+/* Power, Reset, Clock Management Unit */
+/*
+ * SVA: Smart Video Accelerator
+ * SIA: Smart Imaging Accelerator
+ * SGA: Smart Graphic accelerator
+ * B2R2: Graphic blitter
+ */
+#define PRCMU_BASE	CFG_PRCMU_BASE	/* 0x80157000 for U8500 */
+#define PRCM_ARMCLKFIX_MGT_REG		(PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG		(PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG		(PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG		(PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG		(PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG		(PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG		(PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG		(PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG		(PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG		(PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG		(PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG		(PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG		(PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG		(PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG		(PRCMU_BASE + 0x074)
+#define PRCM_B2R2CLK_MGT_REG		(PRCMU_BASE + 0x078)
+
+#define PRCM_PLLSOC0_FREQ_REG		(PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ_REG		(PRCMU_BASE + 0x084)
+#define PRCM_PLLARM_FREQ_REG		(PRCMU_BASE + 0x088)
+#define PRCM_PLLDDR_FREQ_REG		(PRCMU_BASE + 0x08C)
+#define PRCM_ARM_CHGCLKREQ_REG		(PRCMU_BASE + 0x114)
+
+#define PRCM_TCR			(PRCMU_BASE + 0x1C8)
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR			0x80156000
+#define DMC_CTL_97			(DMC_BASE_ADDR + 0x184)
+
+int board_id;	/* set in board_late_init() */
+
+/* PLLs for clock management registers */
+enum {
+	GATED = 0,
+	PLLSOC0,	/* pllsw = 001, ffs() = 1 */
+	PLLSOC1,	/* pllsw = 010, ffs() = 2 */
+	PLLDDR,		/* pllsw = 100, ffs() = 3 */
+	PLLARM,
+};
+
+static struct pll_freq_regs {
+	int idx;	/* index fror pll_name and pll_khz arrays */
+	uint32_t addr;
+} pll_freq_regs[] = {
+	{PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
+	{PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
+	{PLLDDR, PRCM_PLLDDR_FREQ_REG},
+	{PLLARM, PRCM_PLLARM_FREQ_REG},
+	{0, 0},
+};
+
+static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
+static uint32_t pll_khz[5];	/* use ffs(pllsw(reg)) as index for 0..3 */
+
+static struct clk_mgt_regs {
+	uint32_t addr;
+	uint32_t val;
+	const char *descr;
+} clk_mgt_regs[] = {
+	/* register content taken from bootrom settings */
+	{PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+	{PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+	{PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+	{PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+	{PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},	/* dis, SOC0/4, 200 MHz */
+	{PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},	/* ena, GATED, CLK38 */
+	{PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},	/* dis, GATED, CLK38 */
+	{PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},	/* ena, SOC0/16, 50 MHz */
+	{PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+	{PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},	/* ena, SOC0/8, 100 MHz */
+	{PRCM_DMACLK_MGT_REG, 0x125, "DMA"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},	/* dis, SOC0/5, 160 MHz */
+	{0, 0, NULL},
+};
+
+static void init_regs(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+static unsigned int read_asicid(void)
+{
+	unsigned int *address = (void *)U8500_BOOTROM_BASE
+				+ U8500_BOOTROM_ASIC_ID_OFFSET;
+	return readl(address);
+}
+
+int cpu_is_u8500v11(void)
+{
+	return read_asicid() == 0x008500A1;
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_early_init_f(void)
+{
+	init_regs();
+	return 0;
+}
+
+int board_init(void)
+{
+	uint32_t unused_cols_rows;
+	unsigned int nrows;
+	unsigned int ncols;
+
+	gd->bd->bi_arch_number = 0x1A4;
+	gd->bd->bi_boot_params = 0x00000100;
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+
+	/*
+	 * Assumption: 2 CS active, both CS have same layout.
+	 *             15 rows max, 11 cols max (controller spec).
+	 *             memory chip has 8 banks, I/O width 32 bit.
+	 * The correct way would be to read MR#8: I/O width and density,
+	 * but this requires locking against the PRCMU firmware.
+	 * Simplified approach:
+	 * Read number of unused rows and columns from mem controller.
+	 * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+	 */
+	unused_cols_rows = readl(DMC_CTL_97);
+	nrows = 15 - (unused_cols_rows & 0x07);
+	ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+	gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+	icache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+	return 0;
+}
+
+unsigned int addr_vall_arr[] = {
+	0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8011F008, 0x00001CFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8000F000, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x8000F008, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x80157020, 0x00000150, /* I2C 48MHz clock */
+	0x8012F000, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0x8012F008, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0xA03DF000, 0x0000000D, /* Clock for MTU Timers */
+	0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */
+	0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */
+	0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */
+	0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x801571E4, 0x0000000C, /* PRCMU settings for B2R2,
+				   PRCM_APE_RESETN_SET_REG */
+	0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */
+	0xA03FF000, 0x00000003, /* USB */
+	0xA03FF008, 0x00000001, /* USB */
+	0xA03FE00C, 0x00000000, /* USB */
+	0xA03FE020, 0x00000FFF, /* USB */
+	0xA03FE024, 0x00000000	/* USB */
+};
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_MASK		0x3
+#define LDO_VAUX3_ENABLE	0x1
+#define VAUX3_VOLTAGE_2_9V	0xd
+
+#define AB8500_REGU_CTRL2	0x4
+#define AB8500_REGU_VRF1VAUX3_REGU_REG	0x040A
+#define AB8500_REGU_VRF1VAUX3_SEL_REG	0x0421
+
+extern int prcmu_i2c_read(u8 reg, u16 slave);
+extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
+
+static int hrefplus_mmc_power_init(void)
+{
+	int ret;
+	int val;
+
+	if (!cpu_is_u8500v11())
+		return 0;
+
+	/*
+	 * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
+	 * card to work.  This is done by enabling the regulators in the AB8500
+	 * via PRCMU I2C transactions.
+	 *
+	 * This code is derived from the handling of AB8500_LDO_VAUX3 in
+	 * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+	 *
+	 * Turn off and delay is required to have it work across soft reboots.
+	 */
+
+	ret = prcmu_i2c_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+	if (ret < 0)
+		goto out;
+
+	val = ret;
+
+	/* Turn off */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+				val & ~LDO_VAUX3_MASK);
+	if (ret < 0)
+		goto out;
+
+	udelay(10 * 1000);
+
+	/* Set the voltage to 2.9V */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_SEL_REG,
+				VAUX3_VOLTAGE_2_9V);
+	if (ret < 0)
+		goto out;
+
+	val = val & ~LDO_VAUX3_MASK;
+	val = val | LDO_VAUX3_ENABLE;
+
+	/* Turn on the supply */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+
+out:
+	return ret;
+}
+#endif
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+	uchar byte;
+
+	/*
+	 * Determine and set board_id environment variable
+	 * 0: mop500, 1: href500
+	 * Above boards have different GPIO expander chips which we can
+	 * distinguish by the chip id.
+	 *
+	 * The board_id environment variable is needed for the Linux bootargs.
+	 */
+	(void) i2c_set_bus_num(0);
+	(void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
+	if (byte == 0x01) {
+		board_id = 0;
+		setenv("board_id", "0");
+	} else {
+		board_id = 1;
+		setenv("board_id", "1");
+	}
+#ifdef CONFIG_MMC
+	hrefplus_mmc_power_init();
+
+	/*
+	 * config extended GPIO pins for level shifter and
+	 * SDMMC_ENABLE
+	 */
+	if (board_id == 0) {
+		/* MOP500 */
+		byte = 0x0c;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
+	} else {
+		/* HREF */
+		/* set the direction of GPIO KPY9 and KPY10 */
+		byte = 0x06;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
+		/* must be a multibyte access */
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
+						(uchar []) {0x06, 0x06}, 2);
+	}
+#endif /* CONFIG_MMC */
+	/*
+	 * Create a memargs variable which points uses either the memargs256 or
+	 * memargs512 environment variable, depending on the memory size.
+	 * memargs is used to build the bootargs, memargs256 and memargs512 are
+	 * stored in the environment.
+	 */
+	if (gd->bd->bi_dram[0].size == 0x10000000) {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
+		setenv("mem", "256M");
+	} else {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
+		setenv("mem", "512M");
+	}
+
+	return 0;
+}
+#endif /* BOARD_LATE_INIT */
+
+static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
+{
+	writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
+	writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
+}
+
+static void init_regs(void)
+{
+	/* FIXME Remove magic register array settings for ED also */
+	struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
+
+	/* Enable timers */
+	writel(1 << 17, &prcmu->tcr);
+
+	u8500_prcmu_enable(&prcmu->per1clk_mgt);
+	u8500_prcmu_enable(&prcmu->per2clk_mgt);
+	u8500_prcmu_enable(&prcmu->per3clk_mgt);
+	u8500_prcmu_enable(&prcmu->per5clk_mgt);
+	u8500_prcmu_enable(&prcmu->per6clk_mgt);
+	u8500_prcmu_enable(&prcmu->per7clk_mgt);
+
+	u8500_prcmu_enable(&prcmu->uartclk_mgt);
+	u8500_prcmu_enable(&prcmu->i2cclk_mgt);
+
+	u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
+
+	u8500_clock_enable(1, 9, -1);	/* GPIO0 */
+
+	u8500_clock_enable(2, 11, -1);	/* GPIO1 */
+
+	u8500_clock_enable(3, 8, -1);	/* GPIO2 */
+	u8500_clock_enable(5, 1, -1);	/* GPIO3 */
+
+	u8500_clock_enable(3, 6, 6);	/* UART2 */
+
+	gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
+	u8500_clock_enable(3, 3, 3);	/* I2C0 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
+	gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
+
+	u8500_clock_enable(1, 5, 5);	/* SDI0 */
+	u8500_clock_enable(2, 4, 2);	/* SDI4 */
+
+	u8500_clock_enable(6, 7, -1);	/* MTU0 */
+	u8500_clock_enable(3, 4, 4);	/* SDI2 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
+	gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+
+	/*
+	 * Enabling clocks for all devices which are AMBA devices in the
+	 * kernel.  Otherwise they will not get probe()'d because the
+	 * peripheral ID register will not be powered.
+	 */
+
+	/* XXX: some of these differ between ED/V1 */
+
+	u8500_clock_enable(1, 1, 1);	/* UART1 */
+	u8500_clock_enable(1, 0, 0);	/* UART0 */
+
+	u8500_clock_enable(3, 2, 2);	/* SSP1 */
+	u8500_clock_enable(3, 1, 1);	/* SSP0 */
+
+	u8500_clock_enable(2, 8, -1);	/* SPI0 */
+	u8500_clock_enable(2, 5, 3);	/* MSP2 */
+}
+
+#ifdef CONFIG_MMC
+static int u8500_mmci_board_init(void)
+{
+	enum gpio_error error;
+	struct gpio_register *gpio_base_address;
+
+	gpio_base_address = (void *)(U8500_GPIO_0_BASE);
+	gpio_base_address->gpio_dats |= 0xFFC0000;
+	gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+	/* save the GPIO0 AFSELA register */
+	error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+	if (error != GPIO_OK) {
+		printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int board_mmc_init(bd_t *bd)
+{
+	if (u8500_mmci_board_init())
+		return -ENODEV;
+
+	arm_pl180_mmci_init();
+	return 0;
+}
+#endif
+
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+	uint32_t idf, ldf, odf, seldiv, phi;
+
+	/*
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+	 * where:
+	 * IDF=R(2:0) (when R=000, IDF=1d)
+	 * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+	 * ODF = N(5:0) (when N=000000, 0DF=1d)
+	 */
+
+	idf = (freq_reg & 0x70000) >> 16;
+	ldf = (freq_reg & 0xff) * 2;
+	odf = (freq_reg & 0x3f00) >> 8;
+	seldiv = (freq_reg & 0x01000000) >> 24;
+	phi = (inclk_khz * ldf) / (2 * odf * idf);
+	if (seldiv)
+		phi = phi/2;
+
+	return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t inclk_khz;
+	uint32_t reg, phi;
+	uint32_t clk_khz;
+	unsigned int clk_sel;
+	struct clk_mgt_regs *clks = clk_mgt_regs;
+	struct pll_freq_regs *plls = pll_freq_regs;
+
+	/*
+	 * Go through list of PLLs.
+	 * Initialise pll out frequency array (pll_khz) and print frequency.
+	 */
+	inclk_khz = 38400;	/* 38.4 MHz */
+	while (plls->addr) {
+		reg = readl(plls->addr);
+		phi = get_pll_freq_khz(inclk_khz, reg);
+		pll_khz[plls->idx] = phi;
+		printf("%s PLL out frequency: %d.%d Mhz\n",
+				pll_name[plls->idx], phi/1000, phi % 1000);
+		plls++;
+	}
+
+	/* check ARM clock source */
+	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
+	printf("A9 running on ");
+	if (reg & 1)
+		printf("external clock");
+	else
+		printf("ARM PLL");
+	printf("\n");
+
+	/* go through list of clk_mgt_reg */
+	printf("\n%19s %9s %7s %9s enabled\n",
+			"name(addr)", "value", "PLL", "CLK[MHz]");
+	while (clks->addr) {
+		reg = readl(clks->addr);
+		/* convert bit position into array index */
+		clk_sel = ffs((reg >> 5) & 0x7);	/* PLLSW[2:0] */
+		printf("%9s(%08x): %08x", clks->descr, clks->addr, reg);
+		printf(", %6s", pll_name[clk_sel]);
+		if (reg & 0x200)
+			clk_khz = 38400;	/* CLK38 is set */
+		else if ((reg & 0x1f) == 0)
+			/* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+			clk_khz = 0;
+		else
+			clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
+		printf(", %4d.%03d", clk_khz / 1000, clk_khz % 1000);
+		printf(", %s\n", (reg & 0x100) ? "ena" : "dis");
+		clks++;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clkinfo,	1,	1,	do_clkinfo,
+	"print clock info",
+	""
+);
diff --git a/boards.cfg b/boards.cfg
index 999c473..9e5c068 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -132,6 +132,7 @@ smdkc100                     arm         armv7       smdkc100            samsung
 s5pc210_universal            arm         armv7       universal_c210      samsung        s5pc2xx
 harmony                      arm         armv7       harmony             nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
+u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 actux1                       arm         ixp
 actux2                       arm         ixp
 actux3                       arm         ixp
diff --git a/include/configs/u8500_href.h b/include/configs/u8500_href.h
new file mode 100644
index 0000000..ee58d2a
--- /dev/null
+++ b/include/configs/u8500_href.h
@@ -0,0 +1,243 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_U8500		1
+#define CONFIG_L2_OFF		1
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF
+#define CONFIG_SYS_HZ		1000		/* must be 1000 */
+
+#define CONFIG_BOARD_EARLY_INIT_F	1
+#define BOARD_LATE_INIT		1
+
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE		(32*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE		(128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* for initial data */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE		0x80120000
+#define CFG_UART1_BASE		0x80121000
+#define CFG_UART2_BASE		0x80007000
+#define CFG_SERIAL0		CFG_UART0_BASE
+#define CFG_SERIAL1		CFG_UART1_BASE
+#define CFG_SERIAL2		CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK	38400000
+#define CONFIG_PL01x_PORTS	{ (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+				  (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC		1
+#define CONFIG_GENERIC_MMC	1
+#define CONFIG_DOS_PARTITION	1
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY	1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=n\0"							\
+	"loadaddr=0x00100000\0"						\
+	"console=ttyAMA2,115200n8\0"					\
+	"memargs256=mem=96M at 0 mem_modem=32M at 96M mem=30M at 128M "		\
+		"pmem=22M at 158M pmem_hwb=44M at 180M mem_mali=32 at 224M\0"	\
+	"memargs512=mem=96M at 0 mem_modem=32M at 96M mem=44M at 128M "		\
+		"pmem=22M at 172M mem=30M at 194M mem_mali=32M at 224M "		\
+		"pmem_hwb=54M at 256M mem=202M at 310M\0"			\
+	"commonargs=setenv bootargs cachepolicy=writealloc noinitrd "	\
+		"init=init "						\
+		"board_id=${board_id} "					\
+		"logo.${logo} "						\
+		"startup_graphics=${startup_graphics}\0"		\
+	"emmcargs=setenv bootargs ${bootargs} "				\
+		"root=/dev/mmcblk0p2 "					\
+		"rootdelay=1\0"						\
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console}\0"					\
+	"emmcboot=echo Booting from eMMC ...; "				\
+		"run commonargs emmcargs addcons memargs;"		\
+		"mmc read 0 ${loadaddr} 0xA0000 0x4000;"		\
+		"bootm ${loadaddr}\0"					\
+	"flash=mmc init 1;fatload mmc 1 ${loadaddr} flash.scr;"		\
+		"source ${loadaddr}\0"					\
+	"loaduimage=mmc init 1;fatload mmc 1 ${loadaddr} uImage\0"	\
+	"usbtty=cdc_acm\0"						\
+	"stdout=serial,usbtty\0"					\
+	"stdin=serial,usbtty\0"						\
+	"stderr=serial,usbtty\0"
+
+/*
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory     */
+#define CONFIG_SYS_PROMPT	"U8500 $ "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O Buffer Size  */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef	CONFIG_SYS_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR		0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE	1
+
+#define CONFIG_SYS_HUSH_PARSER		1
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS	2
+#define CONFIG_INITRD_TAG		1
+#define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs  */
+
+/*
+ * I2C
+ */
+#define CONFIG_U8500_I2C		1
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support */
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0	/* slave addr of controller */
+#define CONFIG_SYS_U8500_I2C0_BASE		0x80004000
+#define CONFIG_SYS_U8500_I2C1_BASE		0x80122000
+#define CONFIG_SYS_U8500_I2C2_BASE		0x80128000
+#define CONFIG_SYS_U8500_I2C3_BASE		0x80110000
+#define CONFIG_SYS_U8500_I2C_BUS_MAX		4
+
+#define CONFIG_SYS_I2C_GPIOE_ADDR	0x42	/* GPIO expander chip addr */
+#define CONFIG_TC35892_GPIO
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ		(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ		(4*1024)	/* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1		0x20000000	/* 512 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE            0x0
+#endif
+
+/*
+ * MMC related configs
+ * NB Only externa SD slot is currently supported
+ */
+#define MMC_BLOCK_SIZE			512
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x80126000	/* MMC base for 8500  */
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
+#define CONFIG_MMC_DEV_NUM		1
+
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_SAVEENV	/* CMD_ENV is obsolete but used in env_emmc.c */
+#define CONFIG_ENV_IS_IN_MMC		1
+#define CONFIG_ENV_OFFSET		0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV          0               /* SLOT2: eMMC */
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   management unit */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+#endif	/* __CONFIG_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
@ 2011-04-04  5:45   ` Heiko Schocher
  0 siblings, 0 replies; 42+ messages in thread
From: Heiko Schocher @ 2011-04-04  5:45 UTC (permalink / raw)
  To: u-boot

Hello John,

John Rigby wrote:
> From: Michael Brandt <michael.brandt@stericsson.com>
> 
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> CC: Heiko Schocher <hs@denx.de>
> ---
> v2: Incorporate suggestions from Heiko Schocher

Thanks, one nitpicking comment...

> 
>  drivers/i2c/Makefile    |    1 +
>  drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
>  3 files changed, 808 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/i2c/u8500_i2c.c
>  create mode 100644 drivers/i2c/u8500_i2c.h
> 
[...]
> diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
> new file mode 100644
> index 0000000..881dcc5
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.h
[...]
> +/* Mask values for Interrupt registers */
> +#define U8500_I2C_INT_TXFE	0x00000001	/* Tx fifo empty */
> +#define U8500_I2C_INT_TXFNE	0x00000002	/* Tx Fifo nearly empty */
> +#define U8500_I2C_INT_TXFF	0x00000004	/* Tx Fifo Full */
> +#define U8500_I2C_INT_TXFOVR	0x00000008	/* Tx Fifo over run */
> +#define U8500_I2C_INT_RXFE	0x00000010	/* Rx Fifo Empty */
> +#define U8500_I2C_INT_RXFNF	0x00000020	/* Rx Fifo nearly empty */
> +#define U8500_I2C_INT_RXFF	0x00000040	/* Rx Fifo Full  */
> +#define U8500_I2C_INT_RFSR	0x00010000	/* Read From slave request */
> +#define U8500_I2C_INT_RFSE	0x00020000	/* Read from slave empty */
> +#define U8500_I2C_INT_WTSR	0x00040000	/* Write to Slave request */
> +#define U8500_I2C_INT_MTD	0x00080000	/* Master Transcation Done*/
> +#define U8500_I2C_INT_STD	0x00100000	/* Slave Transaction Done */
> +#define U8500_I2C_INT_MAL	0x01000000	/* Master Arbitation Lost */
> +#define U8500_I2C_INT_BERR	0x02000000	/* Bus Error */
> +#define U8500_I2C_INT_MTDWS	0x10000000	/* Master Transaction Done wo/ Stop */

Line over 80 characters.

[...]

Beside of that, it looks Ok to me.

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCHv2 0/4] ST-Ericsson U8500 support
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
@ 2011-04-11 17:33   ` John Rigby
  2011-04-11 19:52     ` Albert ARIBAUD
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 " John Rigby
                     ` (9 subsequent siblings)
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-11 17:33 UTC (permalink / raw)
  To: u-boot

On Sat, Apr 2, 2011 at 10:19 AM, John Rigby <john.rigby@linaro.org> wrote:
> Add support for ST-Ericsson U8500 SoC and HREF platform
>
> John Rigby (2):
> ?armv7: Add ST-Ericsson u8500 arch
> ?armv7: Add support for ST-Ericsson U8500 href platform
>
> Michael Brandt (1):
> ?I2C: add driver of st-ericsson u8500 i2c
>
> Rabin Vincent (1):
> ?p101x: extra init for u8500
>
> ?arch/arm/cpu/armv7/u8500/Makefile ? ? ? ? ? | ? 46 ++
> ?arch/arm/cpu/armv7/u8500/clock.c ? ? ? ? ? ?| ? 56 +++
> ?arch/arm/cpu/armv7/u8500/lowlevel.S ? ? ? ? | ? 33 ++
> ?arch/arm/cpu/armv7/u8500/timer.c ? ? ? ? ? ?| ?167 ++++++++
> ?arch/arm/include/asm/arch-u8500/clock.h ? ? | ? 72 ++++
> ?arch/arm/include/asm/arch-u8500/gpio.h ? ? ?| ?247 +++++++++++
> ?arch/arm/include/asm/arch-u8500/hardware.h ?| ? 83 ++++
> ?arch/arm/include/asm/arch-u8500/sys_proto.h | ? 29 ++
> ?arch/arm/include/asm/arch-u8500/u8500.h ? ? | ? 47 ++
> ?board/st-ericsson/u8500/Makefile ? ? ? ? ? ?| ? 50 +++
> ?board/st-ericsson/u8500/gpio.c ? ? ? ? ? ? ?| ?347 +++++++++++++++
> ?board/st-ericsson/u8500/prcmu-fw.h ? ? ? ? ?| ? 52 +++
> ?board/st-ericsson/u8500/prcmu.c ? ? ? ? ? ? | ?165 +++++++
> ?board/st-ericsson/u8500/u8500_href.c ? ? ? ?| ?546 ++++++++++++++++++++++++
> ?boards.cfg ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?drivers/i2c/Makefile ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?drivers/i2c/u8500_i2c.c ? ? ? ? ? ? ? ? ? ? | ?613 +++++++++++++++++++++++++++
> ?drivers/i2c/u8500_i2c.h ? ? ? ? ? ? ? ? ? ? | ?194 +++++++++
> ?drivers/serial/serial_pl01x.c ? ? ? ? ? ? ? | ? 10 +
> ?drivers/serial/serial_pl01x.h ? ? ? ? ? ? ? | ? ?4 +
> ?include/configs/u8500_href.h ? ? ? ? ? ? ? ?| ?243 +++++++++++
> ?21 files changed, 3006 insertions(+), 0 deletions(-)
> ?create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
> ?create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
> ?create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
> ?create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
> ?create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h
> ?create mode 100644 board/st-ericsson/u8500/Makefile
> ?create mode 100644 board/st-ericsson/u8500/gpio.c
> ?create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
> ?create mode 100644 board/st-ericsson/u8500/prcmu.c
> ?create mode 100644 board/st-ericsson/u8500/u8500_href.c
> ?create mode 100644 drivers/i2c/u8500_i2c.c
> ?create mode 100644 drivers/i2c/u8500_i2c.h
> ?create mode 100644 include/configs/u8500_href.h
>
>

Albert, Do you have any comments on this series?

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

* [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500 John Rigby
@ 2011-04-11 17:48   ` Wolfgang Denk
  0 siblings, 0 replies; 42+ messages in thread
From: Wolfgang Denk @ 2011-04-11 17:48 UTC (permalink / raw)
  To: u-boot

Dear John Rigby,

In message <1301761196-26072-2-git-send-email-john.rigby@linaro.org> you wrote:
> From: Rabin Vincent <rabin.vincent@stericsson.com>
> 
> empty fifo on init
> program receive line control register on u8500
> 
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> ---
> v2: no changes
> 
>  drivers/serial/serial_pl01x.c |   10 ++++++++++
>  drivers/serial/serial_pl01x.h |    4 ++++
>  2 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
> index 5dfcde8..22ada8f 100644
> --- a/drivers/serial/serial_pl01x.c
> +++ b/drivers/serial/serial_pl01x.c
> @@ -112,6 +112,12 @@ int serial_init (void)
>  	unsigned int remainder;
>  	unsigned int fraction;
>  
> +	/* Empty RX fifo if necessary */
> +	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
> +		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
> +			readl(&regs->dr);
> +	}

Does this affect other boards?


> +#ifdef CONFIG_U8500
> +	/* program receive line control register */
> +	writel(0x70, &regs->pl011_rlcr);
> +#endif

I would like to keep board specific code out of this file.

Can you identifiy under which speific circumstances this code is
needed, and add a feature-specific ifdef instead of a board specific
one?

> --- a/drivers/serial/serial_pl01x.h
> +++ b/drivers/serial/serial_pl01x.h
> @@ -43,7 +43,11 @@ struct pl01x_regs {
>  	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
>  	u32	pl010_cr;	/* 0x14 Control register */
>  	u32	fr;		/* 0x18 Flag register (Read only) */
> +#ifdef CONFIG_U8500
> +	u32	pl011_rlcr;	/* 0x1c Receive line control register */
> +#else
>  	u32	reserved;
> +#endif

Ditto.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Those who do not  understand  Unix  are  condemned  to  reinvent  it,
poorly.              - Henry Spencer, University of Toronto Unix hack

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

* [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-03-22 20:40 ` [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-04-11 18:04   ` Wolfgang Denk
  0 siblings, 0 replies; 42+ messages in thread
From: Wolfgang Denk @ 2011-04-11 18:04 UTC (permalink / raw)
  To: u-boot

Dear John Rigby,

In message <1300826419-18632-3-git-send-email-john.rigby@linaro.org> you wrote:
> From: Rabin Vincent <rabin.vincent@stericsson.com>
> 
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: John Rigby <john.rigby@linaro.org>
...

> +void arm_pl180_mmci_init(void);

NAK.

Please move all prototype declarations to appropriate header files.
This avoids errors like here - arm_pl180_mmci_init() actually returns
int!

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Those who will be able to conquer software will be able  to  conquer
the world."                 - Tadahiro Sekimoto, president, NEC Corp.

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

* [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
@ 2011-04-11 18:09   ` Wolfgang Denk
  0 siblings, 0 replies; 42+ messages in thread
From: Wolfgang Denk @ 2011-04-11 18:09 UTC (permalink / raw)
  To: u-boot

Dear John Rigby,

In message <1301761196-26072-5-git-send-email-john.rigby@linaro.org> you wrote:
> Based on ST-Ericsson private git repo.
> Plus changes to use arm_pl180_mmci driver.
> 
> This board support requires the vexpress mmc driver patch set from
> Matt Waddel.

All these comments are not really useful as commit message.  YOu might
add these as comments.

For the commit message, I'd rather like to see a short description of
the board, and which board features are supported by this port.

...
> +extern int prcmu_i2c_read(u8 reg, u16 slave);
> +extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);

Please move prototype declarations to approproate header file.

> +int board_mmc_init(bd_t *bd)
> +{
> +	if (u8500_mmci_board_init())
> +		return -ENODEV;
> +
> +	arm_pl180_mmci_init();

Error.  You ignore the return code from arm_pl180_mmci_init() here.
Please fix.

...
> +	/* check ARM clock source */
> +	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
> +	printf("A9 running on ");
> +	if (reg & 1)
> +		printf("external clock");
> +	else
> +		printf("ARM PLL");
> +	printf("\n");

Something like

	printf("A9 running on %s\n",
		(reg & 1) ? "external clock" : "ARM PLL";

would probably result in smaller (and faster) code.

The same applies to other places, too.

...
> +#define CONFIG_SYS_MEMTEST_START	0x00000000
> +#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF

Has this actually been tested?


> +#define CONFIG_BOARD_EARLY_INIT_F	1
> +#define BOARD_LATE_INIT		1
...
> +#define CONFIG_MMC		1
> +#define CONFIG_GENERIC_MMC	1
> +#define CONFIG_DOS_PARTITION	1

Please omit the '1' in all defines that select features only.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"More software projects have gone awry for lack of calendar time than
for all other causes combined."
                         - Fred Brooks, Jr., _The Mythical Man Month_

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

* [U-Boot] [PATCHv2 0/4] ST-Ericsson U8500 support
  2011-04-11 17:33   ` John Rigby
@ 2011-04-11 19:52     ` Albert ARIBAUD
  0 siblings, 0 replies; 42+ messages in thread
From: Albert ARIBAUD @ 2011-04-11 19:52 UTC (permalink / raw)
  To: u-boot

Hi John,

Le 11/04/2011 19:33, John Rigby a ?crit :

> On Sat, Apr 2, 2011 at 10:19 AM, John Rigby<john.rigby@linaro.org>  wrote:
>> Add support for ST-Ericsson U8500 SoC and HREF platform
>>
>> John Rigby (2):
>>   armv7: Add ST-Ericsson u8500 arch
>>   armv7: Add support for ST-Ericsson U8500 href platform
>>
>> Michael Brandt (1):
>>   I2C: add driver of st-ericsson u8500 i2c
>>
>> Rabin Vincent (1):
>>   p101x: extra init for u8500

> Albert, Do you have any comments on this series?

There were requests for change in the patch set by Wolfgang and Heiko. 
I'll review V3 once it is out.

Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCHv3 0/4] ST-Ericsson U8500 support
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
  2011-04-11 17:33   ` John Rigby
@ 2011-04-12  6:17   ` John Rigby
  2011-04-28 14:47     ` John Rigby
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 1/4] Serial: p1011: new vendor init options John Rigby
                     ` (8 subsequent siblings)
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-12  6:17 UTC (permalink / raw)
  To: u-boot

Add support for ST-Ericsson U8500 SoC and HREF platform

John Rigby (2):
  armv7: Add ST-Ericsson u8500 arch
  armv7: Add support for ST-Ericsson U8500 href platform

Michael Brandt (1):
  I2C: Add driver for ST-Ericsson U8500 i2c

Rabin Vincent (1):
  Serial: p1011: new vendor init options

 README                                      |   12 +
 arch/arm/cpu/armv7/u8500/Makefile           |   46 ++
 arch/arm/cpu/armv7/u8500/clock.c            |   56 +++
 arch/arm/cpu/armv7/u8500/lowlevel.S         |   33 ++
 arch/arm/cpu/armv7/u8500/timer.c            |  167 ++++++++
 arch/arm/include/asm/arch-u8500/clock.h     |   72 ++++
 arch/arm/include/asm/arch-u8500/gpio.h      |  247 +++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h  |   83 ++++
 arch/arm/include/asm/arch-u8500/sys_proto.h |   27 ++
 arch/arm/include/asm/arch-u8500/u8500.h     |   47 ++
 board/st-ericsson/u8500/Makefile            |   50 +++
 board/st-ericsson/u8500/gpio.c              |  347 +++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h          |   55 +++
 board/st-ericsson/u8500/prcmu.c             |  165 +++++++
 board/st-ericsson/u8500/u8500_href.c        |  546 ++++++++++++++++++++++++
 boards.cfg                                  |    1 +
 drivers/i2c/Makefile                        |    1 +
 drivers/i2c/u8500_i2c.c                     |  613 +++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h                     |  194 +++++++++
 drivers/serial/serial_pl01x.c               |   17 +-
 drivers/serial/serial_pl01x.h               |    4 +
 include/configs/u8500_href.h                |  245 +++++++++++
 22 files changed, 3026 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h
 create mode 100644 include/configs/u8500_href.h

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

* [U-Boot] [PATCHv3 1/4] Serial: p1011: new vendor init options
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
  2011-04-11 17:33   ` John Rigby
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 " John Rigby
@ 2011-04-12  6:17   ` John Rigby
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
                     ` (7 subsequent siblings)
  10 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-04-12  6:17 UTC (permalink / raw)
  To: u-boot

From: Rabin Vincent <rabin.vincent@stericsson.com>

Two new options:

CONFIG_PL011_SERIAL_RLCR

Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
have separate receive and transmit line control registers.  Set
this variable to initialize the extra register.

CONFIG_PL011_SERIAL_FLUSH_ON_INIT

On some platforms (e.g. U8500) U-Boot is loaded by a second stage
boot loader that has already initialized the UART.  Define this
variable to flush the UART at init time.
empty fifo on init

Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
Signed-off-by: John Rigby <john.rigby@linaro.org>
---
v3:
Enable changes with new CONFIG_* options instead of platform.
Document new CONFIG_* options in README.

 README                        |   12 ++++++++++++
 drivers/serial/serial_pl01x.c |   17 +++++++++++++++--
 drivers/serial/serial_pl01x.h |    4 ++++
 3 files changed, 31 insertions(+), 2 deletions(-)

diff --git a/README b/README
index c128a6c..8ccac6e 100644
--- a/README
+++ b/README
@@ -468,6 +468,18 @@ The following options need to be configured:
 		define this to a list of base addresses for each (supported)
 		port. See e.g. include/configs/versatile.h
 
+		CONFIG_PL011_SERIAL_RLCR
+
+		Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
+		have separate receive and transmit line control registers.  Set
+		this variable to initialize the extra register.
+
+		CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+		On some platforms (e.g. U8500) U-Boot is loaded by a second stage
+		boot loader that has already initialized the UART.  Define this
+		variable to flush the UART at init time.
+
 
 - Console Interface:
 		Depending on board, define exactly one serial port
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 5dfcde8..164b0ac 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -111,6 +111,15 @@ int serial_init (void)
 	unsigned int divider;
 	unsigned int remainder;
 	unsigned int fraction;
+	unsigned int lcr;
+
+#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+	/* Empty RX fifo if necessary */
+	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+			readl(&regs->dr);
+	}
+#endif
 
 	/* First, disable everything */
 	writel(0, &regs->pl011_cr);
@@ -131,9 +140,13 @@ int serial_init (void)
 	writel(fraction, &regs->pl011_fbrd);
 
 	/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
-	writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN,
-	       &regs->pl011_lcrh);
+	lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
+	writel(lcr, &regs->pl011_lcrh);
 
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	/* program receive line control register */
+	writel(lcr, &regs->pl011_rlcr);
+#endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
 	       &regs->pl011_cr);
diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h
index b670c24..96ee381 100644
--- a/drivers/serial/serial_pl01x.h
+++ b/drivers/serial/serial_pl01x.h
@@ -43,7 +43,11 @@ struct pl01x_regs {
 	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
 	u32	pl010_cr;	/* 0x14 Control register */
 	u32	fr;		/* 0x18 Flag register (Read only) */
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	u32	pl011_rlcr;	/* 0x1c Receive line control register */
+#else
 	u32	reserved;
+#endif
 	u32	ilpr;		/* 0x20 IrDA low-power counter register */
 	u32	pl011_ibrd;	/* 0x24 Integer baud rate register */
 	u32	pl011_fbrd;	/* 0x28 Fractional baud rate register */
-- 
1.7.1

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

* [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (2 preceding siblings ...)
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 1/4] Serial: p1011: new vendor init options John Rigby
@ 2011-04-12  6:17   ` John Rigby
  2011-04-12  7:25     ` Albert ARIBAUD
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
                     ` (6 subsequent siblings)
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-12  6:17 UTC (permalink / raw)
  To: u-boot

Based on ST-Ericsson internal git repo.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
v2: cleanup, mostly removal of unused defines
v3: remove prototype from sys_proto.h as suggested by Wolfgang

 arch/arm/cpu/armv7/u8500/Makefile           |   46 +++++
 arch/arm/cpu/armv7/u8500/clock.c            |   56 ++++++
 arch/arm/cpu/armv7/u8500/lowlevel.S         |   33 ++++
 arch/arm/cpu/armv7/u8500/timer.c            |  167 ++++++++++++++++++
 arch/arm/include/asm/arch-u8500/clock.h     |   72 ++++++++
 arch/arm/include/asm/arch-u8500/gpio.h      |  247 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h  |   83 +++++++++
 arch/arm/include/asm/arch-u8500/sys_proto.h |   27 +++
 arch/arm/include/asm/arch-u8500/u8500.h     |   47 +++++
 9 files changed, 778 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h

diff --git a/arch/arm/cpu/armv7/u8500/Makefile b/arch/arm/cpu/armv7/u8500/Makefile
new file mode 100644
index 0000000..270aa40
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	= timer.o clock.o
+SOBJS	= lowlevel.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/u8500/clock.c b/arch/arm/cpu/armv7/u8500/clock.c
new file mode 100644
index 0000000..9e3b873
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/clock.c
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2009 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clkrst {
+	unsigned int pcken;
+	unsigned int pckdis;
+	unsigned int kcken;
+	unsigned int kckdis;
+};
+
+static unsigned int clkrst_base[] = {
+	U8500_CLKRST1_BASE,
+	U8500_CLKRST2_BASE,
+	U8500_CLKRST3_BASE,
+	0,
+	U8500_CLKRST5_BASE,
+	U8500_CLKRST6_BASE,
+	U8500_CLKRST7_BASE,	/* ED only */
+};
+
+/* Turn on peripheral clock at PRCC level */
+void u8500_clock_enable(int periph, int cluster, int kern)
+{
+	struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1];
+
+	if (kern != -1)
+		writel(1 << kern, &clkrst->kcken);
+
+	if (cluster != -1)
+		writel(1 << cluster, &clkrst->pcken);
+}
diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S
new file mode 100644
index 0000000..0e3f8fc
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/lowlevel.S
@@ -0,0 +1,33 @@
+/*
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+.globl lowlevel_init
+lowlevel_init:
+	mov	pc, lr
+
+	.align	5
+.globl reset_cpu
+reset_cpu:
+        ldr r0, =CFG_PRCMU_BASE
+        ldr r1, =0x1
+        str r1, [r0, #0x228]
+_loop_forever:
+	b	_loop_forever
diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c
new file mode 100644
index 0000000..8850fd5
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/timer.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ * John Rigby <john.rigby@linaro.org>
+ *
+ * Based on original from Linux kernel source and
+ * internal ST-Ericsson U-Boot source.
+ * (C) Copyright 2009 Alessandro Rubini
+ * (C) Copyright 2010 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * The MTU device has some interrupt control registers
+ * followed by 4 timers.
+ */
+
+/* The timers */
+struct u8500_mtu_timer {
+	u32 lr;			/* Load value */
+	u32 cv;			/* Current value */
+	u32 cr;			/* Control reg */
+	u32 bglr;		/* ??? */
+};
+
+/* The MTU that contains the timers */
+struct u8500_mtu {
+	u32 imsc;		/* Interrupt mask set/clear */
+	u32 ris;		/* Raw interrupt status */
+	u32 mis;		/* Masked interrupt status */
+	u32 icr;		/* Interrupt clear register */
+	struct u8500_mtu_timer pt[4];
+};
+
+/* bits for the control register */
+#define MTU_CR_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR */
+#define MTU_CR_32BITS		0x02
+
+#define MTU_CR_PRESCALE_1	0x00
+#define MTU_CR_PRESCALE_16	0x04
+#define MTU_CR_PRESCALE_256	0x08
+#define MTU_CR_PRESCALE_MASK	0x0c
+
+#define MTU_CR_PERIODIC		0x40	/* if 0 = free-running */
+#define MTU_CR_ENA		0x80
+
+/*
+ * The MTU is clocked at 133 MHz by default. (V1 and later)
+ */
+#define TIMER_CLOCK		(133 * 1000 * 1000 / 16)
+#define COUNT_TO_USEC(x)	((x) * 16 / 133)
+#define USEC_TO_COUNT(x)	((x) * 133 / 16)
+#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
+#define TIMER_LOAD_VAL		0xffffffff
+
+/*
+ * MTU timer to use (from 0 to 3).
+ * Linux ux500 timer0 on MTU0 and timer0 on MTU1
+ */
+#define MTU_TIMER 2
+
+static struct u8500_mtu_timer *timer_base =
+	&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
+
+/* macro to read the 32 bit timer: since it decrements, we invert read value */
+#define READ_TIMER() (~readl(&timer_base->cv))
+
+/* Configure a free-running, auto-wrap counter with /16 prescaler */
+int timer_init(void)
+{
+	writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
+	       &timer_base->cr);
+	reset_timer();
+	return 0;
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = TICKS_TO_HZ(READ_TIMER());
+
+	if (now >= gd->lastinc)	/* normal (non rollover) */
+		gd->tbl += (now - gd->lastinc);
+	else			/* rollover */
+		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->tbl;
+}
+
+/* Delay x useconds */
+void __udelay(ulong usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	ulong now, last = READ_TIMER();
+
+	while (tmo > 0) {
+		now = READ_TIMER();
+		if (now > last)	/* normal (non rollover) */
+			tmo -= now - last;
+		else		/* rollover */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+void reset_timer_masked(void)
+{
+	gd->lastinc = TICKS_TO_HZ(READ_TIMER());
+	gd->tbl = 0;		/* reset ticks to 0 */
+}
+
+void reset_timer(void)
+{
+	reset_timer_masked();
+}
+
+/*
+ * Emulation of Power architecture long long timebase.
+ *
+ * TODO: Support gd->tbu for real long long timebase.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * Emulation of Power architecture timebase.
+ * NB: Low resolution compared to Power tbclk.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/include/asm/arch-u8500/clock.h b/arch/arm/include/asm/arch-u8500/clock.h
new file mode 100644
index 0000000..b00ab0d
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/clock.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_CLOCK
+#define __ASM_ARCH_CLOCK
+
+struct prcmu {
+	unsigned int armclkfix_mgt;
+	unsigned int armclk_mgt;
+	unsigned int svammdspclk_mgt;
+	unsigned int siammdspclk_mgt;
+	unsigned int reserved;
+	unsigned int sgaclk_mgt;
+	unsigned int uartclk_mgt;
+	unsigned int msp02clk_mgt;
+	unsigned int i2cclk_mgt;
+	unsigned int sdmmcclk_mgt;
+	unsigned int slimclk_mgt;
+	unsigned int per1clk_mgt;
+	unsigned int per2clk_mgt;
+	unsigned int per3clk_mgt;
+	unsigned int per5clk_mgt;
+	unsigned int per6clk_mgt;
+	unsigned int per7clk_mgt;
+	unsigned int lcdclk_mgt;
+	unsigned int reserved1;
+	unsigned int bmlclk_mgt;
+	unsigned int hsitxclk_mgt;
+	unsigned int hsirxclk_mgt;
+	unsigned int hdmiclk_mgt;
+	unsigned int apeatclk_mgt;
+	unsigned int apetraceclk_mgt;
+	unsigned int mcdeclk_mgt;
+	unsigned int ipi2cclk_mgt;
+	unsigned int dsialtclk_mgt;
+	unsigned int spare2clk_mgt;
+	unsigned int dmaclk_mgt;
+	unsigned int b2r2clk_mgt;
+	unsigned int tvclk_mgt;
+	unsigned int unused[82];
+	unsigned int tcr;
+	unsigned int unused1[23];
+	unsigned int ape_softrst;
+};
+
+extern void u8500_clock_enable(int periph, int kern, int cluster);
+
+static inline void u8500_prcmu_enable(unsigned int *reg)
+{
+	writel(readl(reg) | (1 << 8), reg);
+}
+
+#endif /* __ASM_ARCH_CLOCK */
diff --git a/arch/arm/include/asm/arch-u8500/gpio.h b/arch/arm/include/asm/arch-u8500/gpio.h
new file mode 100644
index 0000000..769def1
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/gpio.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _UX500_GPIO_h
+#define _UX500_GPIO_h
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/u8500.h>
+
+#define GPIO_TOTAL_PINS                 268
+
+#define GPIO_PINS_PER_BLOCK	32
+#define GPIO_BLOCKS_COUNT       (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK + 1)
+#define GPIO_BLOCK(pin)		(((pin + GPIO_PINS_PER_BLOCK) >> 5) - 1)
+
+
+struct gpio_register {
+	u32 gpio_dat;	/* data register *//*0x000 */
+	u32 gpio_dats;	/* data Set register *//*0x004 */
+	u32 gpio_datc;	/* data Clear register *//*0x008 */
+	u32 gpio_pdis;	/* Pull disable register *//*0x00C */
+	u32 gpio_dir;	/* data direction register *//*0x010 */
+	u32 gpio_dirs;	/* data dir Set register *//*0x014 */
+	u32 gpio_dirc;	/* data dir Clear register *//*0x018 */
+	u32 gpio_slpm;	/* Sleep mode register *//*0x01C */
+	u32 gpio_afsa;	/* AltFun A Select reg *//*0x020 */
+	u32 gpio_afsb;	/* AltFun B Select reg *//*0x024 */
+	u32 gpio_lowemi;/* low EMI Select reg *//*0x028 */
+	u32 reserved_1[(0x040 - 0x02C) >> 2];	/*0x028-0x3C Reserved*/
+	u32 gpio_rimsc;	/* rising edge intr set/clear *//*0x040 */
+	u32 gpio_fimsc;	/* falling edge intr set/clear register *//*0x044 */
+	u32 gpio_mis;	/* masked interrupt status register *//*0x048 */
+	u32 gpio_ic;	/* Interrupt Clear register *//*0x04C */
+	u32 gpio_rwimsc;/* Rising-edge Wakeup IMSC register *//*0x050 */
+	u32 gpio_fwimsc;/* Falling-edge Wakeup IMSC register *//*0x054 */
+	u32 gpio_wks;	/* Wakeup Status register *//*0x058 */
+};
+
+/* Error values returned by functions */
+enum gpio_error {
+	GPIO_OK = 0,
+	GPIO_UNSUPPORTED_HW = -2,
+	GPIO_UNSUPPORTED_FEATURE = -3,
+	GPIO_INVALID_PARAMETER = -4,
+	GPIO_REQUEST_NOT_APPLICABLE = -5,
+	GPIO_REQUEST_PENDING = -6,
+	GPIO_NOT_CONFIGURED = -7,
+	GPIO_INTERNAL_ERROR = -8,
+	GPIO_INTERNAL_EVENT = 1,
+	GPIO_REMAINING_EVENT = 2,
+	GPIO_NO_MORE_PENDING_EVENT = 3,
+	GPIO_INVALID_CLIENT = -25,
+	GPIO_INVALID_PIN = -26,
+	GPIO_PIN_BUSY = -27,
+	GPIO_PIN_NOT_ALLOCATED = -28,
+	GPIO_WRONG_CLIENT = -29,
+	GPIO_UNSUPPORTED_ALTFUNC = -30,
+};
+
+/*GPIO DEVICE ID */
+enum gpio_device_id {
+	GPIO_DEVICE_ID_0,
+	GPIO_DEVICE_ID_1,
+	GPIO_DEVICE_ID_2,
+	GPIO_DEVICE_ID_3,
+	GPIO_DEVICE_ID_INVALID
+};
+
+/*
+ * Alternate Function:
+ *  refered in altfun_table to pointout particular altfun to be enabled
+ *  when using GPIO_ALT_FUNCTION A/B/C enable/disable operation
+ */
+enum gpio_alt_function {
+	GPIO_ALT_UART_0_MODEM,
+	GPIO_ALT_UART_0_NO_MODEM,
+	GPIO_ALT_UART_1,
+	GPIO_ALT_UART_2,
+	GPIO_ALT_I2C_0,
+	GPIO_ALT_I2C_1,
+	GPIO_ALT_I2C_2,
+	GPIO_ALT_I2C_3,
+	GPIO_ALT_MSP_0,
+	GPIO_ALT_MSP_1,
+	GPIO_ALT_MSP_2,
+	GPIO_ALT_MSP_3,
+	GPIO_ALT_MSP_4,
+	GPIO_ALT_MSP_5,
+	GPIO_ALT_SSP_0,
+	GPIO_ALT_SSP_1,
+	GPIO_ALT_MM_CARD0,
+	GPIO_ALT_SD_CARD0,
+	GPIO_ALT_DMA_0,
+	GPIO_ALT_DMA_1,
+	GPIO_ALT_HSI0,
+	GPIO_ALT_CCIR656_INPUT,
+	GPIO_ALT_CCIR656_OUTPUT,
+	GPIO_ALT_LCD_PANEL,
+	GPIO_ALT_MDIF,
+	GPIO_ALT_SDRAM,
+	GPIO_ALT_HAMAC_AUDIO_DBG,
+	GPIO_ALT_HAMAC_VIDEO_DBG,
+	GPIO_ALT_CLOCK_RESET,
+	GPIO_ALT_TSP,
+	GPIO_ALT_IRDA,
+	GPIO_ALT_USB_MINIMUM,
+	GPIO_ALT_USB_I2C,
+	GPIO_ALT_OWM,
+	GPIO_ALT_PWL,
+	GPIO_ALT_FSMC,
+	GPIO_ALT_COMP_FLASH,
+	GPIO_ALT_SRAM_NOR_FLASH,
+	GPIO_ALT_FSMC_ADDLINE_0_TO_15,
+	GPIO_ALT_SCROLL_KEY,
+	GPIO_ALT_MSHC,
+	GPIO_ALT_HPI,
+	GPIO_ALT_USB_OTG,
+	GPIO_ALT_SDIO,
+	GPIO_ALT_HSMMC,
+	GPIO_ALT_FSMC_ADD_DATA_0_TO_25,
+	GPIO_ALT_HSI1,
+	GPIO_ALT_NOR,
+	GPIO_ALT_NAND,
+	GPIO_ALT_KEYPAD,
+	GPIO_ALT_VPIP,
+	GPIO_ALT_CAM,
+	GPIO_ALT_CCP1,
+	GPIO_ALT_EMMC,
+	GPIO_ALT_POP_EMMC,
+	GPIO_ALT_FUNMAX		/* Add new alt func before this */
+};
+
+/* Defines pin assignment(Software mode or Alternate mode) */
+enum gpio_mode {
+	GPIO_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_MODE_SOFTWARE,	/* Pin connected to GPIO (SW controlled) */
+	GPIO_ALTF_A,		/* Pin connected to altfunc 1 (HW periph 1) */
+	GPIO_ALTF_B,		/* Pin connected to altfunc 2 (HW periph 2) */
+	GPIO_ALTF_C,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_FIND,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_DISABLE	/* Pin connected to altfunc 3 (HW periph 3) */
+};
+
+/* Defines GPIO pin direction */
+enum gpio_direction {
+	GPIO_DIR_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_DIR_INPUT,		/* GPIO set as input */
+	GPIO_DIR_OUTPUT		/* GPIO set as output */
+};
+
+/* Interrupt trigger mode */
+enum gpio_trig {
+	GPIO_TRIG_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_TRIG_DISABLE,	/* Trigger no IT */
+	GPIO_TRIG_RISING_EDGE,	/* Trigger an IT on rising edge */
+	GPIO_TRIG_FALLING_EDGE,	/* Trigger an IT on falling edge */
+	GPIO_TRIG_BOTH_EDGES,	/* Trigger an IT on rising and falling edge */
+	GPIO_TRIG_HIGH_LEVEL,	/* Trigger an IT on high level */
+	GPIO_TRIG_LOW_LEVEL	/* Trigger an IT on low level */
+};
+
+/* Configuration parameters for one GPIO pin.*/
+struct gpio_config {
+	enum gpio_mode mode;
+	enum gpio_direction direction;
+	enum gpio_trig trig;
+	char *dev_name;		/* Who owns the gpio pin */
+};
+
+/* GPIO pin data*/
+enum gpio_data {
+	GPIO_DATA_LOW,
+	GPIO_DATA_HIGH
+};
+
+/* GPIO behaviour in sleep mode */
+enum gpio_sleep_mode {
+	GPIO_SLEEP_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,	/* GPIO is an input with pull
+						   up/down enabled when in sleep
+						   mode. */
+	GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO	/* GPIO pin is controlled by
+						   GPIO IP. So mode, direction
+						   and data values for GPIO pin
+						   in sleep mode are determined
+						   by configuration set to GPIO
+						   pin before entering to sleep
+						   mode. */
+};
+
+/* GPIO ability to wake the system up from sleep mode.*/
+enum gpio_wake {
+	GPIO_WAKE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_WAKE_DISABLE,	/* No wake of system from sleep mode. */
+	GPIO_WAKE_LOW_LEVEL,	/* Wake the system up on a LOW level. */
+	GPIO_WAKE_HIGH_LEVEL,	/* Wake the system up on a HIGH level. */
+	GPIO_WAKE_RISING_EDGE,	/* Wake the system up on a RISING edge. */
+	GPIO_WAKE_FALLING_EDGE,	/* Wake the system up on a FALLING edge. */
+	GPIO_WAKE_BOTH_EDGES	/* Wake the system up on both RISE and FALL. */
+};
+
+/* Configuration parameters for one GPIO pin in sleep mode.*/
+struct gpio_sleep_config {
+	enum gpio_sleep_mode sleep_mode;/* GPIO behaviour in sleep mode. */
+	enum gpio_wake wake;		/* GPIO ability to wake up system. */
+};
+
+extern int gpio_setpinconfig(int pin_id, struct gpio_config *pin_config);
+extern int gpio_resetpinconfig(int pin_id, char *dev_name);
+extern int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name);
+extern int gpio_readpin(int pin_id, enum gpio_data *value);
+extern int gpio_altfuncenable(enum gpio_alt_function altfunc,
+				      char *dev_name);
+extern int gpio_altfuncdisable(enum gpio_alt_function altfunc,
+				       char *dev_name);
+
+struct gpio_altfun_data {
+	u16 altfun;
+	u16 start;
+	u16 end;
+	u16 cont;
+	u8 type;
+};
+#endif
diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h
new file mode 100644
index 0000000..6bb95ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/hardware.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Peripheral clusters */
+
+#define U8500_PER3_BASE		0x80000000
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_PER4_BASE		0x80150000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER7_BASE		0xa03d0000
+#define U8500_PER5_BASE		0xa03e0000
+
+/* GPIO */
+
+#define U8500_GPIO0_BASE	(U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO2_BASE	(U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xE000 + 0x80)
+#define U8500_GPIO4_BASE	(U8500_PER3_BASE + 0xE000 + 0x100)
+#define U8500_GPIO5_BASE	(U8500_PER3_BASE + 0xE000 + 0x180)
+
+#define U8500_GPIO6_BASE	(U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO7_BASE	(U8500_PER2_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO8_BASE	(U8500_PER5_BASE + 0x1E000)
+
+/* Per7 */
+#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* Per6 */
+#define U8500_MTU0_BASE_V1	(U8500_PER6_BASE + 0x6000)
+#define U8500_MTU1_BASE_V1	(U8500_PER6_BASE + 0x7000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+
+/* Per5 */
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+
+/* Per4 */
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x0f000)
+
+/* Per3 */
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+
+/* Per2 */
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* Per1 */
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+
+/* Last page of Boot ROM */
+#define U8500_BOOTROM_BASE      0x9001f000
+#define U8500_BOOTROM_ASIC_ID_OFFSET    0x0ff4
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-u8500/sys_proto.h b/arch/arm/include/asm/arch-u8500/sys_proto.h
new file mode 100644
index 0000000..bac5e79
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/sys_proto.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void gpio_init(void);
+
+#endif  /* _SYS_PROTO_H_ */
diff --git a/arch/arm/include/asm/arch-u8500/u8500.h b/arch/arm/include/asm/arch-u8500/u8500.h
new file mode 100644
index 0000000..0d6dbb7
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/u8500.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __U8500_H
+#define __U8500_H
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   Management Unit */
+#define CFG_SDRAMC_BASE		0x903CF000	/* SDRAMC cnf registers */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+/*
+ * U8500 GPIO register base for 9 banks
+ */
+#define U8500_GPIO_0_BASE			0x8012E000
+#define U8500_GPIO_1_BASE			0x8012E080
+#define U8500_GPIO_2_BASE			0x8000E000
+#define U8500_GPIO_3_BASE			0x8000E080
+#define U8500_GPIO_4_BASE			0x8000E100
+#define U8500_GPIO_5_BASE			0x8000E180
+#define U8500_GPIO_6_BASE			0x8011E000
+#define U8500_GPIO_7_BASE			0x8011E080
+#define U8500_GPIO_8_BASE			0xA03FE000
+
+#endif	/* __U8500_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (3 preceding siblings ...)
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-04-12  6:17   ` John Rigby
  2011-04-12  6:47     ` Heiko Schocher
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
                     ` (5 subsequent siblings)
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-12  6:17 UTC (permalink / raw)
  To: u-boot

From: Michael Brandt <michael.brandt@stericsson.com>

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Heiko Schocher <hs@denx.de>
---
v2: Incorporate suggestions from Heiko Schocher
v3: Fix line length problem reported by Heiko Schocher
 drivers/i2c/Makefile    |    1 +
 drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
 3 files changed, 808 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..43507fc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
new file mode 100644
index 0000000..ea8a71d
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Basic U-Boot I2C interface for STn8500/DB8500
+ * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Only 7-bit I2C device addresses are supported.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "u8500_i2c.h"
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#define U8500_I2C_ENDAD_COUNTER	(CONFIG_SYS_HZ/100)	/* I2C bus timeout */
+#define U8500_I2C_FIFO_FLUSH_COUNTER	500000		/* flush "timeout" */
+#define U8500_I2C_SCL_FREQ		100000		/* I2C bus clock freq */
+#define U8500_I2C_INPUT_FREQ		48000000	/* Input clock freq */
+#define TX_FIFO_THRESHOLD	0x4
+#define RX_FIFO_THRESHOLD	0x4
+#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
+
+#define WRITE_FIELD(var, mask, shift, value) \
+			(var = ((var & ~(mask)) | ((value) << (shift))))
+
+static unsigned int bus_initialized[CONFIG_SYS_U8500_I2C_BUS_MAX];
+static unsigned int i2c_bus_num;
+static unsigned int i2c_bus_speed[] = {
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
+};
+static struct u8500_i2c_regs *i2c_dev[] = {
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C0_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C1_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C2_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C3_BASE,
+};
+
+static struct {
+	int periph;
+	int pcken;
+	int kcken;
+} i2c_clock_bits[] = {
+	{3, 3, 3}, /* I2C0 */
+	{1, 2, 2}, /* I2C1 */
+	{1, 6, 6}, /* I2C2 */
+	{2, 0, 0}, /* I2C3 */
+};
+
+static void i2c_set_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) | mask, reg);
+}
+
+static void i2c_clr_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) & ~mask, reg);
+}
+
+static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
+{
+	writel((readl(reg) & ~mask) | (value << shift), reg);
+}
+
+static int __i2c_set_bus_speed(unsigned int speed)
+{
+	u32 value;
+	struct u8500_i2c_regs *i2c_regs;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Select standard (100 kbps) speed mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_SM,
+			U8500_I2C_CR_SHIFT_SM, 0x0);
+
+	/*
+	 * Set the Baud Rate Counter 2 value
+	 * Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
+	 * Foncycle = 0 (no digital filtering)
+	 */
+	value = (u32) (U8500_I2C_INPUT_FREQ / (speed * 2));
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT2,
+			U8500_I2C_BRCR_SHIFT_BRCNT2, value);
+
+	/* ensure that BRCNT value is zero */
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT1,
+			U8500_I2C_BRCR_SHIFT_BRCNT1, 0);
+
+	return U8500_I2C_INPUT_FREQ/(value * 2);
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *
+ *	speed: bus speed (in HZ)
+ *	slaveaddr: address of device in slave mode
+ *
+ *	Slave mode is not implemented.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+	struct u8500_i2c_regs *i2c_regs;
+
+	debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
+
+	u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
+			   i2c_clock_bits[i2c_bus_num].pcken,
+			   i2c_clock_bits[i2c_bus_num].kcken);
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Disable the controller */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	/* Clear registers */
+	writel(0, &i2c_regs->cr);
+	writel(0, &i2c_regs->scr);
+	writel(0, &i2c_regs->hsmcr);
+	writel(0, &i2c_regs->tftr);
+	writel(0, &i2c_regs->rftr);
+	writel(0, &i2c_regs->dmar);
+
+	i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
+
+	/*
+	 * Set our own address.
+	 * Set slave address mode to 7 bit addressing mode
+	 */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_SAM);
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_ADDR,
+			U8500_I2C_SCR_SHIFT_ADDR, slaveaddr);
+	/* Slave Data Set up Time */
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_DATA_SETUP_TIME,
+			U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
+
+	/* Disable the DMA sync logic */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_DMA_SLE,
+			U8500_I2C_CR_SHIFT_DMA_SLE, 0);
+
+	/* Disable interrupts */
+	writel(0, &i2c_regs->imscr);
+
+	/* Configure bus master mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_OM, U8500_I2C_CR_SHIFT_OM,
+			U8500_I2C_BUS_MASTER_MODE);
+	/* Set FIFO threshold values */
+	writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
+	writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
+
+	/* Enable the I2C Controller */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	bus_initialized[i2c_bus_num] = 1;
+}
+
+
+/*
+ * loop_till_bit_clear - polls on a bit till it clears
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) == 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_clear timed out\n");
+	return -1;
+}
+
+/*
+ * loop_till_bit_set - polls on a bit till it is set.
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) != 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_set timed out\n");
+	return -1;
+}
+
+/*
+ * flush_fifo - flush the I2C TX and RX FIFOs
+ */
+static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
+{
+	int counter = U8500_I2C_FIFO_FLUSH_COUNTER;
+
+	/* Flush Tx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FTX);
+	/* Flush Rx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FRX);
+	while (counter--) {
+		if (!(readl(&i2c_regs->cr) &
+				(U8500_I2C_CR_FTX | U8500_I2C_CR_FRX)))
+			break;
+	}
+	return;
+}
+
+#ifdef DEBUG
+static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
+{
+	int cause;
+
+	printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
+	cause = (readl(&i2c_regs->sr) & U8500_I2C_SR_CAUSE) >>
+				U8500_I2C_SR_SHIFT_CAUSE;
+	switch (cause) {
+	case U8500_I2C_NACK_ADDR:
+		printf("No Ack received after Slave Address xmission\n");
+		break;
+	case U8500_I2C_NACK_DATA:
+		printf("Valid for MASTER_WRITE: No Ack received "
+				"during data phase\n");
+		break;
+	case U8500_I2C_ACK_MCODE:
+		printf("Master recv ack after xmission of master code"
+				"in hs mode\n");
+		break;
+	case U8500_I2C_ARB_LOST:
+		printf("Master Lost arbitration\n");
+		break;
+	case U8500_I2C_BERR_START:
+		printf("Slave restarts\n");
+		break;
+	case U8500_I2C_BERR_STOP:
+		printf("Slave reset\n");
+		break;
+	case U8500_I2C_OVFL:
+		printf("Overflow\n");
+		break;
+	default:
+		printf("Unknown error type\n");
+	}
+}
+#endif
+
+/*
+ * i2c_abort - called when a I2C transaction failed
+ */
+static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
+{
+#ifdef DEBUG
+	print_abort_reason(i2c_regs);
+#endif
+	/* flush RX and TX fifos */
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
+}
+
+/*
+ * write addr, alias index, to I2C bus.
+ */
+static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
+{
+	while (alen--) {
+		/* Wait until the Tx Fifo is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER)) {
+			i2c_abort(i2c_regs);
+			return -1;
+		}
+
+		/* MSB first */
+		writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
+	}
+
+	return 0;
+}
+
+/*
+ * Internal simplified read function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   value:	Where to put the data
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
+		uint addr, int alen, uchar *value)
+{
+	u32   mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	if (alen != 0) {
+		/* Master write operation */
+		mcr &= ~(U8500_I2C_MCR_OP);
+
+		/* Configure the Frame length to one byte */
+		WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH,
+				U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+		/* Repeated start, no stop */
+		mcr &= ~(U8500_I2C_MCR_STOP);
+
+		/* Write Master Control Register */
+		writel(mcr, &i2c_regs->mcr);
+
+		/* send addr/index */
+		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+			return -1;
+
+		/* Check for the Master Transaction Done Without Stop */
+		if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTDWS,
+					U8500_I2C_ENDAD_COUNTER)) {
+			return -1;
+		}
+
+		/* Acknowledge the Master Transaction Done Without Stop */
+		i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+	}
+
+	/* Master control configuration for read operation  */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Configure the STOP condition, we read only one byte */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Set the frame length to one byte, we support only 1 byte reads */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	i2c_write_field(&i2c_regs->mcr, U8500_I2C_MCR_LENGTH_STOP_OP,
+			U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
+
+	/*
+	 * receive_data_polling
+	 */
+
+	/* Wait until the Rx FIFO is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Read the data byte from Rx FIFO */
+	*value = readb(&i2c_regs->rfr);
+
+	/* Wait until the work is done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr, U8500_I2C_INT_MTD,
+				U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* If MTD is set, Master Transaction Done Without Stop is set too */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Internal simplified write function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   data:	Where to read the data
+ *   len:	How many bytes to write
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
+		int alen, u8 *data, int len)
+{
+	int i;
+	u32 mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Write operation */
+	mcr &= ~(U8500_I2C_MCR_OP);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Frame length: addr byte + len */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH,
+			(alen + len));
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+		return -1;
+
+	for (i = 0; i < len; i++) {
+		/* Wait until the Tx FIFO is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER))
+			return -1;
+
+		/* it is a 32 bit register with upper 24 reserved R/O */
+		writeb(data[i], &i2c_regs->tfr);
+	}
+
+	/* Check for Master Transaction Done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTD,
+					U8500_I2C_ENDAD_COUNTER)) {
+		printf("i2c_write_byte error2: risr %08x\n",
+				i2c_regs->risr);
+		return -1;
+	}
+
+	/* Acknowledge Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Probe the given I2C chip address. Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(uchar chip)
+{
+	u32 mcr = 0;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (chip == CONFIG_SYS_I2C_SLAVE)
+		return 1;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A10, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Read operation */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Set the frame length to one byte */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	/* Wait until the Rx Fifo is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER)) {
+		i2c_abort(i2c_regs);
+		return -1;
+	}
+
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Read/Write interface:
+ *   chip:    I2C chip address, range 0..127
+ *   addr:    Memory (register) address within the chip
+ *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:  Where to read/write the data
+ *   len:     How many bytes to read/write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int i;
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (alen > 2) {
+		debug("I2C read: addr len %d not supported\n", alen);
+		return 1;
+	}
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	for (i = 0; i < len; i++) {
+		rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
+		if (rc != 0) {
+			debug("I2C read: I/O error: %d\n", rc);
+			i2c_abort(i2c_regs);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
+			len);
+	if (rc != 0) {
+		debug("I2C write: I/O error\n");
+		i2c_abort(i2c_regs);
+		return rc;
+	}
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if (bus > ARRAY_SIZE(i2c_dev) - 1) {
+		debug("i2c_set_bus_num: only up to bus %d supported\n",
+				ARRAY_SIZE(i2c_dev)-1);
+		return -1;
+	}
+
+	i2c_bus_num = bus;
+
+	if (!bus_initialized[i2c_bus_num])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+
+	if (speed > U8500_I2C_MAX_STANDARD_SCL) {
+		debug("i2c_set_bus_speed: only up to %d supported\n",
+				U8500_I2C_MAX_STANDARD_SCL);
+		return -1;
+	}
+
+	/* sets as side effect i2c_bus_speed[i2c_bus_num] */
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return i2c_bus_num;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+	return i2c_bus_speed[i2c_bus_num];
+}
diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
new file mode 100644
index 0000000..91dbd3e
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _U8500_I2C_H_
+#define _U8500_I2C_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/u8500.h>
+
+struct u8500_i2c_regs {
+	u32 cr;			/* Control Register                      0x00 */
+	u32 scr;		/* Slave Address Register                0x04 */
+	u32 hsmcr;		/* HS Master code Register               0x08 */
+	u32 mcr;		/* Master Control Register               0x0C */
+	u32 tfr;		/* Transmit Fifo Register                0x10 */
+	u32 sr;			/* Status Register                       0x14 */
+	u32 rfr;		/* Receiver Fifo Register                0x18 */
+	u32 tftr;		/* Transmit Fifo Threshold Register      0x1C */
+	u32 rftr;		/* Receiver Fifo Threshold Register      0x20 */
+	u32 dmar;		/* DMA register                          0x24 */
+	u32 brcr;		/* Baud Rate Counter Register            0x28 */
+	u32 imscr;		/* Interrupt Mask Set and Clear Register 0x2C */
+	u32 risr;		/* Raw interrupt status register         0x30 */
+	u32 misr;		/* Masked interrupt status register      0x34 */
+	u32 icr;		/* Interrupt Set and Clear Register      0x38 */
+	u32 reserved_1[(0xFE0 - 0x3c) >> 2];	/* Reserved 0x03C to 0xFE0 */
+	u32 periph_id_0;	/* peripheral ID 0			0xFE0 */
+	u32 periph_id_1;	/* peripheral ID 1			0xFE4 */
+	u32 periph_id_2;	/* peripheral ID 2			0xFE8 */
+	u32 periph_id_3;	/* peripheral ID 3			0xFEC */
+	u32 cell_id_0;		/* I2C cell   ID 0			0xFF0 */
+	u32 cell_id_1;		/* I2C cell   ID 1			0xFF4 */
+	u32 cell_id_2;		/* I2C cell   ID 2			0xFF8 */
+	u32 cell_id_3;		/* I2C cell   ID 3			0xFFC */
+};
+
+
+/* Control Register */
+
+/* Mask values for control register mask */
+#define U8500_I2C_CR_PE          0x0001	/* Peripheral enable */
+#define U8500_I2C_CR_OM          0x0006	/* Operation mode */
+#define U8500_I2C_CR_SAM         0x0008	/* Slave Addressing mode */
+#define U8500_I2C_CR_SM          0x0030	/* Speed mode */
+#define U8500_I2C_CR_SGCM        0x0040	/* Slave General call mode */
+#define U8500_I2C_CR_FTX         0x0080	/* Flush Transmit */
+#define U8500_I2C_CR_FRX         0x0100	/* Flush Receive */
+#define U8500_I2C_CR_DMA_TX_EN   0x0200	/* DMA TX Enable */
+#define U8500_I2C_CR_DMA_RX_EN   0x0400	/* DMA Rx Enable */
+#define U8500_I2C_CR_DMA_SLE     0x0800	/* DMA Synchronization Logic enable */
+#define U8500_I2C_CR_LM          0x1000	/* Loop back mode */
+#define U8500_I2C_CR_FON         0x6000	/* Filtering On */
+
+/* shift valus for control register bit fields */
+#define U8500_I2C_CR_SHIFT_PE		0	/* Peripheral enable */
+#define U8500_I2C_CR_SHIFT_OM		1	/* Operation mode */
+#define U8500_I2C_CR_SHIFT_SAM		3	/* Slave Addressing mode */
+#define U8500_I2C_CR_SHIFT_SM		4	/* Speed mode */
+#define U8500_I2C_CR_SHIFT_SGCM		6	/* Slave General call mode */
+#define U8500_I2C_CR_SHIFT_FTX		7	/* Flush Transmit */
+#define U8500_I2C_CR_SHIFT_FRX		8	/* Flush Receive */
+#define U8500_I2C_CR_SHIFT_DMA_TX_EN	9	/* DMA TX Enable */
+#define U8500_I2C_CR_SHIFT_DMA_RX_EN	10	/* DMA Rx Enable */
+#define U8500_I2C_CR_SHIFT_DMA_SLE	11	/* DMA Synch Logic enable */
+#define U8500_I2C_CR_SHIFT_LM		12	/* Loop back mode */
+#define U8500_I2C_CR_SHIFT_FON		13	/* Filtering On */
+
+/* bus operation modes */
+#define U8500_I2C_BUS_SLAVE_MODE		0
+#define U8500_I2C_BUS_MASTER_MODE		1
+#define U8500_I2C_BUS_MASTER_SLAVE_MODE	2
+
+
+/* Slave control register*/
+
+/* Mask values slave control register */
+#define U8500_I2C_SCR_ADDR                   0x3FF
+#define U8500_I2C_SCR_DATA_SETUP_TIME        0xFFFF0000
+
+/* Shift values for Slave control register */
+#define U8500_I2C_SCR_SHIFT_ADDR               0
+#define U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME    16
+
+
+/* Master Control Register */
+
+/* Mask values for Master control register */
+#define U8500_I2C_MCR_OP	0x00000001	/* Operation */
+#define U8500_I2C_MCR_A7	0x000000FE	/* LSB bits of Address */
+#define U8500_I2C_MCR_EA10	0x00000700	/* Extended Address */
+#define U8500_I2C_MCR_SB	0x00000800	/* Start byte procedure */
+#define U8500_I2C_MCR_AM	0x00003000	/* Address type */
+#define U8500_I2C_MCR_STOP	0x00004000	/* stop condition */
+#define U8500_I2C_MCR_LENGTH	0x03FF8000	/* Frame length */
+#define U8500_I2C_MCR_A10	0x000007FE	/* Enable 10 bit address */
+/* mask for length field,stop and operation  */
+#define U8500_I2C_MCR_LENGTH_STOP_OP	0x3FFC001
+
+/* Shift values for Master control values */
+#define U8500_I2C_MCR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_MCR_SHIFT_A7		1	/* LSB bits of Address */
+#define U8500_I2C_MCR_SHIFT_EA10	8	/* Extended Address */
+#define U8500_I2C_MCR_SHIFT_SB		11	/* Start byte procedure */
+#define U8500_I2C_MCR_SHIFT_AM		12	/* Address type */
+#define U8500_I2C_MCR_SHIFT_STOP	14	/* stop condition */
+#define U8500_I2C_MCR_SHIFT_LENGTH	15	/* Frame length */
+#define U8500_I2C_MCR_SHIFT_A10		1	/* Enable 10 bit address */
+
+#define U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP	0
+
+
+/* Status Register */
+
+/* Mask values for Status register */
+#define U8500_I2C_SR_OP	0x00000003	/* Operation */
+#define U8500_I2C_SR_STATUS	0x0000000C	/* Controller Status */
+#define U8500_I2C_SR_CAUSE	0x00000070	/* Abort Cause */
+#define U8500_I2C_SR_TYPE	0x00000180	/* Receive Type */
+#define U8500_I2C_SR_LENGTH	0x000FF700	/* Transfer length */
+
+/* Shift values for Status register */
+#define U8500_I2C_SR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_SR_SHIFT_STATUS	2	/* Controller Status */
+#define U8500_I2C_SR_SHIFT_CAUSE	4	/* Abort Cause */
+#define U8500_I2C_SR_SHIFT_TYPE	7	/* Receive Type */
+#define U8500_I2C_SR_SHIFT_LENGTH	9	/* Transfer length */
+
+/* abort cause */
+#define	U8500_I2C_NACK_ADDR	0
+#define	U8500_I2C_NACK_DATA	1
+#define	U8500_I2C_ACK_MCODE	2
+#define	U8500_I2C_ARB_LOST	3
+#define	U8500_I2C_BERR_START	4
+#define	U8500_I2C_BERR_STOP	5
+#define	U8500_I2C_OVFL	6
+
+
+/* Baud rate counter registers */
+
+/* Mask values for Baud rate counter register */
+#define U8500_I2C_BRCR_BRCNT2	0xFFFF		/* Baud Rate Cntr BRCR for HS */
+#define U8500_I2C_BRCR_BRCNT1	0xFFFF0000	/* BRCR for Standard and Fast */
+
+/* Shift values for the Baud rate counter register */
+#define U8500_I2C_BRCR_SHIFT_BRCNT2	0
+#define U8500_I2C_BRCR_SHIFT_BRCNT1	16
+
+
+/* Interrupt Register  */
+
+/* Mask values for Interrupt registers */
+#define U8500_I2C_INT_TXFE	0x00000001	/* Tx fifo empty */
+#define U8500_I2C_INT_TXFNE	0x00000002	/* Tx Fifo nearly empty */
+#define U8500_I2C_INT_TXFF	0x00000004	/* Tx Fifo Full */
+#define U8500_I2C_INT_TXFOVR	0x00000008	/* Tx Fifo over run */
+#define U8500_I2C_INT_RXFE	0x00000010	/* Rx Fifo Empty */
+#define U8500_I2C_INT_RXFNF	0x00000020	/* Rx Fifo nearly empty */
+#define U8500_I2C_INT_RXFF	0x00000040	/* Rx Fifo Full  */
+#define U8500_I2C_INT_RFSR	0x00010000	/* Read From slave request */
+#define U8500_I2C_INT_RFSE	0x00020000	/* Read from slave empty */
+#define U8500_I2C_INT_WTSR	0x00040000	/* Write to Slave request */
+#define U8500_I2C_INT_MTD	0x00080000	/* Master Transcation Done*/
+#define U8500_I2C_INT_STD	0x00100000	/* Slave Transaction Done */
+#define U8500_I2C_INT_MAL	0x01000000	/* Master Arbitation Lost */
+#define U8500_I2C_INT_BERR	0x02000000	/* Bus Error */
+#define U8500_I2C_INT_MTDWS	0x10000000	/* Master Tran Done wo/ Stop */
+
+/* Max clocks (Hz) */
+#define U8500_I2C_MAX_STANDARD_SCL	100000
+#define U8500_I2C_MAX_FAST_SCL		400000
+#define U8500_I2C_MAX_HIGH_SPEED_SCL	3400000
+
+#endif	/* _U8500_I2C_H_ */
-- 
1.7.1

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

* [U-Boot] [PATCHv3 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (4 preceding siblings ...)
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
@ 2011-04-12  6:17   ` John Rigby
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options John Rigby
                     ` (4 subsequent siblings)
  10 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-04-12  6:17 UTC (permalink / raw)
  To: u-boot

Minimal platform support to boot linux from SD.

Supported devices/hw limited to external MMC/SD slot,
GPIO, I2C and minimal PRCMU.

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
This board support requires mmc driver patch set from Matt Waddel.
v2: cleanup, mostly removal of unused defines and include files
v3: incorporate changes suggested by Wolfgang including:
    better commit message
    get arm_pl180_mmci_init prototype from driver .h file
    don't ignore value from arm_pl180_mmci_init
    optimize printf's in u8500_href.c
    use plain #define CONFIG_BLAH for feature enabling 

 board/st-ericsson/u8500/Makefile     |   50 +++
 board/st-ericsson/u8500/gpio.c       |  347 +++++++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h   |   55 ++++
 board/st-ericsson/u8500/prcmu.c      |  165 ++++++++++
 board/st-ericsson/u8500/u8500_href.c |  546 ++++++++++++++++++++++++++++++++++
 boards.cfg                           |    1 +
 include/configs/u8500_href.h         |  245 +++++++++++++++
 7 files changed, 1409 insertions(+), 0 deletions(-)
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 include/configs/u8500_href.h

diff --git a/board/st-ericsson/u8500/Makefile b/board/st-ericsson/u8500/Makefile
new file mode 100644
index 0000000..91c2abf
--- /dev/null
+++ b/board/st-ericsson/u8500/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= u8500_href.o gpio.o prcmu.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/st-ericsson/u8500/gpio.c b/board/st-ericsson/u8500/gpio.c
new file mode 100644
index 0000000..96b2461
--- /dev/null
+++ b/board/st-ericsson/u8500/gpio.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+	(void *)U8500_GPIO_0_BASE,
+	(void *)U8500_GPIO_1_BASE,
+	(void *)U8500_GPIO_2_BASE,
+	(void *)U8500_GPIO_3_BASE,
+	(void *)U8500_GPIO_4_BASE,
+	(void *)U8500_GPIO_5_BASE,
+	(void *)U8500_GPIO_6_BASE,
+	(void *)U8500_GPIO_7_BASE,
+	(void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+	{
+		.altfun = GPIO_ALT_I2C_0,
+		.start = 147,
+		.end = 148,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_1,
+		.start = 16,
+		.end = 17,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_2,
+		.start = 10,
+		.end = 11,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_3,
+		.start = 229,
+		.end = 230,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 0,
+		.end = 3,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_1,
+		.start = 4,
+		.end = 7,
+		.cont = 0,
+		.type =
+			GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 18,
+		.end = 19,
+		.cont = 1,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 29,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 12,
+		.end = 17,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 21,
+		.end = 21,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_1,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_2,
+		.start = 192,
+		.end = 196,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 64,
+		.end = 93,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 150,
+		.end = 171,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_SD_CARD0,
+		.start = 18,
+		.end = 28,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MM_CARD0,
+		.start = 18,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_USB_OTG,
+		.start = 256,
+		.end = 267,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_EMMC,
+		.start = 197,
+		.end = 207,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_POP_EMMC,
+		.start = 128,
+		.end = 138,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	switch (config->mode) {
+	case GPIO_ALTF_A:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_B:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_C:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_MODE_SOFTWARE:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+		switch (config->direction) {
+		case GPIO_DIR_INPUT:
+			writel(mask, &p_gpio_register->gpio_dirc);
+			break;
+		case GPIO_DIR_OUTPUT:
+			writel(mask, &p_gpio_register->gpio_dirs);
+			break;
+		case GPIO_DIR_LEAVE_UNCHANGED:
+			break;
+		default:
+			return GPIO_INVALID_PARAMETER;
+		}
+
+		break;
+	case GPIO_MODE_LEAVE_UNCHANGED:
+		break;
+	default:
+		return GPIO_INVALID_PARAMETER;
+	}
+	return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	temp_reg = readl(&p_gpio_register->gpio_afsa);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsa);
+	temp_reg = readl(&p_gpio_register->gpio_afsb);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsb);
+	writel(mask, &p_gpio_register->gpio_dirc);
+
+	return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+			    int which_altfunc, char *dev_name)
+{
+	int i, j, start, end;
+	enum gpio_error error = -1;
+
+	for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+		if (altfun_table[i].altfun != alt_func)
+			continue;
+
+		start = altfun_table[i].start;
+		end = altfun_table[i].end;
+		for (j = start; j <= end; j++) {
+			if (which_altfunc == GPIO_ALTF_FIND)
+				altfun_pinconfig.mode = altfun_table[i].type;
+			else
+				altfun_pinconfig.mode = which_altfunc;
+			altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+			altfun_pinconfig.dev_name = dev_name;
+
+			if (which_altfunc != GPIO_ALTF_DISABLE)
+				error = gpio_setpinconfig(j, &altfun_pinconfig);
+			else
+				error = gpio_resetgpiopin(j, dev_name);
+			if (!error)
+				continue;
+			printf("GPIO %d configuration failure (nmdk_error:%d)",
+				j, error);
+			error = GPIO_INVALID_PARAMETER;
+			return error;
+		}
+
+		if (!altfun_table[i].cont)
+			break;
+	}
+	return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	switch (value) {
+	case GPIO_DATA_HIGH:
+		writel(mask, &p_gpio_register->gpio_dats);
+		break;
+	case GPIO_DATA_LOW:
+		writel(mask, &p_gpio_register->gpio_datc);
+		break;
+	default:
+		printf("Invalid value passed in %s", __FUNCTION__);
+		return GPIO_INVALID_PARAMETER;
+	}
+	return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+		*rv = GPIO_DATA_HIGH;
+	else
+		*rv = GPIO_DATA_LOW;
+	return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}
diff --git a/board/st-ericsson/u8500/prcmu-fw.h b/board/st-ericsson/u8500/prcmu-fw.h
new file mode 100644
index 0000000..0836983
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu-fw.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __MACH_PRCMU_FW_V1_H
+#define __MACH_PRCMU_FW_V1_H
+
+#define AP_EXECUTE	2
+#define I2CREAD		1
+#define I2C_WR_OK	1
+#define I2C_RD_OK	2
+#define I2CWRITE	0
+
+#define _PRCMU_TCDM_BASE    U8500_PRCMU_TCDM_BASE
+#define PRCM_XP70_CUR_PWR_STATE (_PRCMU_TCDM_BASE + 0xFFC)      /* 4 BYTES */
+
+#define PRCM_REQ_MB5        (_PRCMU_TCDM_BASE + 0xE44)    /* 4 bytes  */
+#define PRCM_ACK_MB5        (_PRCMU_TCDM_BASE + 0xDF4)    /* 4 bytes */
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2COPTYPE_REG	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_BIT_FIELDS		(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2CSLAVE		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2CVAL		(PRCM_REQ_MB5 + 0x3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_SLAVE	(PRCM_ACK_MB5 + 0x2)
+#define PRCM_ACK_MB5_VAL	(PRCM_ACK_MB5 + 0x3)
+
+#define LOW_POWER_WAKEUP	1
+#define EXE_WAKEUP		0
+
+#define REQ_MB5			5
+
+extern int prcmu_i2c_read(u8 reg, u16 slave);
+extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
+
+#endif /* __MACH_PRCMU_FW_V1_H */
diff --git a/board/st-ericsson/u8500/prcmu.c b/board/st-ericsson/u8500/prcmu.c
new file mode 100644
index 0000000..6f9302f
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Adapted from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This currently does not support the I2C workaround access method.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "prcmu-fw.h"
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+
+static int prcmu_is_ready(void)
+{
+	int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
+	if (!ready)
+		printf("PRCMU firmware not ready\n");
+	return ready;
+}
+
+static int _wait_for_req_complete(int num)
+{
+	int timeout = 1000;
+
+	/* checking any already on-going transaction */
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	timeout = 1000;
+
+	/* Set an interrupt to XP70 */
+	writel(1 << num, PRCM_MBOX_CPU_SET);
+
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	if (!timeout) {
+		printf("PRCMU operation timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db8500 register to be accessed
+ * Returns: ACK_MB5  value containing the status
+ */
+int prcmu_i2c_read(u8 reg, u16 slave)
+{
+	uint8_t i2c_status;
+	uint8_t i2c_val;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(0, PRCM_REQ_MB5_I2CVAL);
+
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	i2c_val = readb(PRCM_ACK_MB5_VAL);
+
+	if (i2c_status == I2C_RD_OK)
+		return i2c_val;
+	else {
+
+		printf("prcmu_i2c_read:read return status= %d\n",
+				i2c_status);
+		return -1;
+	}
+
+}
+
+/**
+ * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db800 register to be written to
+ * @reg_data: - the data to write
+ * Returns: ACK_MB5 value containing the status
+ */
+int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
+{
+	uint8_t i2c_status;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
+
+	debug("\ncpu_is_u8500v11\n");
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	debug("\ni2c_status = %x\n", i2c_status);
+	if (i2c_status == I2C_WR_OK)
+		return 0;
+	else {
+		printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
+		return -1;
+	}
+}
diff --git a/board/st-ericsson/u8500/u8500_href.c b/board/st-ericsson/u8500/u8500_href.c
new file mode 100644
index 0000000..525633e
--- /dev/null
+++ b/board/st-ericsson/u8500/u8500_href.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#ifdef CONFIG_MMC
+#include "../../../drivers/mmc/arm_pl180_mmci.h"
+#endif
+
+#define NOMADIK_PER4_BASE	(0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+/* Power, Reset, Clock Management Unit */
+/*
+ * SVA: Smart Video Accelerator
+ * SIA: Smart Imaging Accelerator
+ * SGA: Smart Graphic accelerator
+ * B2R2: Graphic blitter
+ */
+#define PRCMU_BASE	CFG_PRCMU_BASE	/* 0x80157000 for U8500 */
+#define PRCM_ARMCLKFIX_MGT_REG		(PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG		(PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG		(PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG		(PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG		(PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG		(PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG		(PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG		(PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG		(PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG		(PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG		(PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG		(PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG		(PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG		(PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG		(PRCMU_BASE + 0x074)
+#define PRCM_B2R2CLK_MGT_REG		(PRCMU_BASE + 0x078)
+
+#define PRCM_PLLSOC0_FREQ_REG		(PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ_REG		(PRCMU_BASE + 0x084)
+#define PRCM_PLLARM_FREQ_REG		(PRCMU_BASE + 0x088)
+#define PRCM_PLLDDR_FREQ_REG		(PRCMU_BASE + 0x08C)
+#define PRCM_ARM_CHGCLKREQ_REG		(PRCMU_BASE + 0x114)
+
+#define PRCM_TCR			(PRCMU_BASE + 0x1C8)
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR			0x80156000
+#define DMC_CTL_97			(DMC_BASE_ADDR + 0x184)
+
+int board_id;	/* set in board_late_init() */
+
+/* PLLs for clock management registers */
+enum {
+	GATED = 0,
+	PLLSOC0,	/* pllsw = 001, ffs() = 1 */
+	PLLSOC1,	/* pllsw = 010, ffs() = 2 */
+	PLLDDR,		/* pllsw = 100, ffs() = 3 */
+	PLLARM,
+};
+
+static struct pll_freq_regs {
+	int idx;	/* index fror pll_name and pll_khz arrays */
+	uint32_t addr;
+} pll_freq_regs[] = {
+	{PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
+	{PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
+	{PLLDDR, PRCM_PLLDDR_FREQ_REG},
+	{PLLARM, PRCM_PLLARM_FREQ_REG},
+	{0, 0},
+};
+
+static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
+static uint32_t pll_khz[5];	/* use ffs(pllsw(reg)) as index for 0..3 */
+
+static struct clk_mgt_regs {
+	uint32_t addr;
+	uint32_t val;
+	const char *descr;
+} clk_mgt_regs[] = {
+	/* register content taken from bootrom settings */
+	{PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+	{PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+	{PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+	{PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+	{PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},	/* dis, SOC0/4, 200 MHz */
+	{PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},	/* ena, GATED, CLK38 */
+	{PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},	/* dis, GATED, CLK38 */
+	{PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},	/* ena, SOC0/16, 50 MHz */
+	{PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+	{PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},	/* ena, SOC0/8, 100 MHz */
+	{PRCM_DMACLK_MGT_REG, 0x125, "DMA"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},	/* dis, SOC0/5, 160 MHz */
+	{0, 0, NULL},
+};
+
+static void init_regs(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+static unsigned int read_asicid(void)
+{
+	unsigned int *address = (void *)U8500_BOOTROM_BASE
+				+ U8500_BOOTROM_ASIC_ID_OFFSET;
+	return readl(address);
+}
+
+int cpu_is_u8500v11(void)
+{
+	return read_asicid() == 0x008500A1;
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_early_init_f(void)
+{
+	init_regs();
+	return 0;
+}
+
+int board_init(void)
+{
+	uint32_t unused_cols_rows;
+	unsigned int nrows;
+	unsigned int ncols;
+
+	gd->bd->bi_arch_number = 0x1A4;
+	gd->bd->bi_boot_params = 0x00000100;
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+
+	/*
+	 * Assumption: 2 CS active, both CS have same layout.
+	 *             15 rows max, 11 cols max (controller spec).
+	 *             memory chip has 8 banks, I/O width 32 bit.
+	 * The correct way would be to read MR#8: I/O width and density,
+	 * but this requires locking against the PRCMU firmware.
+	 * Simplified approach:
+	 * Read number of unused rows and columns from mem controller.
+	 * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+	 */
+	unused_cols_rows = readl(DMC_CTL_97);
+	nrows = 15 - (unused_cols_rows & 0x07);
+	ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+	gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+	icache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+	return 0;
+}
+
+unsigned int addr_vall_arr[] = {
+	0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8011F008, 0x00001CFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8000F000, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x8000F008, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x80157020, 0x00000150, /* I2C 48MHz clock */
+	0x8012F000, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0x8012F008, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0xA03DF000, 0x0000000D, /* Clock for MTU Timers */
+	0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */
+	0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */
+	0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */
+	0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x801571E4, 0x0000000C, /* PRCMU settings for B2R2,
+				   PRCM_APE_RESETN_SET_REG */
+	0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */
+	0xA03FF000, 0x00000003, /* USB */
+	0xA03FF008, 0x00000001, /* USB */
+	0xA03FE00C, 0x00000000, /* USB */
+	0xA03FE020, 0x00000FFF, /* USB */
+	0xA03FE024, 0x00000000	/* USB */
+};
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_MASK		0x3
+#define LDO_VAUX3_ENABLE	0x1
+#define VAUX3_VOLTAGE_2_9V	0xd
+
+#define AB8500_REGU_CTRL2	0x4
+#define AB8500_REGU_VRF1VAUX3_REGU_REG	0x040A
+#define AB8500_REGU_VRF1VAUX3_SEL_REG	0x0421
+
+static int hrefplus_mmc_power_init(void)
+{
+	int ret;
+	int val;
+
+	if (!cpu_is_u8500v11())
+		return 0;
+
+	/*
+	 * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
+	 * card to work.  This is done by enabling the regulators in the AB8500
+	 * via PRCMU I2C transactions.
+	 *
+	 * This code is derived from the handling of AB8500_LDO_VAUX3 in
+	 * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+	 *
+	 * Turn off and delay is required to have it work across soft reboots.
+	 */
+
+	ret = prcmu_i2c_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+	if (ret < 0)
+		goto out;
+
+	val = ret;
+
+	/* Turn off */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+				val & ~LDO_VAUX3_MASK);
+	if (ret < 0)
+		goto out;
+
+	udelay(10 * 1000);
+
+	/* Set the voltage to 2.9V */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_SEL_REG,
+				VAUX3_VOLTAGE_2_9V);
+	if (ret < 0)
+		goto out;
+
+	val = val & ~LDO_VAUX3_MASK;
+	val = val | LDO_VAUX3_ENABLE;
+
+	/* Turn on the supply */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+
+out:
+	return ret;
+}
+#endif
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+	uchar byte;
+
+	/*
+	 * Determine and set board_id environment variable
+	 * 0: mop500, 1: href500
+	 * Above boards have different GPIO expander chips which we can
+	 * distinguish by the chip id.
+	 *
+	 * The board_id environment variable is needed for the Linux bootargs.
+	 */
+	(void) i2c_set_bus_num(0);
+	(void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
+	if (byte == 0x01) {
+		board_id = 0;
+		setenv("board_id", "0");
+	} else {
+		board_id = 1;
+		setenv("board_id", "1");
+	}
+#ifdef CONFIG_MMC
+	hrefplus_mmc_power_init();
+
+	/*
+	 * config extended GPIO pins for level shifter and
+	 * SDMMC_ENABLE
+	 */
+	if (board_id == 0) {
+		/* MOP500 */
+		byte = 0x0c;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
+	} else {
+		/* HREF */
+		/* set the direction of GPIO KPY9 and KPY10 */
+		byte = 0x06;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
+		/* must be a multibyte access */
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
+						(uchar []) {0x06, 0x06}, 2);
+	}
+#endif /* CONFIG_MMC */
+	/*
+	 * Create a memargs variable which points uses either the memargs256 or
+	 * memargs512 environment variable, depending on the memory size.
+	 * memargs is used to build the bootargs, memargs256 and memargs512 are
+	 * stored in the environment.
+	 */
+	if (gd->bd->bi_dram[0].size == 0x10000000) {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
+		setenv("mem", "256M");
+	} else {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
+		setenv("mem", "512M");
+	}
+
+	return 0;
+}
+#endif /* BOARD_LATE_INIT */
+
+static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
+{
+	writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
+	writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
+}
+
+static void init_regs(void)
+{
+	/* FIXME Remove magic register array settings for ED also */
+	struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
+
+	/* Enable timers */
+	writel(1 << 17, &prcmu->tcr);
+
+	u8500_prcmu_enable(&prcmu->per1clk_mgt);
+	u8500_prcmu_enable(&prcmu->per2clk_mgt);
+	u8500_prcmu_enable(&prcmu->per3clk_mgt);
+	u8500_prcmu_enable(&prcmu->per5clk_mgt);
+	u8500_prcmu_enable(&prcmu->per6clk_mgt);
+	u8500_prcmu_enable(&prcmu->per7clk_mgt);
+
+	u8500_prcmu_enable(&prcmu->uartclk_mgt);
+	u8500_prcmu_enable(&prcmu->i2cclk_mgt);
+
+	u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
+
+	u8500_clock_enable(1, 9, -1);	/* GPIO0 */
+
+	u8500_clock_enable(2, 11, -1);	/* GPIO1 */
+
+	u8500_clock_enable(3, 8, -1);	/* GPIO2 */
+	u8500_clock_enable(5, 1, -1);	/* GPIO3 */
+
+	u8500_clock_enable(3, 6, 6);	/* UART2 */
+
+	gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
+	u8500_clock_enable(3, 3, 3);	/* I2C0 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
+	gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
+
+	u8500_clock_enable(1, 5, 5);	/* SDI0 */
+	u8500_clock_enable(2, 4, 2);	/* SDI4 */
+
+	u8500_clock_enable(6, 7, -1);	/* MTU0 */
+	u8500_clock_enable(3, 4, 4);	/* SDI2 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
+	gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+
+	/*
+	 * Enabling clocks for all devices which are AMBA devices in the
+	 * kernel.  Otherwise they will not get probe()'d because the
+	 * peripheral ID register will not be powered.
+	 */
+
+	/* XXX: some of these differ between ED/V1 */
+
+	u8500_clock_enable(1, 1, 1);	/* UART1 */
+	u8500_clock_enable(1, 0, 0);	/* UART0 */
+
+	u8500_clock_enable(3, 2, 2);	/* SSP1 */
+	u8500_clock_enable(3, 1, 1);	/* SSP0 */
+
+	u8500_clock_enable(2, 8, -1);	/* SPI0 */
+	u8500_clock_enable(2, 5, 3);	/* MSP2 */
+}
+
+#ifdef CONFIG_MMC
+static int u8500_mmci_board_init(void)
+{
+	enum gpio_error error;
+	struct gpio_register *gpio_base_address;
+
+	gpio_base_address = (void *)(U8500_GPIO_0_BASE);
+	gpio_base_address->gpio_dats |= 0xFFC0000;
+	gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+	/* save the GPIO0 AFSELA register */
+	error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+	if (error != GPIO_OK) {
+		printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int board_mmc_init(bd_t *bd)
+{
+	if (u8500_mmci_board_init())
+		return -ENODEV;
+
+	if (arm_pl180_mmci_init())
+		return -ENODEV;
+	return 0;
+}
+#endif
+
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+	uint32_t idf, ldf, odf, seldiv, phi;
+
+	/*
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+	 * where:
+	 * IDF=R(2:0) (when R=000, IDF=1d)
+	 * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+	 * ODF = N(5:0) (when N=000000, 0DF=1d)
+	 */
+
+	idf = (freq_reg & 0x70000) >> 16;
+	ldf = (freq_reg & 0xff) * 2;
+	odf = (freq_reg & 0x3f00) >> 8;
+	seldiv = (freq_reg & 0x01000000) >> 24;
+	phi = (inclk_khz * ldf) / (2 * odf * idf);
+	if (seldiv)
+		phi = phi/2;
+
+	return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t inclk_khz;
+	uint32_t reg, phi;
+	uint32_t clk_khz;
+	unsigned int clk_sel;
+	struct clk_mgt_regs *clks = clk_mgt_regs;
+	struct pll_freq_regs *plls = pll_freq_regs;
+
+	/*
+	 * Go through list of PLLs.
+	 * Initialise pll out frequency array (pll_khz) and print frequency.
+	 */
+	inclk_khz = 38400;	/* 38.4 MHz */
+	while (plls->addr) {
+		reg = readl(plls->addr);
+		phi = get_pll_freq_khz(inclk_khz, reg);
+		pll_khz[plls->idx] = phi;
+		printf("%s PLL out frequency: %d.%d Mhz\n",
+				pll_name[plls->idx], phi/1000, phi % 1000);
+		plls++;
+	}
+
+	/* check ARM clock source */
+	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
+	printf("A9 running on %s\n",
+		(reg & 1) ?  "external clock" : "ARM PLL");
+
+	/* go through list of clk_mgt_reg */
+	printf("\n%19s %9s %7s %9s enabled\n",
+			"name(addr)", "value", "PLL", "CLK[MHz]");
+	while (clks->addr) {
+		reg = readl(clks->addr);
+
+		/* convert bit position into array index */
+		clk_sel = ffs((reg >> 5) & 0x7);	/* PLLSW[2:0] */
+
+		if (reg & 0x200)
+			clk_khz = 38400;	/* CLK38 is set */
+		else if ((reg & 0x1f) == 0)
+			/* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+			clk_khz = 0;
+		else
+			clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
+
+		printf("%9s(%08x): %08x, %6s, %4d.%03d, %s\n",
+			clks->descr, clks->addr, reg, pll_name[clk_sel],
+			clk_khz / 1000, clk_khz % 1000,
+			(reg & 0x100) ? "ena" : "dis");
+		clks++;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clkinfo,	1,	1,	do_clkinfo,
+	"print clock info",
+	""
+);
diff --git a/boards.cfg b/boards.cfg
index a45bd83..1259e96 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -130,6 +130,7 @@ smdkc100                     arm         armv7       smdkc100            samsung
 s5pc210_universal            arm         armv7       universal_c210      samsung        s5pc2xx
 harmony                      arm         armv7       harmony             nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
+u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 actux1                       arm         ixp
 actux2                       arm         ixp
 actux3                       arm         ixp
diff --git a/include/configs/u8500_href.h b/include/configs/u8500_href.h
new file mode 100644
index 0000000..636922c
--- /dev/null
+++ b/include/configs/u8500_href.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_U8500
+#define CONFIG_L2_OFF
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF
+#define CONFIG_SYS_HZ		1000		/* must be 1000 */
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define BOARD_LATE_INIT
+
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE		(32*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE		(128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* for initial data */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL_RLCR
+#define CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE		0x80120000
+#define CFG_UART1_BASE		0x80121000
+#define CFG_UART2_BASE		0x80007000
+#define CFG_SERIAL0		CFG_UART0_BASE
+#define CFG_SERIAL1		CFG_UART1_BASE
+#define CFG_SERIAL2		CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK	38400000
+#define CONFIG_PL01x_PORTS	{ (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+				  (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY	1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=n\0"							\
+	"loadaddr=0x00100000\0"						\
+	"console=ttyAMA2,115200n8\0"					\
+	"memargs256=mem=96M at 0 mem_modem=32M at 96M mem=30M at 128M "		\
+		"pmem=22M at 158M pmem_hwb=44M at 180M mem_mali=32 at 224M\0"	\
+	"memargs512=mem=96M at 0 mem_modem=32M at 96M mem=44M at 128M "		\
+		"pmem=22M at 172M mem=30M at 194M mem_mali=32M at 224M "		\
+		"pmem_hwb=54M at 256M mem=202M at 310M\0"			\
+	"commonargs=setenv bootargs cachepolicy=writealloc noinitrd "	\
+		"init=init "						\
+		"board_id=${board_id} "					\
+		"logo.${logo} "						\
+		"startup_graphics=${startup_graphics}\0"		\
+	"emmcargs=setenv bootargs ${bootargs} "				\
+		"root=/dev/mmcblk0p2 "					\
+		"rootdelay=1\0"						\
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console}\0"					\
+	"emmcboot=echo Booting from eMMC ...; "				\
+		"run commonargs emmcargs addcons memargs;"		\
+		"mmc read 0 ${loadaddr} 0xA0000 0x4000;"		\
+		"bootm ${loadaddr}\0"					\
+	"flash=mmc init 1;fatload mmc 1 ${loadaddr} flash.scr;"		\
+		"source ${loadaddr}\0"					\
+	"loaduimage=mmc init 1;fatload mmc 1 ${loadaddr} uImage\0"	\
+	"usbtty=cdc_acm\0"						\
+	"stdout=serial,usbtty\0"					\
+	"stdin=serial,usbtty\0"						\
+	"stderr=serial,usbtty\0"
+
+/*
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory     */
+#define CONFIG_SYS_PROMPT	"U8500 $ "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O Buffer Size  */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef	CONFIG_SYS_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR		0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS	2
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG			/* enable passing of ATAGs  */
+
+/*
+ * I2C
+ */
+#define CONFIG_U8500_I2C
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support */
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0	/* slave addr of controller */
+#define CONFIG_SYS_U8500_I2C0_BASE		0x80004000
+#define CONFIG_SYS_U8500_I2C1_BASE		0x80122000
+#define CONFIG_SYS_U8500_I2C2_BASE		0x80128000
+#define CONFIG_SYS_U8500_I2C3_BASE		0x80110000
+#define CONFIG_SYS_U8500_I2C_BUS_MAX		4
+
+#define CONFIG_SYS_I2C_GPIOE_ADDR	0x42	/* GPIO expander chip addr */
+#define CONFIG_TC35892_GPIO
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ		(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ		(4*1024)	/* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1		0x20000000	/* 512 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE            0x0
+#endif
+
+/*
+ * MMC related configs
+ * NB Only externa SD slot is currently supported
+ */
+#define MMC_BLOCK_SIZE			512
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x80126000	/* MMC base for 8500  */
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
+#define CONFIG_MMC_DEV_NUM		1
+
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_SAVEENV	/* CMD_ENV is obsolete but used in env_emmc.c */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET		0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV          0               /* SLOT2: eMMC */
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   management unit */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+#endif	/* __CONFIG_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
@ 2011-04-12  6:47     ` Heiko Schocher
  0 siblings, 0 replies; 42+ messages in thread
From: Heiko Schocher @ 2011-04-12  6:47 UTC (permalink / raw)
  To: u-boot

Hello John,

John Rigby wrote:
> From: Michael Brandt <michael.brandt@stericsson.com>
> 
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> CC: Heiko Schocher <hs@denx.de>
> ---
> v2: Incorporate suggestions from Heiko Schocher
> v3: Fix line length problem reported by Heiko Schocher
>  drivers/i2c/Makefile    |    1 +
>  drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
>  drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
>  3 files changed, 808 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/i2c/u8500_i2c.c
>  create mode 100644 drivers/i2c/u8500_i2c.h

Thanks!

Acked-by: Heiko Schocher <hs@denx.de>

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-04-12  7:25     ` Albert ARIBAUD
  0 siblings, 0 replies; 42+ messages in thread
From: Albert ARIBAUD @ 2011-04-12  7:25 UTC (permalink / raw)
  To: u-boot

Hi John,

Le 12/04/2011 08:17, John Rigby a ?crit :

> diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S
> new file mode 100644
> index 0000000..0e3f8fc
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/u8500/lowlevel.S
> @@ -0,0 +1,33 @@
> +/*
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */

Please add a copyright notice identifying the right holder(s). Readers 
*must* be able to tell who the rights holders are and how to contact 
them -- don't assume the file is too simple to qualify.

> diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c
> new file mode 100644
> index 0000000..8850fd5
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/u8500/timer.c
> @@ -0,0 +1,167 @@
> +/*
> + * Copyright (C) 2010 Linaro Limited
> + * John Rigby<john.rigby@linaro.org>
> + *
> + * Based on original from Linux kernel source and
> + * internal ST-Ericsson U-Boot source.
> + * (C) Copyright 2009 Alessandro Rubini
> + * (C) Copyright 2010 ST-Ericsson
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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<asm/io.h>
> +#include<asm/arch/hardware.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/*
> + * The MTU device has some interrupt control registers
> + * followed by 4 timers.
> + */
> +
> +/* The timers */
> +struct u8500_mtu_timer {
> +	u32 lr;			/* Load value */
> +	u32 cv;			/* Current value */
> +	u32 cr;			/* Control reg */
> +	u32 bglr;		/* ??? */
> +};
> +
> +/* The MTU that contains the timers */
> +struct u8500_mtu {
> +	u32 imsc;		/* Interrupt mask set/clear */
> +	u32 ris;		/* Raw interrupt status */
> +	u32 mis;		/* Masked interrupt status */
> +	u32 icr;		/* Interrupt clear register */
> +	struct u8500_mtu_timer pt[4];
> +};
> +
> +/* bits for the control register */
> +#define MTU_CR_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR */
> +#define MTU_CR_32BITS		0x02
> +
> +#define MTU_CR_PRESCALE_1	0x00
> +#define MTU_CR_PRESCALE_16	0x04
> +#define MTU_CR_PRESCALE_256	0x08
> +#define MTU_CR_PRESCALE_MASK	0x0c
> +
> +#define MTU_CR_PERIODIC		0x40	/* if 0 = free-running */
> +#define MTU_CR_ENA		0x80
> +
> +/*
> + * The MTU is clocked at 133 MHz by default. (V1 and later)
> + */
> +#define TIMER_CLOCK		(133 * 1000 * 1000 / 16)
> +#define COUNT_TO_USEC(x)	((x) * 16 / 133)
> +#define USEC_TO_COUNT(x)	((x) * 133 / 16)
> +#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
> +#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
> +#define TIMER_LOAD_VAL		0xffffffff
> +
> +/*
> + * MTU timer to use (from 0 to 3).
> + * Linux ux500 timer0 on MTU0 and timer0 on MTU1

If you really mean the same timer for both, please explicitly state 
"timer0 for both MTU0 and MTU1", otherwise fix.

> + */
> +#define MTU_TIMER 2
> +
> +static struct u8500_mtu_timer *timer_base =
> +	&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
> +
> +/* macro to read the 32 bit timer: since it decrements, we invert read value */
> +#define READ_TIMER() (~readl(&timer_base->cv))
> +
> +/* Configure a free-running, auto-wrap counter with /16 prescaler */
> +int timer_init(void)
> +{
> +	writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
> +	&timer_base->cr);
> +	reset_timer();
> +	return 0;
> +}
> +
> +ulong get_timer_masked(void)
> +{
> +	/* current tick value */
> +	ulong now = TICKS_TO_HZ(READ_TIMER());
> +
> +	if (now>= gd->lastinc)	/* normal (non rollover) */
> +		gd->tbl += (now - gd->lastinc);
> +	else			/* rollover */
> +		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
> +	gd->lastinc = now;
> +	return gd->tbl;
> +}
> +
> +/* Delay x useconds */
> +void __udelay(ulong usec)
> +{
> +	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
> +	ulong now, last = READ_TIMER();
> +
> +	while (tmo>  0) {
> +		now = READ_TIMER();
> +		if (now>  last)	/* normal (non rollover) */
> +			tmo -= now - last;
> +		else		/* rollover */
> +			tmo -= TIMER_LOAD_VAL - last + now;
> +		last = now;
> +	}
> +}
> +
> +ulong get_timer(ulong base)
> +{
> +	return get_timer_masked() - base;
> +}
> +
> +void set_timer(ulong t)
> +{
> +	gd->tbl = t;
> +}
> +
> +void reset_timer_masked(void)
> +{
> +	gd->lastinc = TICKS_TO_HZ(READ_TIMER());
> +	gd->tbl = 0;		/* reset ticks to 0 */
> +}
> +
> +void reset_timer(void)
> +{
> +	reset_timer_masked();
> +}

Please remove these reset_timer functions and in the client code. 
Resetting a timer is never useful for timing loops. Client code that 
resets the timer must be fixed.

Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (5 preceding siblings ...)
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
@ 2011-04-19 20:42   ` John Rigby
  2011-04-19 20:59     ` Kumar Gala
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
                     ` (3 subsequent siblings)
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-19 20:42 UTC (permalink / raw)
  To: u-boot

Two new options:

CONFIG_PL011_SERIAL_RLCR

Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
have separate receive and transmit line control registers.  Set
this variable to initialize the extra register.

CONFIG_PL011_SERIAL_FLUSH_ON_INIT

On some platforms (e.g. U8500) U-Boot is loaded by a second stage
boot loader that has already initialized the UART.  Define this
variable to flush the UART at init time.
empty fifo on init

Signed-off-by: John Rigby <john.rigby@linaro.org>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v2: No changes
v3: Enable changes with new CONFIG_* options instead of platform.
Document new CONFIG_* options in README.
v4: Added delay before writing to RLCR.
Removed Rabin as author at his request.

 README                        |   12 ++++++++++++
 drivers/serial/serial_pl01x.c |   30 +++++++++++++++++++++++++++---
 drivers/serial/serial_pl01x.h |    4 ++++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/README b/README
index 4917e26..496a428 100644
--- a/README
+++ b/README
@@ -468,6 +468,18 @@ The following options need to be configured:
 		define this to a list of base addresses for each (supported)
 		port. See e.g. include/configs/versatile.h
 
+		CONFIG_PL011_SERIAL_RLCR
+
+		Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
+		have separate receive and transmit line control registers.  Set
+		this variable to initialize the extra register.
+
+		CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+		On some platforms (e.g. U8500) U-Boot is loaded by a second stage
+		boot loader that has already initialized the UART.  Define this
+		variable to flush the UART at init time.
+
 
 - Console Interface:
 		Depending on board, define exactly one serial port
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 5dfcde8..7a064ff 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -111,6 +111,15 @@ int serial_init (void)
 	unsigned int divider;
 	unsigned int remainder;
 	unsigned int fraction;
+	unsigned int lcr;
+
+#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+	/* Empty RX fifo if necessary */
+	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+			readl(&regs->dr);
+	}
+#endif
 
 	/* First, disable everything */
 	writel(0, &regs->pl011_cr);
@@ -131,9 +140,24 @@ int serial_init (void)
 	writel(fraction, &regs->pl011_fbrd);
 
 	/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
-	writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN,
-	       &regs->pl011_lcrh);
-
+	lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
+	writel(lcr, &regs->pl011_lcrh);
+
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	{
+		int i;
+
+		/*
+		 * Program receive line control register after waiting
+		 * 10 bus cycles.  Delay be writing to readonly register
+		 * 10 times
+		 */
+		for (i = 0; i < 10; i++)
+			writel(lcr, &regs->fr);
+
+		writel(lcr, &regs->pl011_rlcr);
+	}
+#endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
 	       &regs->pl011_cr);
diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h
index b670c24..96ee381 100644
--- a/drivers/serial/serial_pl01x.h
+++ b/drivers/serial/serial_pl01x.h
@@ -43,7 +43,11 @@ struct pl01x_regs {
 	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
 	u32	pl010_cr;	/* 0x14 Control register */
 	u32	fr;		/* 0x18 Flag register (Read only) */
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	u32	pl011_rlcr;	/* 0x1c Receive line control register */
+#else
 	u32	reserved;
+#endif
 	u32	ilpr;		/* 0x20 IrDA low-power counter register */
 	u32	pl011_ibrd;	/* 0x24 Integer baud rate register */
 	u32	pl011_fbrd;	/* 0x28 Fractional baud rate register */
-- 
1.7.1

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

* [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (6 preceding siblings ...)
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options John Rigby
@ 2011-04-19 20:42   ` John Rigby
  2011-05-19 21:54     ` John Rigby
  2011-06-01 17:34     ` Albert ARIBAUD
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
                     ` (2 subsequent siblings)
  10 siblings, 2 replies; 42+ messages in thread
From: John Rigby @ 2011-04-19 20:42 UTC (permalink / raw)
  To: u-boot

Based on ST-Ericsson internal git repo.

Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
v2: cleanup, mostly removal of unused defines
v3: remove prototype from sys_proto.h as suggested by Wolfgang
v4: incorporate changes suggested by Albert:
  Add copyright to arch/arm/cpu/armv7/u8500/lowlevel.S
  Remove confusing/incorrect timer comment in arch/arm/cpu/armv7/u8500/timer.c
  Remove reset timer functions from ..../timer.c

 arch/arm/cpu/armv7/u8500/Makefile           |   46 +++++
 arch/arm/cpu/armv7/u8500/clock.c            |   56 ++++++
 arch/arm/cpu/armv7/u8500/lowlevel.S         |   35 ++++
 arch/arm/cpu/armv7/u8500/timer.c            |  154 +++++++++++++++++
 arch/arm/include/asm/arch-u8500/clock.h     |   72 ++++++++
 arch/arm/include/asm/arch-u8500/gpio.h      |  247 +++++++++++++++++++++++++++
 arch/arm/include/asm/arch-u8500/hardware.h  |   83 +++++++++
 arch/arm/include/asm/arch-u8500/sys_proto.h |   27 +++
 arch/arm/include/asm/arch-u8500/u8500.h     |   47 +++++
 9 files changed, 767 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
 create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
 create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
 create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
 create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
 create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
 create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
 create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h

diff --git a/arch/arm/cpu/armv7/u8500/Makefile b/arch/arm/cpu/armv7/u8500/Makefile
new file mode 100644
index 0000000..270aa40
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2006
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(SOC).o
+
+COBJS	= timer.o clock.o
+SOBJS	= lowlevel.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(SOBJS))
+
+all:	$(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/u8500/clock.c b/arch/arm/cpu/armv7/u8500/clock.c
new file mode 100644
index 0000000..9e3b873
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/clock.c
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2009 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct clkrst {
+	unsigned int pcken;
+	unsigned int pckdis;
+	unsigned int kcken;
+	unsigned int kckdis;
+};
+
+static unsigned int clkrst_base[] = {
+	U8500_CLKRST1_BASE,
+	U8500_CLKRST2_BASE,
+	U8500_CLKRST3_BASE,
+	0,
+	U8500_CLKRST5_BASE,
+	U8500_CLKRST6_BASE,
+	U8500_CLKRST7_BASE,	/* ED only */
+};
+
+/* Turn on peripheral clock at PRCC level */
+void u8500_clock_enable(int periph, int cluster, int kern)
+{
+	struct clkrst *clkrst = (struct clkrst *) clkrst_base[periph - 1];
+
+	if (kern != -1)
+		writel(1 << kern, &clkrst->kcken);
+
+	if (cluster != -1)
+		writel(1 << cluster, &clkrst->pcken);
+}
diff --git a/arch/arm/cpu/armv7/u8500/lowlevel.S b/arch/arm/cpu/armv7/u8500/lowlevel.S
new file mode 100644
index 0000000..743071c
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/lowlevel.S
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2011 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+
+.globl lowlevel_init
+lowlevel_init:
+	mov	pc, lr
+
+	.align	5
+.globl reset_cpu
+reset_cpu:
+        ldr r0, =CFG_PRCMU_BASE
+        ldr r1, =0x1
+        str r1, [r0, #0x228]
+_loop_forever:
+	b	_loop_forever
diff --git a/arch/arm/cpu/armv7/u8500/timer.c b/arch/arm/cpu/armv7/u8500/timer.c
new file mode 100644
index 0000000..8e96eaa
--- /dev/null
+++ b/arch/arm/cpu/armv7/u8500/timer.c
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2010 Linaro Limited
+ * John Rigby <john.rigby@linaro.org>
+ *
+ * Based on original from Linux kernel source and
+ * internal ST-Ericsson U-Boot source.
+ * (C) Copyright 2009 Alessandro Rubini
+ * (C) Copyright 2010 ST-Ericsson
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/io.h>
+#include <asm/arch/hardware.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * The MTU device has some interrupt control registers
+ * followed by 4 timers.
+ */
+
+/* The timers */
+struct u8500_mtu_timer {
+	u32 lr;			/* Load value */
+	u32 cv;			/* Current value */
+	u32 cr;			/* Control reg */
+	u32 bglr;		/* ??? */
+};
+
+/* The MTU that contains the timers */
+struct u8500_mtu {
+	u32 imsc;		/* Interrupt mask set/clear */
+	u32 ris;		/* Raw interrupt status */
+	u32 mis;		/* Masked interrupt status */
+	u32 icr;		/* Interrupt clear register */
+	struct u8500_mtu_timer pt[4];
+};
+
+/* bits for the control register */
+#define MTU_CR_ONESHOT		0x01	/* if 0 = wraps reloading from BGLR */
+#define MTU_CR_32BITS		0x02
+
+#define MTU_CR_PRESCALE_1	0x00
+#define MTU_CR_PRESCALE_16	0x04
+#define MTU_CR_PRESCALE_256	0x08
+#define MTU_CR_PRESCALE_MASK	0x0c
+
+#define MTU_CR_PERIODIC		0x40	/* if 0 = free-running */
+#define MTU_CR_ENA		0x80
+
+/*
+ * The MTU is clocked at 133 MHz by default. (V1 and later)
+ */
+#define TIMER_CLOCK		(133 * 1000 * 1000 / 16)
+#define COUNT_TO_USEC(x)	((x) * 16 / 133)
+#define USEC_TO_COUNT(x)	((x) * 133 / 16)
+#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
+#define TIMER_LOAD_VAL		0xffffffff
+
+/*
+ * MTU timer to use (from 0 to 3).
+ */
+#define MTU_TIMER 2
+
+static struct u8500_mtu_timer *timer_base =
+	&((struct u8500_mtu *)U8500_MTU0_BASE_V1)->pt[MTU_TIMER];
+
+/* macro to read the 32 bit timer: since it decrements, we invert read value */
+#define READ_TIMER() (~readl(&timer_base->cv))
+
+/* Configure a free-running, auto-wrap counter with /16 prescaler */
+int timer_init(void)
+{
+	writel(MTU_CR_ENA | MTU_CR_PRESCALE_16 | MTU_CR_32BITS,
+	       &timer_base->cr);
+	return 0;
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = TICKS_TO_HZ(READ_TIMER());
+
+	if (now >= gd->lastinc)	/* normal (non rollover) */
+		gd->tbl += (now - gd->lastinc);
+	else			/* rollover */
+		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
+	gd->lastinc = now;
+	return gd->tbl;
+}
+
+/* Delay x useconds */
+void __udelay(ulong usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	ulong now, last = READ_TIMER();
+
+	while (tmo > 0) {
+		now = READ_TIMER();
+		if (now > last)	/* normal (non rollover) */
+			tmo -= now - last;
+		else		/* rollover */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+void set_timer(ulong t)
+{
+	gd->tbl = t;
+}
+
+/*
+ * Emulation of Power architecture long long timebase.
+ *
+ * TODO: Support gd->tbu for real long long timebase.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * Emulation of Power architecture timebase.
+ * NB: Low resolution compared to Power tbclk.
+ */
+ulong get_tbclk(void)
+{
+	return CONFIG_SYS_HZ;
+}
diff --git a/arch/arm/include/asm/arch-u8500/clock.h b/arch/arm/include/asm/arch-u8500/clock.h
new file mode 100644
index 0000000..b00ab0d
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/clock.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __ASM_ARCH_CLOCK
+#define __ASM_ARCH_CLOCK
+
+struct prcmu {
+	unsigned int armclkfix_mgt;
+	unsigned int armclk_mgt;
+	unsigned int svammdspclk_mgt;
+	unsigned int siammdspclk_mgt;
+	unsigned int reserved;
+	unsigned int sgaclk_mgt;
+	unsigned int uartclk_mgt;
+	unsigned int msp02clk_mgt;
+	unsigned int i2cclk_mgt;
+	unsigned int sdmmcclk_mgt;
+	unsigned int slimclk_mgt;
+	unsigned int per1clk_mgt;
+	unsigned int per2clk_mgt;
+	unsigned int per3clk_mgt;
+	unsigned int per5clk_mgt;
+	unsigned int per6clk_mgt;
+	unsigned int per7clk_mgt;
+	unsigned int lcdclk_mgt;
+	unsigned int reserved1;
+	unsigned int bmlclk_mgt;
+	unsigned int hsitxclk_mgt;
+	unsigned int hsirxclk_mgt;
+	unsigned int hdmiclk_mgt;
+	unsigned int apeatclk_mgt;
+	unsigned int apetraceclk_mgt;
+	unsigned int mcdeclk_mgt;
+	unsigned int ipi2cclk_mgt;
+	unsigned int dsialtclk_mgt;
+	unsigned int spare2clk_mgt;
+	unsigned int dmaclk_mgt;
+	unsigned int b2r2clk_mgt;
+	unsigned int tvclk_mgt;
+	unsigned int unused[82];
+	unsigned int tcr;
+	unsigned int unused1[23];
+	unsigned int ape_softrst;
+};
+
+extern void u8500_clock_enable(int periph, int kern, int cluster);
+
+static inline void u8500_prcmu_enable(unsigned int *reg)
+{
+	writel(readl(reg) | (1 << 8), reg);
+}
+
+#endif /* __ASM_ARCH_CLOCK */
diff --git a/arch/arm/include/asm/arch-u8500/gpio.h b/arch/arm/include/asm/arch-u8500/gpio.h
new file mode 100644
index 0000000..769def1
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/gpio.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _UX500_GPIO_h
+#define _UX500_GPIO_h
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/arch/u8500.h>
+
+#define GPIO_TOTAL_PINS                 268
+
+#define GPIO_PINS_PER_BLOCK	32
+#define GPIO_BLOCKS_COUNT       (GPIO_TOTAL_PINS/GPIO_PINS_PER_BLOCK + 1)
+#define GPIO_BLOCK(pin)		(((pin + GPIO_PINS_PER_BLOCK) >> 5) - 1)
+
+
+struct gpio_register {
+	u32 gpio_dat;	/* data register *//*0x000 */
+	u32 gpio_dats;	/* data Set register *//*0x004 */
+	u32 gpio_datc;	/* data Clear register *//*0x008 */
+	u32 gpio_pdis;	/* Pull disable register *//*0x00C */
+	u32 gpio_dir;	/* data direction register *//*0x010 */
+	u32 gpio_dirs;	/* data dir Set register *//*0x014 */
+	u32 gpio_dirc;	/* data dir Clear register *//*0x018 */
+	u32 gpio_slpm;	/* Sleep mode register *//*0x01C */
+	u32 gpio_afsa;	/* AltFun A Select reg *//*0x020 */
+	u32 gpio_afsb;	/* AltFun B Select reg *//*0x024 */
+	u32 gpio_lowemi;/* low EMI Select reg *//*0x028 */
+	u32 reserved_1[(0x040 - 0x02C) >> 2];	/*0x028-0x3C Reserved*/
+	u32 gpio_rimsc;	/* rising edge intr set/clear *//*0x040 */
+	u32 gpio_fimsc;	/* falling edge intr set/clear register *//*0x044 */
+	u32 gpio_mis;	/* masked interrupt status register *//*0x048 */
+	u32 gpio_ic;	/* Interrupt Clear register *//*0x04C */
+	u32 gpio_rwimsc;/* Rising-edge Wakeup IMSC register *//*0x050 */
+	u32 gpio_fwimsc;/* Falling-edge Wakeup IMSC register *//*0x054 */
+	u32 gpio_wks;	/* Wakeup Status register *//*0x058 */
+};
+
+/* Error values returned by functions */
+enum gpio_error {
+	GPIO_OK = 0,
+	GPIO_UNSUPPORTED_HW = -2,
+	GPIO_UNSUPPORTED_FEATURE = -3,
+	GPIO_INVALID_PARAMETER = -4,
+	GPIO_REQUEST_NOT_APPLICABLE = -5,
+	GPIO_REQUEST_PENDING = -6,
+	GPIO_NOT_CONFIGURED = -7,
+	GPIO_INTERNAL_ERROR = -8,
+	GPIO_INTERNAL_EVENT = 1,
+	GPIO_REMAINING_EVENT = 2,
+	GPIO_NO_MORE_PENDING_EVENT = 3,
+	GPIO_INVALID_CLIENT = -25,
+	GPIO_INVALID_PIN = -26,
+	GPIO_PIN_BUSY = -27,
+	GPIO_PIN_NOT_ALLOCATED = -28,
+	GPIO_WRONG_CLIENT = -29,
+	GPIO_UNSUPPORTED_ALTFUNC = -30,
+};
+
+/*GPIO DEVICE ID */
+enum gpio_device_id {
+	GPIO_DEVICE_ID_0,
+	GPIO_DEVICE_ID_1,
+	GPIO_DEVICE_ID_2,
+	GPIO_DEVICE_ID_3,
+	GPIO_DEVICE_ID_INVALID
+};
+
+/*
+ * Alternate Function:
+ *  refered in altfun_table to pointout particular altfun to be enabled
+ *  when using GPIO_ALT_FUNCTION A/B/C enable/disable operation
+ */
+enum gpio_alt_function {
+	GPIO_ALT_UART_0_MODEM,
+	GPIO_ALT_UART_0_NO_MODEM,
+	GPIO_ALT_UART_1,
+	GPIO_ALT_UART_2,
+	GPIO_ALT_I2C_0,
+	GPIO_ALT_I2C_1,
+	GPIO_ALT_I2C_2,
+	GPIO_ALT_I2C_3,
+	GPIO_ALT_MSP_0,
+	GPIO_ALT_MSP_1,
+	GPIO_ALT_MSP_2,
+	GPIO_ALT_MSP_3,
+	GPIO_ALT_MSP_4,
+	GPIO_ALT_MSP_5,
+	GPIO_ALT_SSP_0,
+	GPIO_ALT_SSP_1,
+	GPIO_ALT_MM_CARD0,
+	GPIO_ALT_SD_CARD0,
+	GPIO_ALT_DMA_0,
+	GPIO_ALT_DMA_1,
+	GPIO_ALT_HSI0,
+	GPIO_ALT_CCIR656_INPUT,
+	GPIO_ALT_CCIR656_OUTPUT,
+	GPIO_ALT_LCD_PANEL,
+	GPIO_ALT_MDIF,
+	GPIO_ALT_SDRAM,
+	GPIO_ALT_HAMAC_AUDIO_DBG,
+	GPIO_ALT_HAMAC_VIDEO_DBG,
+	GPIO_ALT_CLOCK_RESET,
+	GPIO_ALT_TSP,
+	GPIO_ALT_IRDA,
+	GPIO_ALT_USB_MINIMUM,
+	GPIO_ALT_USB_I2C,
+	GPIO_ALT_OWM,
+	GPIO_ALT_PWL,
+	GPIO_ALT_FSMC,
+	GPIO_ALT_COMP_FLASH,
+	GPIO_ALT_SRAM_NOR_FLASH,
+	GPIO_ALT_FSMC_ADDLINE_0_TO_15,
+	GPIO_ALT_SCROLL_KEY,
+	GPIO_ALT_MSHC,
+	GPIO_ALT_HPI,
+	GPIO_ALT_USB_OTG,
+	GPIO_ALT_SDIO,
+	GPIO_ALT_HSMMC,
+	GPIO_ALT_FSMC_ADD_DATA_0_TO_25,
+	GPIO_ALT_HSI1,
+	GPIO_ALT_NOR,
+	GPIO_ALT_NAND,
+	GPIO_ALT_KEYPAD,
+	GPIO_ALT_VPIP,
+	GPIO_ALT_CAM,
+	GPIO_ALT_CCP1,
+	GPIO_ALT_EMMC,
+	GPIO_ALT_POP_EMMC,
+	GPIO_ALT_FUNMAX		/* Add new alt func before this */
+};
+
+/* Defines pin assignment(Software mode or Alternate mode) */
+enum gpio_mode {
+	GPIO_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_MODE_SOFTWARE,	/* Pin connected to GPIO (SW controlled) */
+	GPIO_ALTF_A,		/* Pin connected to altfunc 1 (HW periph 1) */
+	GPIO_ALTF_B,		/* Pin connected to altfunc 2 (HW periph 2) */
+	GPIO_ALTF_C,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_FIND,		/* Pin connected to altfunc 3 (HW periph 3) */
+	GPIO_ALTF_DISABLE	/* Pin connected to altfunc 3 (HW periph 3) */
+};
+
+/* Defines GPIO pin direction */
+enum gpio_direction {
+	GPIO_DIR_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_DIR_INPUT,		/* GPIO set as input */
+	GPIO_DIR_OUTPUT		/* GPIO set as output */
+};
+
+/* Interrupt trigger mode */
+enum gpio_trig {
+	GPIO_TRIG_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_TRIG_DISABLE,	/* Trigger no IT */
+	GPIO_TRIG_RISING_EDGE,	/* Trigger an IT on rising edge */
+	GPIO_TRIG_FALLING_EDGE,	/* Trigger an IT on falling edge */
+	GPIO_TRIG_BOTH_EDGES,	/* Trigger an IT on rising and falling edge */
+	GPIO_TRIG_HIGH_LEVEL,	/* Trigger an IT on high level */
+	GPIO_TRIG_LOW_LEVEL	/* Trigger an IT on low level */
+};
+
+/* Configuration parameters for one GPIO pin.*/
+struct gpio_config {
+	enum gpio_mode mode;
+	enum gpio_direction direction;
+	enum gpio_trig trig;
+	char *dev_name;		/* Who owns the gpio pin */
+};
+
+/* GPIO pin data*/
+enum gpio_data {
+	GPIO_DATA_LOW,
+	GPIO_DATA_HIGH
+};
+
+/* GPIO behaviour in sleep mode */
+enum gpio_sleep_mode {
+	GPIO_SLEEP_MODE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_SLEEP_MODE_INPUT_DEFAULTVOLT,	/* GPIO is an input with pull
+						   up/down enabled when in sleep
+						   mode. */
+	GPIO_SLEEP_MODE_CONTROLLED_BY_GPIO	/* GPIO pin is controlled by
+						   GPIO IP. So mode, direction
+						   and data values for GPIO pin
+						   in sleep mode are determined
+						   by configuration set to GPIO
+						   pin before entering to sleep
+						   mode. */
+};
+
+/* GPIO ability to wake the system up from sleep mode.*/
+enum gpio_wake {
+	GPIO_WAKE_LEAVE_UNCHANGED,	/* Parameter will be ignored */
+	GPIO_WAKE_DISABLE,	/* No wake of system from sleep mode. */
+	GPIO_WAKE_LOW_LEVEL,	/* Wake the system up on a LOW level. */
+	GPIO_WAKE_HIGH_LEVEL,	/* Wake the system up on a HIGH level. */
+	GPIO_WAKE_RISING_EDGE,	/* Wake the system up on a RISING edge. */
+	GPIO_WAKE_FALLING_EDGE,	/* Wake the system up on a FALLING edge. */
+	GPIO_WAKE_BOTH_EDGES	/* Wake the system up on both RISE and FALL. */
+};
+
+/* Configuration parameters for one GPIO pin in sleep mode.*/
+struct gpio_sleep_config {
+	enum gpio_sleep_mode sleep_mode;/* GPIO behaviour in sleep mode. */
+	enum gpio_wake wake;		/* GPIO ability to wake up system. */
+};
+
+extern int gpio_setpinconfig(int pin_id, struct gpio_config *pin_config);
+extern int gpio_resetpinconfig(int pin_id, char *dev_name);
+extern int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name);
+extern int gpio_readpin(int pin_id, enum gpio_data *value);
+extern int gpio_altfuncenable(enum gpio_alt_function altfunc,
+				      char *dev_name);
+extern int gpio_altfuncdisable(enum gpio_alt_function altfunc,
+				       char *dev_name);
+
+struct gpio_altfun_data {
+	u16 altfun;
+	u16 start;
+	u16 end;
+	u16 cont;
+	u8 type;
+};
+#endif
diff --git a/arch/arm/include/asm/arch-u8500/hardware.h b/arch/arm/include/asm/arch-u8500/hardware.h
new file mode 100644
index 0000000..6bb95ec
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/hardware.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+/* Peripheral clusters */
+
+#define U8500_PER3_BASE		0x80000000
+#define U8500_PER2_BASE		0x80110000
+#define U8500_PER1_BASE		0x80120000
+#define U8500_PER4_BASE		0x80150000
+
+#define U8500_PER6_BASE		0xa03c0000
+#define U8500_PER7_BASE		0xa03d0000
+#define U8500_PER5_BASE		0xa03e0000
+
+/* GPIO */
+
+#define U8500_GPIO0_BASE	(U8500_PER1_BASE + 0xE000)
+#define U8500_GPIO1_BASE	(U8500_PER1_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO2_BASE	(U8500_PER3_BASE + 0xE000)
+#define U8500_GPIO3_BASE	(U8500_PER3_BASE + 0xE000 + 0x80)
+#define U8500_GPIO4_BASE	(U8500_PER3_BASE + 0xE000 + 0x100)
+#define U8500_GPIO5_BASE	(U8500_PER3_BASE + 0xE000 + 0x180)
+
+#define U8500_GPIO6_BASE	(U8500_PER2_BASE + 0xE000)
+#define U8500_GPIO7_BASE	(U8500_PER2_BASE + 0xE000 + 0x80)
+
+#define U8500_GPIO8_BASE	(U8500_PER5_BASE + 0x1E000)
+
+/* Per7 */
+#define U8500_CLKRST7_BASE	(U8500_PER7_BASE + 0xf000)
+
+/* Per6 */
+#define U8500_MTU0_BASE_V1	(U8500_PER6_BASE + 0x6000)
+#define U8500_MTU1_BASE_V1	(U8500_PER6_BASE + 0x7000)
+#define U8500_CLKRST6_BASE	(U8500_PER6_BASE + 0xf000)
+
+/* Per5 */
+#define U8500_CLKRST5_BASE	(U8500_PER5_BASE + 0x1f000)
+
+/* Per4 */
+#define U8500_PRCMU_BASE	(U8500_PER4_BASE + 0x07000)
+#define U8500_PRCMU_TCDM_BASE   (U8500_PER4_BASE + 0x0f000)
+
+/* Per3 */
+#define U8500_UART2_BASE	(U8500_PER3_BASE + 0x7000)
+#define U8500_CLKRST3_BASE	(U8500_PER3_BASE + 0xf000)
+
+/* Per2 */
+#define U8500_CLKRST2_BASE	(U8500_PER2_BASE + 0xf000)
+
+/* Per1 */
+#define U8500_UART0_BASE	(U8500_PER1_BASE + 0x0000)
+#define U8500_UART1_BASE	(U8500_PER1_BASE + 0x1000)
+#define U8500_CLKRST1_BASE	(U8500_PER1_BASE + 0xf000)
+
+/* Last page of Boot ROM */
+#define U8500_BOOTROM_BASE      0x9001f000
+#define U8500_BOOTROM_ASIC_ID_OFFSET    0x0ff4
+
+#endif /* __ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/include/asm/arch-u8500/sys_proto.h b/arch/arm/include/asm/arch-u8500/sys_proto.h
new file mode 100644
index 0000000..bac5e79
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/sys_proto.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void gpio_init(void);
+
+#endif  /* _SYS_PROTO_H_ */
diff --git a/arch/arm/include/asm/arch-u8500/u8500.h b/arch/arm/include/asm/arch-u8500/u8500.h
new file mode 100644
index 0000000..0d6dbb7
--- /dev/null
+++ b/arch/arm/include/asm/arch-u8500/u8500.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __U8500_H
+#define __U8500_H
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   Management Unit */
+#define CFG_SDRAMC_BASE		0x903CF000	/* SDRAMC cnf registers */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+/*
+ * U8500 GPIO register base for 9 banks
+ */
+#define U8500_GPIO_0_BASE			0x8012E000
+#define U8500_GPIO_1_BASE			0x8012E080
+#define U8500_GPIO_2_BASE			0x8000E000
+#define U8500_GPIO_3_BASE			0x8000E080
+#define U8500_GPIO_4_BASE			0x8000E100
+#define U8500_GPIO_5_BASE			0x8000E180
+#define U8500_GPIO_6_BASE			0x8011E000
+#define U8500_GPIO_7_BASE			0x8011E080
+#define U8500_GPIO_8_BASE			0xA03FE000
+
+#endif	/* __U8500_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (7 preceding siblings ...)
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-04-19 20:42   ` John Rigby
  2011-04-28 18:52     ` John Rigby
  2011-06-01 17:34     ` Albert ARIBAUD
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
  2011-05-12  8:05   ` [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options John Rigby
  10 siblings, 2 replies; 42+ messages in thread
From: John Rigby @ 2011-04-19 20:42 UTC (permalink / raw)
  To: u-boot

From: Michael Brandt <michael.brandt@stericsson.com>

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Heiko Schocher <hs@denx.de>
---
v2: Incorporate suggestions from Heiko Schocher
v3: Fix line length problem reported by Heiko Schocher
v4: No changes just rebased to latest and included for completeness
 drivers/i2c/Makefile    |    1 +
 drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
 drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
 3 files changed, 808 insertions(+), 0 deletions(-)
 create mode 100644 drivers/i2c/u8500_i2c.c
 create mode 100644 drivers/i2c/u8500_i2c.h

diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 052fe36..43507fc 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
 COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
 COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
 COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
+COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
new file mode 100644
index 0000000..ea8a71d
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.c
@@ -0,0 +1,613 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2010
+ *
+ * Basic U-Boot I2C interface for STn8500/DB8500
+ * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Only 7-bit I2C device addresses are supported.
+ */
+
+#include <common.h>
+#include <i2c.h>
+
+#include "u8500_i2c.h"
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+
+#define U8500_I2C_ENDAD_COUNTER	(CONFIG_SYS_HZ/100)	/* I2C bus timeout */
+#define U8500_I2C_FIFO_FLUSH_COUNTER	500000		/* flush "timeout" */
+#define U8500_I2C_SCL_FREQ		100000		/* I2C bus clock freq */
+#define U8500_I2C_INPUT_FREQ		48000000	/* Input clock freq */
+#define TX_FIFO_THRESHOLD	0x4
+#define RX_FIFO_THRESHOLD	0x4
+#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
+
+#define WRITE_FIELD(var, mask, shift, value) \
+			(var = ((var & ~(mask)) | ((value) << (shift))))
+
+static unsigned int bus_initialized[CONFIG_SYS_U8500_I2C_BUS_MAX];
+static unsigned int i2c_bus_num;
+static unsigned int i2c_bus_speed[] = {
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
+	CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
+};
+static struct u8500_i2c_regs *i2c_dev[] = {
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C0_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C1_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C2_BASE,
+	(struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C3_BASE,
+};
+
+static struct {
+	int periph;
+	int pcken;
+	int kcken;
+} i2c_clock_bits[] = {
+	{3, 3, 3}, /* I2C0 */
+	{1, 2, 2}, /* I2C1 */
+	{1, 6, 6}, /* I2C2 */
+	{2, 0, 0}, /* I2C3 */
+};
+
+static void i2c_set_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) | mask, reg);
+}
+
+static void i2c_clr_bit(void *reg, u32 mask)
+{
+	writel(readl(reg) & ~mask, reg);
+}
+
+static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
+{
+	writel((readl(reg) & ~mask) | (value << shift), reg);
+}
+
+static int __i2c_set_bus_speed(unsigned int speed)
+{
+	u32 value;
+	struct u8500_i2c_regs *i2c_regs;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Select standard (100 kbps) speed mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_SM,
+			U8500_I2C_CR_SHIFT_SM, 0x0);
+
+	/*
+	 * Set the Baud Rate Counter 2 value
+	 * Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
+	 * Foncycle = 0 (no digital filtering)
+	 */
+	value = (u32) (U8500_I2C_INPUT_FREQ / (speed * 2));
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT2,
+			U8500_I2C_BRCR_SHIFT_BRCNT2, value);
+
+	/* ensure that BRCNT value is zero */
+	i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT1,
+			U8500_I2C_BRCR_SHIFT_BRCNT1, 0);
+
+	return U8500_I2C_INPUT_FREQ/(value * 2);
+}
+
+/*
+ * i2c_init - initialize the i2c bus
+ *
+ *	speed: bus speed (in HZ)
+ *	slaveaddr: address of device in slave mode
+ *
+ *	Slave mode is not implemented.
+ */
+void i2c_init(int speed, int slaveaddr)
+{
+	struct u8500_i2c_regs *i2c_regs;
+
+	debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
+
+	u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
+			   i2c_clock_bits[i2c_bus_num].pcken,
+			   i2c_clock_bits[i2c_bus_num].kcken);
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Disable the controller */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	/* Clear registers */
+	writel(0, &i2c_regs->cr);
+	writel(0, &i2c_regs->scr);
+	writel(0, &i2c_regs->hsmcr);
+	writel(0, &i2c_regs->tftr);
+	writel(0, &i2c_regs->rftr);
+	writel(0, &i2c_regs->dmar);
+
+	i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
+
+	/*
+	 * Set our own address.
+	 * Set slave address mode to 7 bit addressing mode
+	 */
+	i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_SAM);
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_ADDR,
+			U8500_I2C_SCR_SHIFT_ADDR, slaveaddr);
+	/* Slave Data Set up Time */
+	i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_DATA_SETUP_TIME,
+			U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
+
+	/* Disable the DMA sync logic */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_DMA_SLE,
+			U8500_I2C_CR_SHIFT_DMA_SLE, 0);
+
+	/* Disable interrupts */
+	writel(0, &i2c_regs->imscr);
+
+	/* Configure bus master mode */
+	i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_OM, U8500_I2C_CR_SHIFT_OM,
+			U8500_I2C_BUS_MASTER_MODE);
+	/* Set FIFO threshold values */
+	writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
+	writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
+
+	/* Enable the I2C Controller */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
+
+	bus_initialized[i2c_bus_num] = 1;
+}
+
+
+/*
+ * loop_till_bit_clear - polls on a bit till it clears
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) == 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_clear timed out\n");
+	return -1;
+}
+
+/*
+ * loop_till_bit_set - polls on a bit till it is set.
+ * ioreg: register where you want to check status
+ * mask: bit mask for the bit you wish to check
+ * timeout: timeout in ticks/s
+ */
+static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
+{
+	unsigned long timebase = get_timer(0);
+
+	do {
+		if ((readl(io_reg) & mask) != 0x0UL)
+			return 0;
+	} while (get_timer(timebase) < timeout);
+
+	debug("loop_till_bit_set timed out\n");
+	return -1;
+}
+
+/*
+ * flush_fifo - flush the I2C TX and RX FIFOs
+ */
+static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
+{
+	int counter = U8500_I2C_FIFO_FLUSH_COUNTER;
+
+	/* Flush Tx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FTX);
+	/* Flush Rx FIFO */
+	i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FRX);
+	while (counter--) {
+		if (!(readl(&i2c_regs->cr) &
+				(U8500_I2C_CR_FTX | U8500_I2C_CR_FRX)))
+			break;
+	}
+	return;
+}
+
+#ifdef DEBUG
+static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
+{
+	int cause;
+
+	printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
+	cause = (readl(&i2c_regs->sr) & U8500_I2C_SR_CAUSE) >>
+				U8500_I2C_SR_SHIFT_CAUSE;
+	switch (cause) {
+	case U8500_I2C_NACK_ADDR:
+		printf("No Ack received after Slave Address xmission\n");
+		break;
+	case U8500_I2C_NACK_DATA:
+		printf("Valid for MASTER_WRITE: No Ack received "
+				"during data phase\n");
+		break;
+	case U8500_I2C_ACK_MCODE:
+		printf("Master recv ack after xmission of master code"
+				"in hs mode\n");
+		break;
+	case U8500_I2C_ARB_LOST:
+		printf("Master Lost arbitration\n");
+		break;
+	case U8500_I2C_BERR_START:
+		printf("Slave restarts\n");
+		break;
+	case U8500_I2C_BERR_STOP:
+		printf("Slave reset\n");
+		break;
+	case U8500_I2C_OVFL:
+		printf("Overflow\n");
+		break;
+	default:
+		printf("Unknown error type\n");
+	}
+}
+#endif
+
+/*
+ * i2c_abort - called when a I2C transaction failed
+ */
+static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
+{
+#ifdef DEBUG
+	print_abort_reason(i2c_regs);
+#endif
+	/* flush RX and TX fifos */
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
+}
+
+/*
+ * write addr, alias index, to I2C bus.
+ */
+static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
+{
+	while (alen--) {
+		/* Wait until the Tx Fifo is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER)) {
+			i2c_abort(i2c_regs);
+			return -1;
+		}
+
+		/* MSB first */
+		writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
+	}
+
+	return 0;
+}
+
+/*
+ * Internal simplified read function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   value:	Where to put the data
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
+		uint addr, int alen, uchar *value)
+{
+	u32   mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	if (alen != 0) {
+		/* Master write operation */
+		mcr &= ~(U8500_I2C_MCR_OP);
+
+		/* Configure the Frame length to one byte */
+		WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH,
+				U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+		/* Repeated start, no stop */
+		mcr &= ~(U8500_I2C_MCR_STOP);
+
+		/* Write Master Control Register */
+		writel(mcr, &i2c_regs->mcr);
+
+		/* send addr/index */
+		if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+			return -1;
+
+		/* Check for the Master Transaction Done Without Stop */
+		if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTDWS,
+					U8500_I2C_ENDAD_COUNTER)) {
+			return -1;
+		}
+
+		/* Acknowledge the Master Transaction Done Without Stop */
+		i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+	}
+
+	/* Master control configuration for read operation  */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Configure the STOP condition, we read only one byte */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Set the frame length to one byte, we support only 1 byte reads */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	i2c_write_field(&i2c_regs->mcr, U8500_I2C_MCR_LENGTH_STOP_OP,
+			U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
+
+	/*
+	 * receive_data_polling
+	 */
+
+	/* Wait until the Rx FIFO is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Read the data byte from Rx FIFO */
+	*value = readb(&i2c_regs->rfr);
+
+	/* Wait until the work is done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr, U8500_I2C_INT_MTD,
+				U8500_I2C_ENDAD_COUNTER))
+		return -1;
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* If MTD is set, Master Transaction Done Without Stop is set too */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Internal simplified write function:
+ *   i2c_regs:	Pointer to I2C registers for current bus
+ *   chip:	I2C chip address, range 0..127
+ *   addr:	Memory (register) address within the chip
+ *   alen:	Number of bytes to use for addr (typically 1, 2 for larger
+ *		memories, 0 for register type devices with only one register)
+ *   data:	Where to read the data
+ *   len:	How many bytes to write
+ *
+ *   Returns:	0 on success, not 0 on failure
+ */
+static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
+		int alen, u8 *data, int len)
+{
+	int i;
+	u32 mcr = 0;
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Write operation */
+	mcr &= ~(U8500_I2C_MCR_OP);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Frame length: addr byte + len */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH,
+			(alen + len));
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	if (i2c_write_addr(i2c_regs, addr, alen) != 0)
+		return -1;
+
+	for (i = 0; i < len; i++) {
+		/* Wait until the Tx FIFO is not full */
+		if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_TXFF,
+					U8500_I2C_ENDAD_COUNTER))
+			return -1;
+
+		/* it is a 32 bit register with upper 24 reserved R/O */
+		writeb(data[i], &i2c_regs->tfr);
+	}
+
+	/* Check for Master Transaction Done */
+	if (loop_till_bit_set((void *)&i2c_regs->risr,
+					U8500_I2C_INT_MTD,
+					U8500_I2C_ENDAD_COUNTER)) {
+		printf("i2c_write_byte error2: risr %08x\n",
+				i2c_regs->risr);
+		return -1;
+	}
+
+	/* Acknowledge Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Probe the given I2C chip address. Returns 0 if a chip responded,
+ * not 0 on failure.
+ */
+int i2c_probe(uchar chip)
+{
+	u32 mcr = 0;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (chip == CONFIG_SYS_I2C_SLAVE)
+		return 1;
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	/* Set the address mode to 7 bit */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
+
+	/* Store the slave address in the master control register */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_A10, U8500_I2C_MCR_SHIFT_A7, chip);
+
+	/* Read operation */
+	mcr |= U8500_I2C_MCR_OP;
+
+	/* Set the frame length to one byte */
+	WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
+
+	/* Current transaction is terminated by STOP condition */
+	mcr |= U8500_I2C_MCR_STOP;
+
+	/* Write MCR register */
+	writel(mcr, &i2c_regs->mcr);
+
+	/* Wait until the Rx Fifo is not empty */
+	if (loop_till_bit_clear((void *)&i2c_regs->risr,
+					U8500_I2C_INT_RXFE,
+					U8500_I2C_ENDAD_COUNTER)) {
+		i2c_abort(i2c_regs);
+		return -1;
+	}
+
+	flush_fifo(i2c_regs);
+
+	/* Acknowledge the Master Transaction Done */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
+
+	/* Acknowledge the Master Transaction Done Without Stop */
+	i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
+
+	return 0;
+}
+
+/*
+ * Read/Write interface:
+ *   chip:    I2C chip address, range 0..127
+ *   addr:    Memory (register) address within the chip
+ *   alen:    Number of bytes to use for addr (typically 1, 2 for larger
+ *              memories, 0 for register type devices with only one
+ *              register)
+ *   buffer:  Where to read/write the data
+ *   len:     How many bytes to read/write
+ *
+ *   Returns: 0 on success, not 0 on failure
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int i;
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+
+	if (alen > 2) {
+		debug("I2C read: addr len %d not supported\n", alen);
+		return 1;
+	}
+
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	for (i = 0; i < len; i++) {
+		rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
+		if (rc != 0) {
+			debug("I2C read: I/O error: %d\n", rc);
+			i2c_abort(i2c_regs);
+			return rc;
+		}
+	}
+
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc;
+	struct u8500_i2c_regs *i2c_regs;
+	i2c_regs = i2c_dev[i2c_bus_num];
+
+	rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
+			len);
+	if (rc != 0) {
+		debug("I2C write: I/O error\n");
+		i2c_abort(i2c_regs);
+		return rc;
+	}
+	return 0;
+}
+
+int i2c_set_bus_num(unsigned int bus)
+{
+	if (bus > ARRAY_SIZE(i2c_dev) - 1) {
+		debug("i2c_set_bus_num: only up to bus %d supported\n",
+				ARRAY_SIZE(i2c_dev)-1);
+		return -1;
+	}
+
+	i2c_bus_num = bus;
+
+	if (!bus_initialized[i2c_bus_num])
+		i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+int i2c_set_bus_speed(unsigned int speed)
+{
+
+	if (speed > U8500_I2C_MAX_STANDARD_SCL) {
+		debug("i2c_set_bus_speed: only up to %d supported\n",
+				U8500_I2C_MAX_STANDARD_SCL);
+		return -1;
+	}
+
+	/* sets as side effect i2c_bus_speed[i2c_bus_num] */
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+
+	return 0;
+}
+
+unsigned int i2c_get_bus_num(void)
+{
+	return i2c_bus_num;
+}
+
+unsigned int i2c_get_bus_speed(void)
+{
+	return i2c_bus_speed[i2c_bus_num];
+}
diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
new file mode 100644
index 0000000..91dbd3e
--- /dev/null
+++ b/drivers/i2c/u8500_i2c.h
@@ -0,0 +1,194 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef _U8500_I2C_H_
+#define _U8500_I2C_H_
+
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/u8500.h>
+
+struct u8500_i2c_regs {
+	u32 cr;			/* Control Register                      0x00 */
+	u32 scr;		/* Slave Address Register                0x04 */
+	u32 hsmcr;		/* HS Master code Register               0x08 */
+	u32 mcr;		/* Master Control Register               0x0C */
+	u32 tfr;		/* Transmit Fifo Register                0x10 */
+	u32 sr;			/* Status Register                       0x14 */
+	u32 rfr;		/* Receiver Fifo Register                0x18 */
+	u32 tftr;		/* Transmit Fifo Threshold Register      0x1C */
+	u32 rftr;		/* Receiver Fifo Threshold Register      0x20 */
+	u32 dmar;		/* DMA register                          0x24 */
+	u32 brcr;		/* Baud Rate Counter Register            0x28 */
+	u32 imscr;		/* Interrupt Mask Set and Clear Register 0x2C */
+	u32 risr;		/* Raw interrupt status register         0x30 */
+	u32 misr;		/* Masked interrupt status register      0x34 */
+	u32 icr;		/* Interrupt Set and Clear Register      0x38 */
+	u32 reserved_1[(0xFE0 - 0x3c) >> 2];	/* Reserved 0x03C to 0xFE0 */
+	u32 periph_id_0;	/* peripheral ID 0			0xFE0 */
+	u32 periph_id_1;	/* peripheral ID 1			0xFE4 */
+	u32 periph_id_2;	/* peripheral ID 2			0xFE8 */
+	u32 periph_id_3;	/* peripheral ID 3			0xFEC */
+	u32 cell_id_0;		/* I2C cell   ID 0			0xFF0 */
+	u32 cell_id_1;		/* I2C cell   ID 1			0xFF4 */
+	u32 cell_id_2;		/* I2C cell   ID 2			0xFF8 */
+	u32 cell_id_3;		/* I2C cell   ID 3			0xFFC */
+};
+
+
+/* Control Register */
+
+/* Mask values for control register mask */
+#define U8500_I2C_CR_PE          0x0001	/* Peripheral enable */
+#define U8500_I2C_CR_OM          0x0006	/* Operation mode */
+#define U8500_I2C_CR_SAM         0x0008	/* Slave Addressing mode */
+#define U8500_I2C_CR_SM          0x0030	/* Speed mode */
+#define U8500_I2C_CR_SGCM        0x0040	/* Slave General call mode */
+#define U8500_I2C_CR_FTX         0x0080	/* Flush Transmit */
+#define U8500_I2C_CR_FRX         0x0100	/* Flush Receive */
+#define U8500_I2C_CR_DMA_TX_EN   0x0200	/* DMA TX Enable */
+#define U8500_I2C_CR_DMA_RX_EN   0x0400	/* DMA Rx Enable */
+#define U8500_I2C_CR_DMA_SLE     0x0800	/* DMA Synchronization Logic enable */
+#define U8500_I2C_CR_LM          0x1000	/* Loop back mode */
+#define U8500_I2C_CR_FON         0x6000	/* Filtering On */
+
+/* shift valus for control register bit fields */
+#define U8500_I2C_CR_SHIFT_PE		0	/* Peripheral enable */
+#define U8500_I2C_CR_SHIFT_OM		1	/* Operation mode */
+#define U8500_I2C_CR_SHIFT_SAM		3	/* Slave Addressing mode */
+#define U8500_I2C_CR_SHIFT_SM		4	/* Speed mode */
+#define U8500_I2C_CR_SHIFT_SGCM		6	/* Slave General call mode */
+#define U8500_I2C_CR_SHIFT_FTX		7	/* Flush Transmit */
+#define U8500_I2C_CR_SHIFT_FRX		8	/* Flush Receive */
+#define U8500_I2C_CR_SHIFT_DMA_TX_EN	9	/* DMA TX Enable */
+#define U8500_I2C_CR_SHIFT_DMA_RX_EN	10	/* DMA Rx Enable */
+#define U8500_I2C_CR_SHIFT_DMA_SLE	11	/* DMA Synch Logic enable */
+#define U8500_I2C_CR_SHIFT_LM		12	/* Loop back mode */
+#define U8500_I2C_CR_SHIFT_FON		13	/* Filtering On */
+
+/* bus operation modes */
+#define U8500_I2C_BUS_SLAVE_MODE		0
+#define U8500_I2C_BUS_MASTER_MODE		1
+#define U8500_I2C_BUS_MASTER_SLAVE_MODE	2
+
+
+/* Slave control register*/
+
+/* Mask values slave control register */
+#define U8500_I2C_SCR_ADDR                   0x3FF
+#define U8500_I2C_SCR_DATA_SETUP_TIME        0xFFFF0000
+
+/* Shift values for Slave control register */
+#define U8500_I2C_SCR_SHIFT_ADDR               0
+#define U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME    16
+
+
+/* Master Control Register */
+
+/* Mask values for Master control register */
+#define U8500_I2C_MCR_OP	0x00000001	/* Operation */
+#define U8500_I2C_MCR_A7	0x000000FE	/* LSB bits of Address */
+#define U8500_I2C_MCR_EA10	0x00000700	/* Extended Address */
+#define U8500_I2C_MCR_SB	0x00000800	/* Start byte procedure */
+#define U8500_I2C_MCR_AM	0x00003000	/* Address type */
+#define U8500_I2C_MCR_STOP	0x00004000	/* stop condition */
+#define U8500_I2C_MCR_LENGTH	0x03FF8000	/* Frame length */
+#define U8500_I2C_MCR_A10	0x000007FE	/* Enable 10 bit address */
+/* mask for length field,stop and operation  */
+#define U8500_I2C_MCR_LENGTH_STOP_OP	0x3FFC001
+
+/* Shift values for Master control values */
+#define U8500_I2C_MCR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_MCR_SHIFT_A7		1	/* LSB bits of Address */
+#define U8500_I2C_MCR_SHIFT_EA10	8	/* Extended Address */
+#define U8500_I2C_MCR_SHIFT_SB		11	/* Start byte procedure */
+#define U8500_I2C_MCR_SHIFT_AM		12	/* Address type */
+#define U8500_I2C_MCR_SHIFT_STOP	14	/* stop condition */
+#define U8500_I2C_MCR_SHIFT_LENGTH	15	/* Frame length */
+#define U8500_I2C_MCR_SHIFT_A10		1	/* Enable 10 bit address */
+
+#define U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP	0
+
+
+/* Status Register */
+
+/* Mask values for Status register */
+#define U8500_I2C_SR_OP	0x00000003	/* Operation */
+#define U8500_I2C_SR_STATUS	0x0000000C	/* Controller Status */
+#define U8500_I2C_SR_CAUSE	0x00000070	/* Abort Cause */
+#define U8500_I2C_SR_TYPE	0x00000180	/* Receive Type */
+#define U8500_I2C_SR_LENGTH	0x000FF700	/* Transfer length */
+
+/* Shift values for Status register */
+#define U8500_I2C_SR_SHIFT_OP		0	/* Operation */
+#define U8500_I2C_SR_SHIFT_STATUS	2	/* Controller Status */
+#define U8500_I2C_SR_SHIFT_CAUSE	4	/* Abort Cause */
+#define U8500_I2C_SR_SHIFT_TYPE	7	/* Receive Type */
+#define U8500_I2C_SR_SHIFT_LENGTH	9	/* Transfer length */
+
+/* abort cause */
+#define	U8500_I2C_NACK_ADDR	0
+#define	U8500_I2C_NACK_DATA	1
+#define	U8500_I2C_ACK_MCODE	2
+#define	U8500_I2C_ARB_LOST	3
+#define	U8500_I2C_BERR_START	4
+#define	U8500_I2C_BERR_STOP	5
+#define	U8500_I2C_OVFL	6
+
+
+/* Baud rate counter registers */
+
+/* Mask values for Baud rate counter register */
+#define U8500_I2C_BRCR_BRCNT2	0xFFFF		/* Baud Rate Cntr BRCR for HS */
+#define U8500_I2C_BRCR_BRCNT1	0xFFFF0000	/* BRCR for Standard and Fast */
+
+/* Shift values for the Baud rate counter register */
+#define U8500_I2C_BRCR_SHIFT_BRCNT2	0
+#define U8500_I2C_BRCR_SHIFT_BRCNT1	16
+
+
+/* Interrupt Register  */
+
+/* Mask values for Interrupt registers */
+#define U8500_I2C_INT_TXFE	0x00000001	/* Tx fifo empty */
+#define U8500_I2C_INT_TXFNE	0x00000002	/* Tx Fifo nearly empty */
+#define U8500_I2C_INT_TXFF	0x00000004	/* Tx Fifo Full */
+#define U8500_I2C_INT_TXFOVR	0x00000008	/* Tx Fifo over run */
+#define U8500_I2C_INT_RXFE	0x00000010	/* Rx Fifo Empty */
+#define U8500_I2C_INT_RXFNF	0x00000020	/* Rx Fifo nearly empty */
+#define U8500_I2C_INT_RXFF	0x00000040	/* Rx Fifo Full  */
+#define U8500_I2C_INT_RFSR	0x00010000	/* Read From slave request */
+#define U8500_I2C_INT_RFSE	0x00020000	/* Read from slave empty */
+#define U8500_I2C_INT_WTSR	0x00040000	/* Write to Slave request */
+#define U8500_I2C_INT_MTD	0x00080000	/* Master Transcation Done*/
+#define U8500_I2C_INT_STD	0x00100000	/* Slave Transaction Done */
+#define U8500_I2C_INT_MAL	0x01000000	/* Master Arbitation Lost */
+#define U8500_I2C_INT_BERR	0x02000000	/* Bus Error */
+#define U8500_I2C_INT_MTDWS	0x10000000	/* Master Tran Done wo/ Stop */
+
+/* Max clocks (Hz) */
+#define U8500_I2C_MAX_STANDARD_SCL	100000
+#define U8500_I2C_MAX_FAST_SCL		400000
+#define U8500_I2C_MAX_HIGH_SPEED_SCL	3400000
+
+#endif	/* _U8500_I2C_H_ */
-- 
1.7.1

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

* [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (8 preceding siblings ...)
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
@ 2011-04-19 20:42   ` John Rigby
  2011-06-01 17:35     ` Albert ARIBAUD
  2011-05-12  8:05   ` [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options John Rigby
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-19 20:42 UTC (permalink / raw)
  To: u-boot

Minimal platform support to boot linux from SD.

Supported devices/hw limited to external MMC/SD slot,
GPIO, I2C and minimal PRCMU.

Signed-off-by: John Rigby <john.rigby@linaro.org>
CC: Albert Aribaud <albert.aribaud@free.fr>
---
This board support requires mmc driver patch set from Matt Waddel.
v2: cleanup, mostly removal of unused defines and include files
v3: incorporate changes suggested by Wolfgang including:
   better commit message
   get arm_pl180_mmci_init prototype from driver .h file
   don't ignore value from arm_pl180_mmci_init
   optimize printf's in u8500_href.c
   use plain #define CONFIG_BLAH for feature enabling
v4: no changes, just rebased to latest upstream and included for completness
 board/st-ericsson/u8500/Makefile     |   50 +++
 board/st-ericsson/u8500/gpio.c       |  347 +++++++++++++++++++++
 board/st-ericsson/u8500/prcmu-fw.h   |   55 ++++
 board/st-ericsson/u8500/prcmu.c      |  165 ++++++++++
 board/st-ericsson/u8500/u8500_href.c |  546 ++++++++++++++++++++++++++++++++++
 boards.cfg                           |    1 +
 include/configs/u8500_href.h         |  245 +++++++++++++++
 7 files changed, 1409 insertions(+), 0 deletions(-)
 create mode 100644 board/st-ericsson/u8500/Makefile
 create mode 100644 board/st-ericsson/u8500/gpio.c
 create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
 create mode 100644 board/st-ericsson/u8500/prcmu.c
 create mode 100644 board/st-ericsson/u8500/u8500_href.c
 create mode 100644 include/configs/u8500_href.h

diff --git a/board/st-ericsson/u8500/Makefile b/board/st-ericsson/u8500/Makefile
new file mode 100644
index 0000000..91c2abf
--- /dev/null
+++ b/board/st-ericsson/u8500/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) ST-Ericsson SA 2009
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# 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 $(TOPDIR)/config.mk
+
+CFLAGS += -D__RELEASE -D__STN_8500
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= u8500_href.o gpio.o prcmu.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB): $(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak $(obj).depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/st-ericsson/u8500/gpio.c b/board/st-ericsson/u8500/gpio.c
new file mode 100644
index 0000000..96b2461
--- /dev/null
+++ b/board/st-ericsson/u8500/gpio.c
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 <asm/arch/gpio.h>
+
+static struct gpio_register *addr_gpio_register[] = {
+	(void *)U8500_GPIO_0_BASE,
+	(void *)U8500_GPIO_1_BASE,
+	(void *)U8500_GPIO_2_BASE,
+	(void *)U8500_GPIO_3_BASE,
+	(void *)U8500_GPIO_4_BASE,
+	(void *)U8500_GPIO_5_BASE,
+	(void *)U8500_GPIO_6_BASE,
+	(void *)U8500_GPIO_7_BASE,
+	(void *)U8500_GPIO_8_BASE,
+};
+
+struct gpio_altfun_data altfun_table[] = {
+	{
+		.altfun = GPIO_ALT_I2C_0,
+		.start = 147,
+		.end = 148,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_1,
+		.start = 16,
+		.end = 17,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_2,
+		.start = 10,
+		.end = 11,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_I2C_3,
+		.start = 229,
+		.end = 230,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 0,
+		.end = 3,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_0_MODEM,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_UART_1,
+		.start = 4,
+		.end = 7,
+		.cont = 0,
+		.type =
+			GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 18,
+		.end = 19,
+		.cont = 1,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_UART_2,
+		.start = 29,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_C,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 12,
+		.end = 17,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_0,
+		.start = 21,
+		.end = 21,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_1,
+		.start = 33,
+		.end = 36,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MSP_2,
+		.start = 192,
+		.end = 196,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 64,
+		.end = 93,
+		.cont = 1,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_LCD_PANEL,
+		.start = 150,
+		.end = 171,
+		.cont = 0,
+		.type = GPIO_ALTF_B,
+	},
+	{
+		.altfun = GPIO_ALT_SD_CARD0,
+		.start = 18,
+		.end = 28,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_MM_CARD0,
+		.start = 18,
+		.end = 32,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_USB_OTG,
+		.start = 256,
+		.end = 267,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_EMMC,
+		.start = 197,
+		.end = 207,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+	{
+		.altfun = GPIO_ALT_POP_EMMC,
+		.start = 128,
+		.end = 138,
+		.cont = 0,
+		.type = GPIO_ALTF_A,
+	},
+};
+
+/*
+ * Static Function declarations
+ */
+enum gpio_error gpio_setpinconfig(int pin_id, struct gpio_config *config)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	switch (config->mode) {
+	case GPIO_ALTF_A:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_B:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_ALTF_C:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg |= mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+		break;
+	case GPIO_MODE_SOFTWARE:
+		temp_reg = readl(&p_gpio_register->gpio_afsa);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsa);
+		temp_reg = readl(&p_gpio_register->gpio_afsb);
+		temp_reg &= ~mask;
+		writel(temp_reg, &p_gpio_register->gpio_afsb);
+
+		switch (config->direction) {
+		case GPIO_DIR_INPUT:
+			writel(mask, &p_gpio_register->gpio_dirc);
+			break;
+		case GPIO_DIR_OUTPUT:
+			writel(mask, &p_gpio_register->gpio_dirs);
+			break;
+		case GPIO_DIR_LEAVE_UNCHANGED:
+			break;
+		default:
+			return GPIO_INVALID_PARAMETER;
+		}
+
+		break;
+	case GPIO_MODE_LEAVE_UNCHANGED:
+		break;
+	default:
+		return GPIO_INVALID_PARAMETER;
+	}
+	return error;
+}
+
+enum gpio_error gpio_resetgpiopin(int pin_id, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+	enum gpio_error error = GPIO_OK;
+	u32 temp_reg;
+
+	temp_reg = readl(&p_gpio_register->gpio_afsa);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsa);
+	temp_reg = readl(&p_gpio_register->gpio_afsb);
+	temp_reg &= ~mask;
+	writel(temp_reg, &p_gpio_register->gpio_afsb);
+	writel(mask, &p_gpio_register->gpio_dirc);
+
+	return error;
+}
+
+struct gpio_config altfun_pinconfig;
+enum gpio_error gpio_altfunction(enum gpio_alt_function alt_func,
+			    int which_altfunc, char *dev_name)
+{
+	int i, j, start, end;
+	enum gpio_error error = -1;
+
+	for (i = 0; i < ARRAY_SIZE(altfun_table); i++) {
+		if (altfun_table[i].altfun != alt_func)
+			continue;
+
+		start = altfun_table[i].start;
+		end = altfun_table[i].end;
+		for (j = start; j <= end; j++) {
+			if (which_altfunc == GPIO_ALTF_FIND)
+				altfun_pinconfig.mode = altfun_table[i].type;
+			else
+				altfun_pinconfig.mode = which_altfunc;
+			altfun_pinconfig.direction = GPIO_DIR_OUTPUT;
+			altfun_pinconfig.dev_name = dev_name;
+
+			if (which_altfunc != GPIO_ALTF_DISABLE)
+				error = gpio_setpinconfig(j, &altfun_pinconfig);
+			else
+				error = gpio_resetgpiopin(j, dev_name);
+			if (!error)
+				continue;
+			printf("GPIO %d configuration failure (nmdk_error:%d)",
+				j, error);
+			error = GPIO_INVALID_PARAMETER;
+			return error;
+		}
+
+		if (!altfun_table[i].cont)
+			break;
+	}
+	return error;
+}
+
+int gpio_writepin(int pin_id, enum gpio_data value, char *dev_name)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	switch (value) {
+	case GPIO_DATA_HIGH:
+		writel(mask, &p_gpio_register->gpio_dats);
+		break;
+	case GPIO_DATA_LOW:
+		writel(mask, &p_gpio_register->gpio_datc);
+		break;
+	default:
+		printf("Invalid value passed in %s", __FUNCTION__);
+		return GPIO_INVALID_PARAMETER;
+	}
+	return GPIO_OK;
+}
+
+int gpio_readpin(int pin_id, enum gpio_data *rv)
+{
+	struct gpio_register *p_gpio_register =
+	    addr_gpio_register[GPIO_BLOCK(pin_id)];
+	u32 mask = 1UL << (pin_id % GPIO_PINS_PER_BLOCK);
+
+	if ((readl(&p_gpio_register->gpio_dat) & mask) != 0)
+		*rv = GPIO_DATA_HIGH;
+	else
+		*rv = GPIO_DATA_LOW;
+	return GPIO_OK;
+}
+
+int gpio_altfuncenable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_FIND, dev_name);
+}
+
+int gpio_altfuncdisable(enum gpio_alt_function altfunc, char *dev_name)
+{
+	return (int)gpio_altfunction(altfunc, GPIO_ALTF_DISABLE, dev_name);
+}
diff --git a/board/st-ericsson/u8500/prcmu-fw.h b/board/st-ericsson/u8500/prcmu-fw.h
new file mode 100644
index 0000000..0836983
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu-fw.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Copied from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __MACH_PRCMU_FW_V1_H
+#define __MACH_PRCMU_FW_V1_H
+
+#define AP_EXECUTE	2
+#define I2CREAD		1
+#define I2C_WR_OK	1
+#define I2C_RD_OK	2
+#define I2CWRITE	0
+
+#define _PRCMU_TCDM_BASE    U8500_PRCMU_TCDM_BASE
+#define PRCM_XP70_CUR_PWR_STATE (_PRCMU_TCDM_BASE + 0xFFC)      /* 4 BYTES */
+
+#define PRCM_REQ_MB5        (_PRCMU_TCDM_BASE + 0xE44)    /* 4 bytes  */
+#define PRCM_ACK_MB5        (_PRCMU_TCDM_BASE + 0xDF4)    /* 4 bytes */
+
+/* Mailbox 5 Requests */
+#define PRCM_REQ_MB5_I2COPTYPE_REG	(PRCM_REQ_MB5 + 0x0)
+#define PRCM_REQ_MB5_BIT_FIELDS		(PRCM_REQ_MB5 + 0x1)
+#define PRCM_REQ_MB5_I2CSLAVE		(PRCM_REQ_MB5 + 0x2)
+#define PRCM_REQ_MB5_I2CVAL		(PRCM_REQ_MB5 + 0x3)
+
+/* Mailbox 5 ACKs */
+#define PRCM_ACK_MB5_STATUS	(PRCM_ACK_MB5 + 0x1)
+#define PRCM_ACK_MB5_SLAVE	(PRCM_ACK_MB5 + 0x2)
+#define PRCM_ACK_MB5_VAL	(PRCM_ACK_MB5 + 0x3)
+
+#define LOW_POWER_WAKEUP	1
+#define EXE_WAKEUP		0
+
+#define REQ_MB5			5
+
+extern int prcmu_i2c_read(u8 reg, u16 slave);
+extern int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data);
+
+#endif /* __MACH_PRCMU_FW_V1_H */
diff --git a/board/st-ericsson/u8500/prcmu.c b/board/st-ericsson/u8500/prcmu.c
new file mode 100644
index 0000000..6f9302f
--- /dev/null
+++ b/board/st-ericsson/u8500/prcmu.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2009 ST-Ericsson SA
+ *
+ * Adapted from the Linux version:
+ * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ */
+
+/*
+ * NOTE: This currently does not support the I2C workaround access method.
+ */
+
+#include <common.h>
+#include <config.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+
+#include "prcmu-fw.h"
+
+/* CPU mailbox registers */
+#define PRCM_MBOX_CPU_VAL (U8500_PRCMU_BASE + 0x0fc)
+#define PRCM_MBOX_CPU_SET (U8500_PRCMU_BASE + 0x100)
+#define PRCM_MBOX_CPU_CLR (U8500_PRCMU_BASE + 0x104)
+
+static int prcmu_is_ready(void)
+{
+	int ready = readb(PRCM_XP70_CUR_PWR_STATE) == AP_EXECUTE;
+	if (!ready)
+		printf("PRCMU firmware not ready\n");
+	return ready;
+}
+
+static int _wait_for_req_complete(int num)
+{
+	int timeout = 1000;
+
+	/* checking any already on-going transaction */
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	timeout = 1000;
+
+	/* Set an interrupt to XP70 */
+	writel(1 << num, PRCM_MBOX_CPU_SET);
+
+	while ((readl(PRCM_MBOX_CPU_VAL) & (1 << num)) && timeout--)
+		;
+
+	if (!timeout) {
+		printf("PRCMU operation timed out\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+/**
+ * prcmu_i2c_read - PRCMU - 4500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db8500 register to be accessed
+ * Returns: ACK_MB5  value containing the status
+ */
+int prcmu_i2c_read(u8 reg, u16 slave)
+{
+	uint8_t i2c_status;
+	uint8_t i2c_val;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_read:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CREAD, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(0, PRCM_REQ_MB5_I2CVAL);
+
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	i2c_val = readb(PRCM_ACK_MB5_VAL);
+
+	if (i2c_status == I2C_RD_OK)
+		return i2c_val;
+	else {
+
+		printf("prcmu_i2c_read:read return status= %d\n",
+				i2c_status);
+		return -1;
+	}
+
+}
+
+/**
+ * prcmu_i2c_write - PRCMU-db8500 communication using PRCMU I2C
+ * @reg: - db8500 register bank to be accessed
+ * @slave:  - db800 register to be written to
+ * @reg_data: - the data to write
+ * Returns: ACK_MB5 value containing the status
+ */
+int prcmu_i2c_write(u8 reg, u16 slave, u8 reg_data)
+{
+	uint8_t i2c_status;
+
+	if (!prcmu_is_ready())
+		return -1;
+
+	debug("\nprcmu_4500_i2c_write:bank=%x;reg=%x;\n",
+			reg, slave);
+
+	/* prepare the data for mailbox 5 */
+	writeb((reg << 1) | I2CWRITE, PRCM_REQ_MB5_I2COPTYPE_REG);
+	writeb((1 << 3) | 0x0, PRCM_REQ_MB5_BIT_FIELDS);
+	writeb(slave, PRCM_REQ_MB5_I2CSLAVE);
+	writeb(reg_data, PRCM_REQ_MB5_I2CVAL);
+
+	debug("\ncpu_is_u8500v11\n");
+	_wait_for_req_complete(REQ_MB5);
+
+	/* retrieve values */
+	debug("ack-mb5:transfer status = %x\n",
+			readb(PRCM_ACK_MB5_STATUS));
+	debug("ack-mb5:reg bank = %x\n", readb(PRCM_ACK_MB5) >> 1);
+	debug("ack-mb5:slave_add = %x\n",
+			readb(PRCM_ACK_MB5_SLAVE));
+	debug("ack-mb5:reg_val = %d\n", readb(PRCM_ACK_MB5_VAL));
+
+	i2c_status = readb(PRCM_ACK_MB5_STATUS);
+	debug("\ni2c_status = %x\n", i2c_status);
+	if (i2c_status == I2C_WR_OK)
+		return 0;
+	else {
+		printf("ape-i2c: i2c_status : 0x%x\n", i2c_status);
+		return -1;
+	}
+}
diff --git a/board/st-ericsson/u8500/u8500_href.c b/board/st-ericsson/u8500/u8500_href.c
new file mode 100644
index 0000000..525633e
--- /dev/null
+++ b/board/st-ericsson/u8500/u8500_href.c
@@ -0,0 +1,546 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <config.h>
+#include <common.h>
+#include <i2c.h>
+#include <asm/types.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/sys_proto.h>
+#ifdef CONFIG_MMC
+#include "../../../drivers/mmc/arm_pl180_mmci.h"
+#endif
+
+#define NOMADIK_PER4_BASE	(0x80150000)
+#define NOMADIK_BACKUPRAM0_BASE (NOMADIK_PER4_BASE + 0x00000)
+#define NOMADIK_BACKUPRAM1_BASE (NOMADIK_PER4_BASE + 0x01000)
+
+/* Power, Reset, Clock Management Unit */
+/*
+ * SVA: Smart Video Accelerator
+ * SIA: Smart Imaging Accelerator
+ * SGA: Smart Graphic accelerator
+ * B2R2: Graphic blitter
+ */
+#define PRCMU_BASE	CFG_PRCMU_BASE	/* 0x80157000 for U8500 */
+#define PRCM_ARMCLKFIX_MGT_REG		(PRCMU_BASE + 0x000)
+#define PRCM_ACLK_MGT_REG		(PRCMU_BASE + 0x004)
+#define PRCM_SVAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x008)
+#define PRCM_SIAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x00C)
+#define PRCM_SAAMMDSPCLK_MGT_REG	(PRCMU_BASE + 0x010)
+#define PRCM_SGACLK_MGT_REG		(PRCMU_BASE + 0x014)
+#define PRCM_UARTCLK_MGT_REG		(PRCMU_BASE + 0x018)
+#define PRCM_MSPCLK_MGT_REG		(PRCMU_BASE + 0x01C)
+#define PRCM_I2CCLK_MGT_REG		(PRCMU_BASE + 0x020)
+#define PRCM_SDMMCCLK_MGT_REG		(PRCMU_BASE + 0x024)
+#define PRCM_SLIMCLK_MGT_REG		(PRCMU_BASE + 0x028)
+#define PRCM_PER1CLK_MGT_REG		(PRCMU_BASE + 0x02C)
+#define PRCM_PER2CLK_MGT_REG		(PRCMU_BASE + 0x030)
+#define PRCM_PER3CLK_MGT_REG		(PRCMU_BASE + 0x034)
+#define PRCM_PER5CLK_MGT_REG		(PRCMU_BASE + 0x038)
+#define PRCM_PER6CLK_MGT_REG		(PRCMU_BASE + 0x03C)
+#define PRCM_PER7CLK_MGT_REG		(PRCMU_BASE + 0x040)
+#define PRCM_DMACLK_MGT_REG		(PRCMU_BASE + 0x074)
+#define PRCM_B2R2CLK_MGT_REG		(PRCMU_BASE + 0x078)
+
+#define PRCM_PLLSOC0_FREQ_REG		(PRCMU_BASE + 0x080)
+#define PRCM_PLLSOC1_FREQ_REG		(PRCMU_BASE + 0x084)
+#define PRCM_PLLARM_FREQ_REG		(PRCMU_BASE + 0x088)
+#define PRCM_PLLDDR_FREQ_REG		(PRCMU_BASE + 0x08C)
+#define PRCM_ARM_CHGCLKREQ_REG		(PRCMU_BASE + 0x114)
+
+#define PRCM_TCR			(PRCMU_BASE + 0x1C8)
+
+/*
+ * Memory controller register
+ */
+#define DMC_BASE_ADDR			0x80156000
+#define DMC_CTL_97			(DMC_BASE_ADDR + 0x184)
+
+int board_id;	/* set in board_late_init() */
+
+/* PLLs for clock management registers */
+enum {
+	GATED = 0,
+	PLLSOC0,	/* pllsw = 001, ffs() = 1 */
+	PLLSOC1,	/* pllsw = 010, ffs() = 2 */
+	PLLDDR,		/* pllsw = 100, ffs() = 3 */
+	PLLARM,
+};
+
+static struct pll_freq_regs {
+	int idx;	/* index fror pll_name and pll_khz arrays */
+	uint32_t addr;
+} pll_freq_regs[] = {
+	{PLLSOC0, PRCM_PLLSOC0_FREQ_REG},
+	{PLLSOC1, PRCM_PLLSOC1_FREQ_REG},
+	{PLLDDR, PRCM_PLLDDR_FREQ_REG},
+	{PLLARM, PRCM_PLLARM_FREQ_REG},
+	{0, 0},
+};
+
+static const char *pll_name[5] = {"GATED", "SOC0", "SOC1", "DDR", "ARM"};
+static uint32_t pll_khz[5];	/* use ffs(pllsw(reg)) as index for 0..3 */
+
+static struct clk_mgt_regs {
+	uint32_t addr;
+	uint32_t val;
+	const char *descr;
+} clk_mgt_regs[] = {
+	/* register content taken from bootrom settings */
+	{PRCM_ARMCLKFIX_MGT_REG, 0x0120, "ARMCLKFIX"}, /* ena, SOC0/0, ??? */
+	{PRCM_ACLK_MGT_REG, 0x0125, "ACLK"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_SVAMMDSPCLK_MGT_REG, 0x1122, "SVA"}, /* ena, SOC0/2, 400 MHz */
+	{PRCM_SIAMMDSPCLK_MGT_REG, 0x0022, "SIA"}, /* dis, SOC0/2, 400 MHz */
+	{PRCM_SAAMMDSPCLK_MGT_REG, 0x0822, "SAA"}, /* dis, SOC0/4, 200 MHz */
+	{PRCM_SGACLK_MGT_REG, 0x0024, "SGA"},	/* dis, SOC0/4, 200 MHz */
+	{PRCM_UARTCLK_MGT_REG, 0x0300, "UART"},	/* ena, GATED, CLK38 */
+	{PRCM_MSPCLK_MGT_REG, 0x0200, "MSP"},	/* dis, GATED, CLK38 */
+	{PRCM_I2CCLK_MGT_REG, 0x0130, "I2C"},	/* ena, SOC0/16, 50 MHz */
+	{PRCM_SDMMCCLK_MGT_REG, 0x0130, "SDMMC"}, /* ena, SOC0/16, 50 MHz */
+	{PRCM_PER1CLK_MGT_REG, 0x126, "PER1"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER2CLK_MGT_REG, 0x126, "PER2"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER3CLK_MGT_REG, 0x126, "PER3"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER5CLK_MGT_REG, 0x126, "PER5"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER6CLK_MGT_REG, 0x126, "PER6"},	/* ena, SOC0/6, 133 MHz */
+	{PRCM_PER7CLK_MGT_REG, 0x128, "PER7"},	/* ena, SOC0/8, 100 MHz */
+	{PRCM_DMACLK_MGT_REG, 0x125, "DMA"},	/* ena, SOC0/5, 160 MHz */
+	{PRCM_B2R2CLK_MGT_REG, 0x025, "B2R2"},	/* dis, SOC0/5, 160 MHz */
+	{0, 0, NULL},
+};
+
+static void init_regs(void);
+
+DECLARE_GLOBAL_DATA_PTR;
+#if defined(CONFIG_SHOW_BOOT_PROGRESS)
+void show_boot_progress(int progress)
+{
+	printf("Boot reached stage %d\n", progress);
+}
+#endif
+
+static unsigned int read_asicid(void)
+{
+	unsigned int *address = (void *)U8500_BOOTROM_BASE
+				+ U8500_BOOTROM_ASIC_ID_OFFSET;
+	return readl(address);
+}
+
+int cpu_is_u8500v11(void)
+{
+	return read_asicid() == 0x008500A1;
+}
+
+/*
+ * Miscellaneous platform dependent initialisations
+ */
+
+int board_early_init_f(void)
+{
+	init_regs();
+	return 0;
+}
+
+int board_init(void)
+{
+	uint32_t unused_cols_rows;
+	unsigned int nrows;
+	unsigned int ncols;
+
+	gd->bd->bi_arch_number = 0x1A4;
+	gd->bd->bi_boot_params = 0x00000100;
+	gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
+
+	/*
+	 * Assumption: 2 CS active, both CS have same layout.
+	 *             15 rows max, 11 cols max (controller spec).
+	 *             memory chip has 8 banks, I/O width 32 bit.
+	 * The correct way would be to read MR#8: I/O width and density,
+	 * but this requires locking against the PRCMU firmware.
+	 * Simplified approach:
+	 * Read number of unused rows and columns from mem controller.
+	 * size = nCS x 2^(rows+cols) x nbanks x buswidth_bytes
+	 */
+	unused_cols_rows = readl(DMC_CTL_97);
+	nrows = 15 - (unused_cols_rows & 0x07);
+	ncols = 11 - ((unused_cols_rows & 0x0700) >> 8);
+	gd->bd->bi_dram[0].size = 2 * (1 << (nrows + ncols)) * 8 * 4;
+
+	icache_enable();
+
+	return 0;
+}
+
+int dram_init(void)
+{
+	gd->ram_size = PHYS_SDRAM_SIZE_1;
+
+	return 0;
+}
+
+unsigned int addr_vall_arr[] = {
+	0x8011F000, 0x0000FFFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8011F008, 0x00001CFF, /* Clocks for HSI TODO: Enable reqd only */
+	0x8000F000, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x8000F008, 0x00007FFF, /* Clocks for I2C TODO: Enable reqd only */
+	0x80157020, 0x00000150, /* I2C 48MHz clock */
+	0x8012F000, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0x8012F008, 0x00007FFF, /* Clocks for SD TODO: Enable reqd only */
+	0xA03DF000, 0x0000000D, /* Clock for MTU Timers */
+	0x8011E00C, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8011E004, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E020, 0x0000FFE0, /* GPIO ALT FUNC for EMMC */
+	0x8011E024, 0x00000000, /* GPIO ALT FUNC for EMMC */
+	0x8012E000, 0x20000000, /* GPIO ALT FUNC for UART */
+	0x8012E00C, 0x00000000, /* GPIO ALT FUNC for SD */
+	0x8012E004, 0x0FFC0000, /* GPIO ALT FUNC for SD */
+	0x8012E020, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x8012E024, 0x60000000, /* GPIO ALT FUNC for SD */
+	0x801571E4, 0x0000000C, /* PRCMU settings for B2R2,
+				   PRCM_APE_RESETN_SET_REG */
+	0x80157024, 0x00000130, /* PRCMU settings for EMMC/SD */
+	0xA03FF000, 0x00000003, /* USB */
+	0xA03FF008, 0x00000001, /* USB */
+	0xA03FE00C, 0x00000000, /* USB */
+	0xA03FE020, 0x00000FFF, /* USB */
+	0xA03FE024, 0x00000000	/* USB */
+};
+
+#ifdef BOARD_LATE_INIT
+#ifdef CONFIG_MMC
+
+#define LDO_VAUX3_MASK		0x3
+#define LDO_VAUX3_ENABLE	0x1
+#define VAUX3_VOLTAGE_2_9V	0xd
+
+#define AB8500_REGU_CTRL2	0x4
+#define AB8500_REGU_VRF1VAUX3_REGU_REG	0x040A
+#define AB8500_REGU_VRF1VAUX3_SEL_REG	0x0421
+
+static int hrefplus_mmc_power_init(void)
+{
+	int ret;
+	int val;
+
+	if (!cpu_is_u8500v11())
+		return 0;
+
+	/*
+	 * On v1.1 HREF boards (HREF+), Vaux3 needs to be enabled for the SD
+	 * card to work.  This is done by enabling the regulators in the AB8500
+	 * via PRCMU I2C transactions.
+	 *
+	 * This code is derived from the handling of AB8500_LDO_VAUX3 in
+	 * ab8500_ldo_enable() and ab8500_ldo_disable() in Linux.
+	 *
+	 * Turn off and delay is required to have it work across soft reboots.
+	 */
+
+	ret = prcmu_i2c_read(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG);
+	if (ret < 0)
+		goto out;
+
+	val = ret;
+
+	/* Turn off */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2, AB8500_REGU_VRF1VAUX3_REGU_REG,
+				val & ~LDO_VAUX3_MASK);
+	if (ret < 0)
+		goto out;
+
+	udelay(10 * 1000);
+
+	/* Set the voltage to 2.9V */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_SEL_REG,
+				VAUX3_VOLTAGE_2_9V);
+	if (ret < 0)
+		goto out;
+
+	val = val & ~LDO_VAUX3_MASK;
+	val = val | LDO_VAUX3_ENABLE;
+
+	/* Turn on the supply */
+	ret = prcmu_i2c_write(AB8500_REGU_CTRL2,
+				AB8500_REGU_VRF1VAUX3_REGU_REG, val);
+
+out:
+	return ret;
+}
+#endif
+/*
+ * called after all initialisation were done, but before the generic
+ * mmc_initialize().
+ */
+int board_late_init(void)
+{
+	uchar byte;
+
+	/*
+	 * Determine and set board_id environment variable
+	 * 0: mop500, 1: href500
+	 * Above boards have different GPIO expander chips which we can
+	 * distinguish by the chip id.
+	 *
+	 * The board_id environment variable is needed for the Linux bootargs.
+	 */
+	(void) i2c_set_bus_num(0);
+	(void) i2c_read(CONFIG_SYS_I2C_GPIOE_ADDR, 0x80, 1, &byte, 1);
+	if (byte == 0x01) {
+		board_id = 0;
+		setenv("board_id", "0");
+	} else {
+		board_id = 1;
+		setenv("board_id", "1");
+	}
+#ifdef CONFIG_MMC
+	hrefplus_mmc_power_init();
+
+	/*
+	 * config extended GPIO pins for level shifter and
+	 * SDMMC_ENABLE
+	 */
+	if (board_id == 0) {
+		/* MOP500 */
+		byte = 0x0c;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x89, 1, &byte, 1);
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0x83, 1, &byte, 1);
+	} else {
+		/* HREF */
+		/* set the direction of GPIO KPY9 and KPY10 */
+		byte = 0x06;
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC8, 1, &byte, 1);
+		/* must be a multibyte access */
+		(void) i2c_write(CONFIG_SYS_I2C_GPIOE_ADDR, 0xC4, 1,
+						(uchar []) {0x06, 0x06}, 2);
+	}
+#endif /* CONFIG_MMC */
+	/*
+	 * Create a memargs variable which points uses either the memargs256 or
+	 * memargs512 environment variable, depending on the memory size.
+	 * memargs is used to build the bootargs, memargs256 and memargs512 are
+	 * stored in the environment.
+	 */
+	if (gd->bd->bi_dram[0].size == 0x10000000) {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs256}");
+		setenv("mem", "256M");
+	} else {
+		setenv("memargs", "setenv bootargs ${bootargs} ${memargs512}");
+		setenv("mem", "512M");
+	}
+
+	return 0;
+}
+#endif /* BOARD_LATE_INIT */
+
+static void early_gpio_setup(struct gpio_register *gpio_reg, u32 bits)
+{
+	writel(readl(&gpio_reg->gpio_dats) | bits, &gpio_reg->gpio_dats);
+	writel(readl(&gpio_reg->gpio_pdis) & ~bits, &gpio_reg->gpio_pdis);
+}
+
+static void init_regs(void)
+{
+	/* FIXME Remove magic register array settings for ED also */
+	struct prcmu *prcmu = (struct prcmu *) U8500_PRCMU_BASE;
+
+	/* Enable timers */
+	writel(1 << 17, &prcmu->tcr);
+
+	u8500_prcmu_enable(&prcmu->per1clk_mgt);
+	u8500_prcmu_enable(&prcmu->per2clk_mgt);
+	u8500_prcmu_enable(&prcmu->per3clk_mgt);
+	u8500_prcmu_enable(&prcmu->per5clk_mgt);
+	u8500_prcmu_enable(&prcmu->per6clk_mgt);
+	u8500_prcmu_enable(&prcmu->per7clk_mgt);
+
+	u8500_prcmu_enable(&prcmu->uartclk_mgt);
+	u8500_prcmu_enable(&prcmu->i2cclk_mgt);
+
+	u8500_prcmu_enable(&prcmu->sdmmcclk_mgt);
+
+	u8500_clock_enable(1, 9, -1);	/* GPIO0 */
+
+	u8500_clock_enable(2, 11, -1);	/* GPIO1 */
+
+	u8500_clock_enable(3, 8, -1);	/* GPIO2 */
+	u8500_clock_enable(5, 1, -1);	/* GPIO3 */
+
+	u8500_clock_enable(3, 6, 6);	/* UART2 */
+
+	gpio_altfuncenable(GPIO_ALT_I2C_0, "I2C0");
+	u8500_clock_enable(3, 3, 3);	/* I2C0 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x60000000);
+	gpio_altfuncenable(GPIO_ALT_UART_2, "UART2");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_6_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_EMMC, "EMMC");
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_0_BASE, 0x0000ffe0);
+	gpio_altfuncenable(GPIO_ALT_SD_CARD0, "SDCARD");
+
+	u8500_clock_enable(1, 5, 5);	/* SDI0 */
+	u8500_clock_enable(2, 4, 2);	/* SDI4 */
+
+	u8500_clock_enable(6, 7, -1);	/* MTU0 */
+	u8500_clock_enable(3, 4, 4);	/* SDI2 */
+
+	early_gpio_setup((struct gpio_register *)U8500_GPIO_4_BASE, 0x000007ff);
+	gpio_altfuncenable(GPIO_ALT_POP_EMMC, "EMMC");
+
+	/*
+	 * Enabling clocks for all devices which are AMBA devices in the
+	 * kernel.  Otherwise they will not get probe()'d because the
+	 * peripheral ID register will not be powered.
+	 */
+
+	/* XXX: some of these differ between ED/V1 */
+
+	u8500_clock_enable(1, 1, 1);	/* UART1 */
+	u8500_clock_enable(1, 0, 0);	/* UART0 */
+
+	u8500_clock_enable(3, 2, 2);	/* SSP1 */
+	u8500_clock_enable(3, 1, 1);	/* SSP0 */
+
+	u8500_clock_enable(2, 8, -1);	/* SPI0 */
+	u8500_clock_enable(2, 5, 3);	/* MSP2 */
+}
+
+#ifdef CONFIG_MMC
+static int u8500_mmci_board_init(void)
+{
+	enum gpio_error error;
+	struct gpio_register *gpio_base_address;
+
+	gpio_base_address = (void *)(U8500_GPIO_0_BASE);
+	gpio_base_address->gpio_dats |= 0xFFC0000;
+	gpio_base_address->gpio_pdis &= ~0xFFC0000;
+
+	/* save the GPIO0 AFSELA register */
+	error = gpio_altfuncenable(GPIO_ALT_SD_CARD0, "MMC");
+	if (error != GPIO_OK) {
+		printf("u8500_mmci_board_init() gpio_altfuncenable failed\n");
+		return -ENODEV;
+	}
+	return 0;
+}
+
+int board_mmc_init(bd_t *bd)
+{
+	if (u8500_mmci_board_init())
+		return -ENODEV;
+
+	if (arm_pl180_mmci_init())
+		return -ENODEV;
+	return 0;
+}
+#endif
+
+
+/*
+ * get_pll_freq_khz - return PLL frequency in kHz
+ */
+static uint32_t get_pll_freq_khz(uint32_t inclk_khz, uint32_t freq_reg)
+{
+	uint32_t idf, ldf, odf, seldiv, phi;
+
+	/*
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(2*ODF*IDF) if SELDIV2=0
+	 * PLLOUTCLK = PHI = (INCLK*LDF)/(4*ODF*IDF) if SELDIV2=1
+	 * where:
+	 * IDF=R(2:0) (when R=000, IDF=1d)
+	 * LDF = 2*D(7:0) (D must be greater than or equal to 6)
+	 * ODF = N(5:0) (when N=000000, 0DF=1d)
+	 */
+
+	idf = (freq_reg & 0x70000) >> 16;
+	ldf = (freq_reg & 0xff) * 2;
+	odf = (freq_reg & 0x3f00) >> 8;
+	seldiv = (freq_reg & 0x01000000) >> 24;
+	phi = (inclk_khz * ldf) / (2 * odf * idf);
+	if (seldiv)
+		phi = phi/2;
+
+	return phi;
+}
+
+int do_clkinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+	uint32_t inclk_khz;
+	uint32_t reg, phi;
+	uint32_t clk_khz;
+	unsigned int clk_sel;
+	struct clk_mgt_regs *clks = clk_mgt_regs;
+	struct pll_freq_regs *plls = pll_freq_regs;
+
+	/*
+	 * Go through list of PLLs.
+	 * Initialise pll out frequency array (pll_khz) and print frequency.
+	 */
+	inclk_khz = 38400;	/* 38.4 MHz */
+	while (plls->addr) {
+		reg = readl(plls->addr);
+		phi = get_pll_freq_khz(inclk_khz, reg);
+		pll_khz[plls->idx] = phi;
+		printf("%s PLL out frequency: %d.%d Mhz\n",
+				pll_name[plls->idx], phi/1000, phi % 1000);
+		plls++;
+	}
+
+	/* check ARM clock source */
+	reg = readl(PRCM_ARM_CHGCLKREQ_REG);
+	printf("A9 running on %s\n",
+		(reg & 1) ?  "external clock" : "ARM PLL");
+
+	/* go through list of clk_mgt_reg */
+	printf("\n%19s %9s %7s %9s enabled\n",
+			"name(addr)", "value", "PLL", "CLK[MHz]");
+	while (clks->addr) {
+		reg = readl(clks->addr);
+
+		/* convert bit position into array index */
+		clk_sel = ffs((reg >> 5) & 0x7);	/* PLLSW[2:0] */
+
+		if (reg & 0x200)
+			clk_khz = 38400;	/* CLK38 is set */
+		else if ((reg & 0x1f) == 0)
+			/* ARMCLKFIX_MGT is 0x120, e.g. div = 0 ! */
+			clk_khz = 0;
+		else
+			clk_khz = pll_khz[clk_sel] / (reg & 0x1f);
+
+		printf("%9s(%08x): %08x, %6s, %4d.%03d, %s\n",
+			clks->descr, clks->addr, reg, pll_name[clk_sel],
+			clk_khz / 1000, clk_khz % 1000,
+			(reg & 0x100) ? "ena" : "dis");
+		clks++;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD(
+	clkinfo,	1,	1,	do_clkinfo,
+	"print clock info",
+	""
+);
diff --git a/boards.cfg b/boards.cfg
index 554e06c..2a30f3e 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -130,6 +130,7 @@ smdkc100                     arm         armv7       smdkc100            samsung
 s5pc210_universal            arm         armv7       universal_c210      samsung        s5pc2xx
 harmony                      arm         armv7       harmony             nvidia         tegra2
 seaboard                     arm         armv7       seaboard            nvidia         tegra2
+u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 actux1                       arm         ixp
 actux2                       arm         ixp
 actux3                       arm         ixp
diff --git a/include/configs/u8500_href.h b/include/configs/u8500_href.h
new file mode 100644
index 0000000..636922c
--- /dev/null
+++ b/include/configs/u8500_href.h
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2009
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * High Level Configuration Options
+ * (easy to change)
+ */
+#define CONFIG_U8500
+#define CONFIG_L2_OFF
+
+#define CONFIG_SYS_MEMTEST_START	0x00000000
+#define CONFIG_SYS_MEMTEST_END	0x1FFFFFFF
+#define CONFIG_SYS_HZ		1000		/* must be 1000 */
+
+#define CONFIG_BOARD_EARLY_INIT_F
+#define BOARD_LATE_INIT
+
+/*
+ * Size of malloc() pool
+ */
+#ifdef CONFIG_BOOT_SRAM
+#define CONFIG_ENV_SIZE		(32*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 64*1024)
+#else
+#define CONFIG_ENV_SIZE		(128*1024)
+#define CONFIG_SYS_MALLOC_LEN	(CONFIG_ENV_SIZE + 256*1024)
+#endif
+#define CONFIG_SYS_GBL_DATA_SIZE	128	/* for initial data */
+
+/*
+ * PL011 Configuration
+ */
+#define CONFIG_PL011_SERIAL
+#define CONFIG_PL011_SERIAL_RLCR
+#define CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+/*
+ * U8500 UART registers base for 3 serial devices
+ */
+#define CFG_UART0_BASE		0x80120000
+#define CFG_UART1_BASE		0x80121000
+#define CFG_UART2_BASE		0x80007000
+#define CFG_SERIAL0		CFG_UART0_BASE
+#define CFG_SERIAL1		CFG_UART1_BASE
+#define CFG_SERIAL2		CFG_UART2_BASE
+#define CONFIG_PL011_CLOCK	38400000
+#define CONFIG_PL01x_PORTS	{ (void *)CFG_SERIAL0, (void *)CFG_SERIAL1, \
+				  (void *)CFG_SERIAL2 }
+#define CONFIG_CONS_INDEX	2
+#define CONFIG_BAUDRATE		115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*
+ * Devices and file systems
+ */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_DOS_PARTITION
+
+/*
+ * Commands
+ */
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_BOOTD
+#define CONFIG_CMD_BDI
+#define CONFIG_CMD_IMI
+#define CONFIG_CMD_MISC
+#define CONFIG_CMD_RUN
+#define CONFIG_CMD_ECHO
+#define CONFIG_CMD_CONSOLE
+#define CONFIG_CMD_LOADS
+#define CONFIG_CMD_LOADB
+#define CONFIG_CMD_MMC
+#define CONFIG_CMD_FAT
+#define CONFIG_CMD_EXT2
+#define CONFIG_CMD_EMMC
+#define CONFIG_CMD_SOURCE
+#define CONFIG_CMD_I2C
+
+#ifndef CONFIG_BOOTDELAY
+#define CONFIG_BOOTDELAY	1
+#endif
+#define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */
+
+#undef CONFIG_BOOTARGS
+#define CONFIG_BOOTCOMMAND	"run emmcboot"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"verify=n\0"							\
+	"loadaddr=0x00100000\0"						\
+	"console=ttyAMA2,115200n8\0"					\
+	"memargs256=mem=96M at 0 mem_modem=32M at 96M mem=30M at 128M "		\
+		"pmem=22M at 158M pmem_hwb=44M at 180M mem_mali=32 at 224M\0"	\
+	"memargs512=mem=96M at 0 mem_modem=32M at 96M mem=44M at 128M "		\
+		"pmem=22M at 172M mem=30M at 194M mem_mali=32M at 224M "		\
+		"pmem_hwb=54M at 256M mem=202M at 310M\0"			\
+	"commonargs=setenv bootargs cachepolicy=writealloc noinitrd "	\
+		"init=init "						\
+		"board_id=${board_id} "					\
+		"logo.${logo} "						\
+		"startup_graphics=${startup_graphics}\0"		\
+	"emmcargs=setenv bootargs ${bootargs} "				\
+		"root=/dev/mmcblk0p2 "					\
+		"rootdelay=1\0"						\
+	"addcons=setenv bootargs ${bootargs} "				\
+		"console=${console}\0"					\
+	"emmcboot=echo Booting from eMMC ...; "				\
+		"run commonargs emmcargs addcons memargs;"		\
+		"mmc read 0 ${loadaddr} 0xA0000 0x4000;"		\
+		"bootm ${loadaddr}\0"					\
+	"flash=mmc init 1;fatload mmc 1 ${loadaddr} flash.scr;"		\
+		"source ${loadaddr}\0"					\
+	"loaduimage=mmc init 1;fatload mmc 1 ${loadaddr} uImage\0"	\
+	"usbtty=cdc_acm\0"						\
+	"stdout=serial,usbtty\0"					\
+	"stdin=serial,usbtty\0"						\
+	"stderr=serial,usbtty\0"
+
+/*
+ * Miscellaneous configurable options
+ */
+
+#define CONFIG_SYS_LONGHELP			/* undef to save memory     */
+#define CONFIG_SYS_PROMPT	"U8500 $ "	/* Monitor Command Prompt   */
+#define CONFIG_SYS_CBSIZE	1024		/* Console I/O Buffer Size  */
+
+/* Print Buffer Size */
+#define CONFIG_SYS_PBSIZE		(CONFIG_SYS_CBSIZE \
+					+ sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	32	/* max number of command args */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE /* Boot Arg Buffer Size */
+
+#undef	CONFIG_SYS_CLKS_IN_HZ		/* everything, incl board info, in Hz */
+#define CONFIG_SYS_LOAD_ADDR		0x00100000 /* default load address */
+#define CONFIG_SYS_LOADS_BAUD_CHANGE
+
+#define CONFIG_SYS_HUSH_PARSER
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_CMDLINE_EDITING
+
+#define CONFIG_SETUP_MEMORY_TAGS	2
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_TAG			/* enable passing of ATAGs  */
+
+/*
+ * I2C
+ */
+#define CONFIG_U8500_I2C
+#undef	CONFIG_HARD_I2C			/* I2C with hardware support */
+#undef	CONFIG_SOFT_I2C			/* I2C bit-banged */
+#define CONFIG_I2C_MULTI_BUS
+#define CONFIG_SYS_I2C_SPEED		100000
+#define CONFIG_SYS_I2C_SLAVE		0	/* slave addr of controller */
+#define CONFIG_SYS_U8500_I2C0_BASE		0x80004000
+#define CONFIG_SYS_U8500_I2C1_BASE		0x80122000
+#define CONFIG_SYS_U8500_I2C2_BASE		0x80128000
+#define CONFIG_SYS_U8500_I2C3_BASE		0x80110000
+#define CONFIG_SYS_U8500_I2C_BUS_MAX		4
+
+#define CONFIG_SYS_I2C_GPIOE_ADDR	0x42	/* GPIO expander chip addr */
+#define CONFIG_TC35892_GPIO
+/*
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+
+#ifdef CONFIG_USE_IRQ
+#define CONFIG_STACKSIZE_IRQ		(4*1024)	/* IRQ stack */
+#define CONFIG_STACKSIZE_FIQ		(4*1024)	/* FIQ stack */
+#endif
+
+/*
+ * Physical Memory Map
+ */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			0x00000000	/* DDR-SDRAM Bank #1 */
+#define PHYS_SDRAM_SIZE_1		0x20000000	/* 512 MB */
+
+/*
+ * additions for new relocation code
+ */
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_RAM_SIZE	0x100000
+#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_SDRAM_BASE + \
+					 CONFIG_SYS_INIT_RAM_SIZE - \
+					 GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR		CONFIG_SYS_GBL_DATA_OFFSET
+
+/* landing address before relocation */
+#ifndef CONFIG_SYS_TEXT_BASE
+#define CONFIG_SYS_TEXT_BASE            0x0
+#endif
+
+/*
+ * MMC related configs
+ * NB Only externa SD slot is currently supported
+ */
+#define MMC_BLOCK_SIZE			512
+#define CONFIG_ARM_PL180_MMCI
+#define CONFIG_ARM_PL180_MMCI_BASE	0x80126000	/* MMC base for 8500  */
+#define CONFIG_ARM_PL180_MMCI_CLOCK_FREQ 6250000
+#define CONFIG_MMC_DEV_NUM		1
+
+#define CONFIG_CMD_ENV
+#define CONFIG_CMD_SAVEENV	/* CMD_ENV is obsolete but used in env_emmc.c */
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_ENV_OFFSET		0x13F80000
+#define CONFIG_SYS_MMC_ENV_DEV          0               /* SLOT2: eMMC */
+
+/*
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+/*
+ * base register values for U8500
+ */
+#define CFG_PRCMU_BASE		0x80157000	/* Power, reset and clock
+						   management unit */
+#define CFG_FSMC_BASE		0x80000000	/* FSMC Controller */
+
+#endif	/* __CONFIG_H */
-- 
1.7.1

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

* [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options John Rigby
@ 2011-04-19 20:59     ` Kumar Gala
  0 siblings, 0 replies; 42+ messages in thread
From: Kumar Gala @ 2011-04-19 20:59 UTC (permalink / raw)
  To: u-boot


On Apr 19, 2011, at 3:42 PM, John Rigby wrote:

> Two new options:
> 
> CONFIG_PL011_SERIAL_RLCR
> 
> Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
> have separate receive and transmit line control registers.  Set
> this variable to initialize the extra register.
> 
> CONFIG_PL011_SERIAL_FLUSH_ON_INIT
> 
> On some platforms (e.g. U8500) U-Boot is loaded by a second stage
> boot loader that has already initialized the UART.  Define this
> variable to flush the UART at init time.
> empty fifo on init
> 
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> ---
> v2: No changes
> v3: Enable changes with new CONFIG_* options instead of platform.
> Document new CONFIG_* options in README.
> v4: Added delay before writing to RLCR.
> Removed Rabin as author at his request.
> 
> README                        |   12 ++++++++++++
> drivers/serial/serial_pl01x.c |   30 +++++++++++++++++++++++++++---
> drivers/serial/serial_pl01x.h |    4 ++++
> 3 files changed, 43 insertions(+), 3 deletions(-)

Just a nit, but the subject appears to be 'p1' not 'pl'.

(that is a one, not the letter L)

- k

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

* [U-Boot] [PATCHv3 0/4] ST-Ericsson U8500 support
  2011-04-12  6:17   ` [U-Boot] [PATCHv3 " John Rigby
@ 2011-04-28 14:47     ` John Rigby
  2011-04-28 15:40       ` Albert ARIBAUD
  0 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-28 14:47 UTC (permalink / raw)
  To: u-boot

On Tue, Apr 12, 2011 at 12:17 AM, John Rigby <john.rigby@linaro.org> wrote:
> Add support for ST-Ericsson U8500 SoC and HREF platform
>
> John Rigby (2):
> ?armv7: Add ST-Ericsson u8500 arch
> ?armv7: Add support for ST-Ericsson U8500 href platform
>
> Michael Brandt (1):
> ?I2C: Add driver for ST-Ericsson U8500 i2c
>
> Rabin Vincent (1):
> ?Serial: p1011: new vendor init options
>
> ?README ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 12 +
> ?arch/arm/cpu/armv7/u8500/Makefile ? ? ? ? ? | ? 46 ++
> ?arch/arm/cpu/armv7/u8500/clock.c ? ? ? ? ? ?| ? 56 +++
> ?arch/arm/cpu/armv7/u8500/lowlevel.S ? ? ? ? | ? 33 ++
> ?arch/arm/cpu/armv7/u8500/timer.c ? ? ? ? ? ?| ?167 ++++++++
> ?arch/arm/include/asm/arch-u8500/clock.h ? ? | ? 72 ++++
> ?arch/arm/include/asm/arch-u8500/gpio.h ? ? ?| ?247 +++++++++++
> ?arch/arm/include/asm/arch-u8500/hardware.h ?| ? 83 ++++
> ?arch/arm/include/asm/arch-u8500/sys_proto.h | ? 27 ++
> ?arch/arm/include/asm/arch-u8500/u8500.h ? ? | ? 47 ++
> ?board/st-ericsson/u8500/Makefile ? ? ? ? ? ?| ? 50 +++
> ?board/st-ericsson/u8500/gpio.c ? ? ? ? ? ? ?| ?347 +++++++++++++++
> ?board/st-ericsson/u8500/prcmu-fw.h ? ? ? ? ?| ? 55 +++
> ?board/st-ericsson/u8500/prcmu.c ? ? ? ? ? ? | ?165 +++++++
> ?board/st-ericsson/u8500/u8500_href.c ? ? ? ?| ?546 ++++++++++++++++++++++++
> ?boards.cfg ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?drivers/i2c/Makefile ? ? ? ? ? ? ? ? ? ? ? ?| ? ?1 +
> ?drivers/i2c/u8500_i2c.c ? ? ? ? ? ? ? ? ? ? | ?613 +++++++++++++++++++++++++++
> ?drivers/i2c/u8500_i2c.h ? ? ? ? ? ? ? ? ? ? | ?194 +++++++++
> ?drivers/serial/serial_pl01x.c ? ? ? ? ? ? ? | ? 17 +-
> ?drivers/serial/serial_pl01x.h ? ? ? ? ? ? ? | ? ?4 +
> ?include/configs/u8500_href.h ? ? ? ? ? ? ? ?| ?245 +++++++++++
> ?22 files changed, 3026 insertions(+), 2 deletions(-)
> ?create mode 100644 arch/arm/cpu/armv7/u8500/Makefile
> ?create mode 100644 arch/arm/cpu/armv7/u8500/clock.c
> ?create mode 100644 arch/arm/cpu/armv7/u8500/lowlevel.S
> ?create mode 100644 arch/arm/cpu/armv7/u8500/timer.c
> ?create mode 100644 arch/arm/include/asm/arch-u8500/clock.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/gpio.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/hardware.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/sys_proto.h
> ?create mode 100644 arch/arm/include/asm/arch-u8500/u8500.h
> ?create mode 100644 board/st-ericsson/u8500/Makefile
> ?create mode 100644 board/st-ericsson/u8500/gpio.c
> ?create mode 100644 board/st-ericsson/u8500/prcmu-fw.h
> ?create mode 100644 board/st-ericsson/u8500/prcmu.c
> ?create mode 100644 board/st-ericsson/u8500/u8500_href.c
> ?create mode 100644 drivers/i2c/u8500_i2c.c
> ?create mode 100644 drivers/i2c/u8500_i2c.h
> ?create mode 100644 include/configs/u8500_href.h
>
>
Albert, can this series go in now?  At least the arm ones.  I will
followup on the serial and i2c ones with the appropriate maintainers.

Thanks,
John

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

* [U-Boot] [PATCHv3 0/4] ST-Ericsson U8500 support
  2011-04-28 14:47     ` John Rigby
@ 2011-04-28 15:40       ` Albert ARIBAUD
  2011-04-28 18:41         ` John Rigby
  0 siblings, 1 reply; 42+ messages in thread
From: Albert ARIBAUD @ 2011-04-28 15:40 UTC (permalink / raw)
  To: u-boot

Le 28/04/2011 16:47, John Rigby a ?crit :

>>   armv7: Add ST-Ericsson u8500 arch
>>   armv7: Add support for ST-Ericsson U8500 href platform

Applying these on top of the current u-boot-arm/master and trying a 
MAKEALL u8500_href (with an ELDK 4.2 toolchain) results in

Configuring for u8500_href board...
u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No 
such file or directory
u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No 
such file or directory
u8500_href.c: In function 'hrefplus_mmc_power_init':
u8500_href.c:258: warning: implicit declaration of function 'prcmu_i2c_read'
u8500_href.c:265: warning: implicit declaration of function 
'prcmu_i2c_write'
u8500_href.c: In function 'board_mmc_init':
u8500_href.c:453: warning: implicit declaration of function 
'arm_pl180_mmci_init'

Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCHv3 0/4] ST-Ericsson U8500 support
  2011-04-28 15:40       ` Albert ARIBAUD
@ 2011-04-28 18:41         ` John Rigby
  2011-05-12 13:41           ` John Rigby
  0 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-28 18:41 UTC (permalink / raw)
  To: u-boot

On Thu, Apr 28, 2011 at 9:40 AM, Albert ARIBAUD
<albert.u.boot@aribaud.net> wrote:
> Le 28/04/2011 16:47, John Rigby a ?crit :
>
>>> ?armv7: Add ST-Ericsson u8500 arch
>>> ?armv7: Add support for ST-Ericsson U8500 href platform
>
> Applying these on top of the current u-boot-arm/master and trying a MAKEALL
> u8500_href (with an ELDK 4.2 toolchain) results in
>
> Configuring for u8500_href board...
> u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No such
> file or directory
> u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No such
> file or directory
> u8500_href.c: In function 'hrefplus_mmc_power_init':
> u8500_href.c:258: warning: implicit declaration of function 'prcmu_i2c_read'
> u8500_href.c:265: warning: implicit declaration of function
> 'prcmu_i2c_write'
> u8500_href.c: In function 'board_mmc_init':
> u8500_href.c:453: warning: implicit declaration of function
> 'arm_pl180_mmci_init'
>
> Amicalement,
> --
> Albert.
>
Ok, we have a bit of a dependency problem.  I will followup on the
pending mmc and i2c patches and once they have been committed ping
you.

Thanks,
John

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

* [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
@ 2011-04-28 18:52     ` John Rigby
  2011-04-29  5:34       ` Heiko Schocher
  2011-06-01 17:34     ` Albert ARIBAUD
  1 sibling, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-04-28 18:52 UTC (permalink / raw)
  To: u-boot

On Tue, Apr 19, 2011 at 2:42 PM, John Rigby <john.rigby@linaro.org> wrote:
> From: Michael Brandt <michael.brandt@stericsson.com>
>
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> CC: Heiko Schocher <hs@denx.de>
> ---
> v2: Incorporate suggestions from Heiko Schocher
> v3: Fix line length problem reported by Heiko Schocher
> v4: No changes just rebased to latest and included for completeness
> ?drivers/i2c/Makefile ? ?| ? ?1 +
> ?drivers/i2c/u8500_i2c.c | ?613 +++++++++++++++++++++++++++++++++++++++++++++++
> ?drivers/i2c/u8500_i2c.h | ?194 +++++++++++++++
> ?3 files changed, 808 insertions(+), 0 deletions(-)
> ?create mode 100644 drivers/i2c/u8500_i2c.c
> ?create mode 100644 drivers/i2c/u8500_i2c.h
>
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 052fe36..43507fc 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -40,6 +40,7 @@ COBJS-$(CONFIG_S3C44B0_I2C) += s3c44b0_i2c.o
> ?COBJS-$(CONFIG_SOFT_I2C) += soft_i2c.o
> ?COBJS-$(CONFIG_SPEAR_I2C) += spr_i2c.o
> ?COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
> +COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
>
> ?COBJS ?:= $(COBJS-y)
> ?SRCS ? := $(COBJS:.o=.c)
> diff --git a/drivers/i2c/u8500_i2c.c b/drivers/i2c/u8500_i2c.c
> new file mode 100644
> index 0000000..ea8a71d
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.c
> @@ -0,0 +1,613 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2010
> + *
> + * Basic U-Boot I2C interface for STn8500/DB8500
> + * Author: Michael Brandt <Michael.Brandt@stericsson.com> for ST-Ericsson
> + *
> + * 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., 675 Mass Ave, Cambridge, MA 02139, USA.
> + */
> +
> +/*
> + * Only 7-bit I2C device addresses are supported.
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +
> +#include "u8500_i2c.h"
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +
> +#define U8500_I2C_ENDAD_COUNTER ? ? ? ?(CONFIG_SYS_HZ/100) ? ? /* I2C bus timeout */
> +#define U8500_I2C_FIFO_FLUSH_COUNTER ? 500000 ? ? ? ? ?/* flush "timeout" */
> +#define U8500_I2C_SCL_FREQ ? ? ? ? ? ? 100000 ? ? ? ? ?/* I2C bus clock freq */
> +#define U8500_I2C_INPUT_FREQ ? ? ? ? ? 48000000 ? ? ? ?/* Input clock freq */
> +#define TX_FIFO_THRESHOLD ? ? ?0x4
> +#define RX_FIFO_THRESHOLD ? ? ?0x4
> +#define SLAVE_SETUP_TIME 14 /* Slave data setup time, 250ns for 48MHz i2c_clk */
> +
> +#define WRITE_FIELD(var, mask, shift, value) \
> + ? ? ? ? ? ? ? ? ? ? ? (var = ((var & ~(mask)) | ((value) << (shift))))
> +
> +static unsigned int bus_initialized[CONFIG_SYS_U8500_I2C_BUS_MAX];
> +static unsigned int i2c_bus_num;
> +static unsigned int i2c_bus_speed[] = {
> + ? ? ? CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,
> + ? ? ? CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED
> +};
> +static struct u8500_i2c_regs *i2c_dev[] = {
> + ? ? ? (struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C0_BASE,
> + ? ? ? (struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C1_BASE,
> + ? ? ? (struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C2_BASE,
> + ? ? ? (struct u8500_i2c_regs *)CONFIG_SYS_U8500_I2C3_BASE,
> +};
> +
> +static struct {
> + ? ? ? int periph;
> + ? ? ? int pcken;
> + ? ? ? int kcken;
> +} i2c_clock_bits[] = {
> + ? ? ? {3, 3, 3}, /* I2C0 */
> + ? ? ? {1, 2, 2}, /* I2C1 */
> + ? ? ? {1, 6, 6}, /* I2C2 */
> + ? ? ? {2, 0, 0}, /* I2C3 */
> +};
> +
> +static void i2c_set_bit(void *reg, u32 mask)
> +{
> + ? ? ? writel(readl(reg) | mask, reg);
> +}
> +
> +static void i2c_clr_bit(void *reg, u32 mask)
> +{
> + ? ? ? writel(readl(reg) & ~mask, reg);
> +}
> +
> +static void i2c_write_field(void *reg, u32 mask, uint shift, u32 value)
> +{
> + ? ? ? writel((readl(reg) & ~mask) | (value << shift), reg);
> +}
> +
> +static int __i2c_set_bus_speed(unsigned int speed)
> +{
> + ? ? ? u32 value;
> + ? ? ? struct u8500_i2c_regs *i2c_regs;
> +
> + ? ? ? i2c_regs = i2c_dev[i2c_bus_num];
> +
> + ? ? ? /* Select standard (100 kbps) speed mode */
> + ? ? ? i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_SM,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_CR_SHIFT_SM, 0x0);
> +
> + ? ? ? /*
> + ? ? ? ?* Set the Baud Rate Counter 2 value
> + ? ? ? ?* Baud rate (standard) = fi2cclk / ( (BRCNT2 x 2) + Foncycle )
> + ? ? ? ?* Foncycle = 0 (no digital filtering)
> + ? ? ? ?*/
> + ? ? ? value = (u32) (U8500_I2C_INPUT_FREQ / (speed * 2));
> + ? ? ? i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT2,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_BRCR_SHIFT_BRCNT2, value);
> +
> + ? ? ? /* ensure that BRCNT value is zero */
> + ? ? ? i2c_write_field(&i2c_regs->brcr, U8500_I2C_BRCR_BRCNT1,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_BRCR_SHIFT_BRCNT1, 0);
> +
> + ? ? ? return U8500_I2C_INPUT_FREQ/(value * 2);
> +}
> +
> +/*
> + * i2c_init - initialize the i2c bus
> + *
> + * ? ? speed: bus speed (in HZ)
> + * ? ? slaveaddr: address of device in slave mode
> + *
> + * ? ? Slave mode is not implemented.
> + */
> +void i2c_init(int speed, int slaveaddr)
> +{
> + ? ? ? struct u8500_i2c_regs *i2c_regs;
> +
> + ? ? ? debug("i2c_init bus %d, speed %d\n", i2c_bus_num, speed);
> +
> + ? ? ? u8500_clock_enable(i2c_clock_bits[i2c_bus_num].periph,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?i2c_clock_bits[i2c_bus_num].pcken,
> + ? ? ? ? ? ? ? ? ? ? ? ? ?i2c_clock_bits[i2c_bus_num].kcken);
> +
> + ? ? ? i2c_regs = i2c_dev[i2c_bus_num];
> +
> + ? ? ? /* Disable the controller */
> + ? ? ? i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
> +
> + ? ? ? /* Clear registers */
> + ? ? ? writel(0, &i2c_regs->cr);
> + ? ? ? writel(0, &i2c_regs->scr);
> + ? ? ? writel(0, &i2c_regs->hsmcr);
> + ? ? ? writel(0, &i2c_regs->tftr);
> + ? ? ? writel(0, &i2c_regs->rftr);
> + ? ? ? writel(0, &i2c_regs->dmar);
> +
> + ? ? ? i2c_bus_speed[i2c_bus_num] = __i2c_set_bus_speed(speed);
> +
> + ? ? ? /*
> + ? ? ? ?* Set our own address.
> + ? ? ? ?* Set slave address mode to 7 bit addressing mode
> + ? ? ? ?*/
> + ? ? ? i2c_clr_bit(&i2c_regs->cr, U8500_I2C_CR_SAM);
> + ? ? ? i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_ADDR,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_SCR_SHIFT_ADDR, slaveaddr);
> + ? ? ? /* Slave Data Set up Time */
> + ? ? ? i2c_write_field(&i2c_regs->scr, U8500_I2C_SCR_DATA_SETUP_TIME,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME, SLAVE_SETUP_TIME);
> +
> + ? ? ? /* Disable the DMA sync logic */
> + ? ? ? i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_DMA_SLE,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_CR_SHIFT_DMA_SLE, 0);
> +
> + ? ? ? /* Disable interrupts */
> + ? ? ? writel(0, &i2c_regs->imscr);
> +
> + ? ? ? /* Configure bus master mode */
> + ? ? ? i2c_write_field(&i2c_regs->cr, U8500_I2C_CR_OM, U8500_I2C_CR_SHIFT_OM,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_BUS_MASTER_MODE);
> + ? ? ? /* Set FIFO threshold values */
> + ? ? ? writel(TX_FIFO_THRESHOLD, &i2c_regs->tftr);
> + ? ? ? writel(RX_FIFO_THRESHOLD, &i2c_regs->rftr);
> +
> + ? ? ? /* Enable the I2C Controller */
> + ? ? ? i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_PE);
> +
> + ? ? ? bus_initialized[i2c_bus_num] = 1;
> +}
> +
> +
> +/*
> + * loop_till_bit_clear - polls on a bit till it clears
> + * ioreg: register where you want to check status
> + * mask: bit mask for the bit you wish to check
> + * timeout: timeout in ticks/s
> + */
> +static int loop_till_bit_clear(void *io_reg, u32 mask, unsigned long timeout)
> +{
> + ? ? ? unsigned long timebase = get_timer(0);
> +
> + ? ? ? do {
> + ? ? ? ? ? ? ? if ((readl(io_reg) & mask) == 0x0UL)
> + ? ? ? ? ? ? ? ? ? ? ? return 0;
> + ? ? ? } while (get_timer(timebase) < timeout);
> +
> + ? ? ? debug("loop_till_bit_clear timed out\n");
> + ? ? ? return -1;
> +}
> +
> +/*
> + * loop_till_bit_set - polls on a bit till it is set.
> + * ioreg: register where you want to check status
> + * mask: bit mask for the bit you wish to check
> + * timeout: timeout in ticks/s
> + */
> +static int loop_till_bit_set(void *io_reg, u32 mask, unsigned long timeout)
> +{
> + ? ? ? unsigned long timebase = get_timer(0);
> +
> + ? ? ? do {
> + ? ? ? ? ? ? ? if ((readl(io_reg) & mask) != 0x0UL)
> + ? ? ? ? ? ? ? ? ? ? ? return 0;
> + ? ? ? } while (get_timer(timebase) < timeout);
> +
> + ? ? ? debug("loop_till_bit_set timed out\n");
> + ? ? ? return -1;
> +}
> +
> +/*
> + * flush_fifo - flush the I2C TX and RX FIFOs
> + */
> +static void flush_fifo(struct u8500_i2c_regs *i2c_regs)
> +{
> + ? ? ? int counter = U8500_I2C_FIFO_FLUSH_COUNTER;
> +
> + ? ? ? /* Flush Tx FIFO */
> + ? ? ? i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FTX);
> + ? ? ? /* Flush Rx FIFO */
> + ? ? ? i2c_set_bit(&i2c_regs->cr, U8500_I2C_CR_FRX);
> + ? ? ? while (counter--) {
> + ? ? ? ? ? ? ? if (!(readl(&i2c_regs->cr) &
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (U8500_I2C_CR_FTX | U8500_I2C_CR_FRX)))
> + ? ? ? ? ? ? ? ? ? ? ? break;
> + ? ? ? }
> + ? ? ? return;
> +}
> +
> +#ifdef DEBUG
> +static void print_abort_reason(struct u8500_i2c_regs *i2c_regs)
> +{
> + ? ? ? int cause;
> +
> + ? ? ? printf("abort: risr %08x, sr %08x\n", i2c_regs->risr, i2c_regs->sr);
> + ? ? ? cause = (readl(&i2c_regs->sr) & U8500_I2C_SR_CAUSE) >>
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_SR_SHIFT_CAUSE;
> + ? ? ? switch (cause) {
> + ? ? ? case U8500_I2C_NACK_ADDR:
> + ? ? ? ? ? ? ? printf("No Ack received after Slave Address xmission\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_NACK_DATA:
> + ? ? ? ? ? ? ? printf("Valid for MASTER_WRITE: No Ack received "
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "during data phase\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_ACK_MCODE:
> + ? ? ? ? ? ? ? printf("Master recv ack after xmission of master code"
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "in hs mode\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_ARB_LOST:
> + ? ? ? ? ? ? ? printf("Master Lost arbitration\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_BERR_START:
> + ? ? ? ? ? ? ? printf("Slave restarts\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_BERR_STOP:
> + ? ? ? ? ? ? ? printf("Slave reset\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? case U8500_I2C_OVFL:
> + ? ? ? ? ? ? ? printf("Overflow\n");
> + ? ? ? ? ? ? ? break;
> + ? ? ? default:
> + ? ? ? ? ? ? ? printf("Unknown error type\n");
> + ? ? ? }
> +}
> +#endif
> +
> +/*
> + * i2c_abort - called when a I2C transaction failed
> + */
> +static void i2c_abort(struct u8500_i2c_regs *i2c_regs)
> +{
> +#ifdef DEBUG
> + ? ? ? print_abort_reason(i2c_regs);
> +#endif
> + ? ? ? /* flush RX and TX fifos */
> + ? ? ? flush_fifo(i2c_regs);
> +
> + ? ? ? /* Acknowledge the Master Transaction Done */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
> +
> + ? ? ? /* Acknowledge the Master Transaction Done Without Stop */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
> +
> + ? ? ? i2c_init(i2c_bus_speed[i2c_bus_num], CONFIG_SYS_I2C_SLAVE);
> +}
> +
> +/*
> + * write addr, alias index, to I2C bus.
> + */
> +static int i2c_write_addr(struct u8500_i2c_regs *i2c_regs, uint addr, int alen)
> +{
> + ? ? ? while (alen--) {
> + ? ? ? ? ? ? ? /* Wait until the Tx Fifo is not full */
> + ? ? ? ? ? ? ? if (loop_till_bit_clear((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_TXFF,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER)) {
> + ? ? ? ? ? ? ? ? ? ? ? i2c_abort(i2c_regs);
> + ? ? ? ? ? ? ? ? ? ? ? return -1;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* MSB first */
> + ? ? ? ? ? ? ? writeb((addr >> (alen * 8)) & 0xff, &i2c_regs->tfr);
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * Internal simplified read function:
> + * ? i2c_regs: Pointer to I2C registers for current bus
> + * ? chip: ? ? I2C chip address, range 0..127
> + * ? addr: ? ? Memory (register) address within the chip
> + * ? alen: ? ? Number of bytes to use for addr (typically 1, 2 for larger
> + * ? ? ? ? ? ? memories, 0 for register type devices with only one register)
> + * ? value: ? ?Where to put the data
> + *
> + * ? Returns: ?0 on success, not 0 on failure
> + */
> +static int i2c_read_byte(struct u8500_i2c_regs *i2c_regs, uchar chip,
> + ? ? ? ? ? ? ? uint addr, int alen, uchar *value)
> +{
> + ? ? ? u32 ? mcr = 0;
> +
> + ? ? ? /* Set the address mode to 7 bit */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
> +
> + ? ? ? /* Store the slave address in the master control register */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
> +
> + ? ? ? if (alen != 0) {
> + ? ? ? ? ? ? ? /* Master write operation */
> + ? ? ? ? ? ? ? mcr &= ~(U8500_I2C_MCR_OP);
> +
> + ? ? ? ? ? ? ? /* Configure the Frame length to one byte */
> + ? ? ? ? ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_MCR_SHIFT_LENGTH, 1);
> +
> + ? ? ? ? ? ? ? /* Repeated start, no stop */
> + ? ? ? ? ? ? ? mcr &= ~(U8500_I2C_MCR_STOP);
> +
> + ? ? ? ? ? ? ? /* Write Master Control Register */
> + ? ? ? ? ? ? ? writel(mcr, &i2c_regs->mcr);
> +
> + ? ? ? ? ? ? ? /* send addr/index */
> + ? ? ? ? ? ? ? if (i2c_write_addr(i2c_regs, addr, alen) != 0)
> + ? ? ? ? ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? ? ? ? ? /* Check for the Master Transaction Done Without Stop */
> + ? ? ? ? ? ? ? if (loop_till_bit_set((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_MTDWS,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER)) {
> + ? ? ? ? ? ? ? ? ? ? ? return -1;
> + ? ? ? ? ? ? ? }
> +
> + ? ? ? ? ? ? ? /* Acknowledge the Master Transaction Done Without Stop */
> + ? ? ? ? ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
> + ? ? ? }
> +
> + ? ? ? /* Master control configuration for read operation ?*/
> + ? ? ? mcr |= U8500_I2C_MCR_OP;
> +
> + ? ? ? /* Configure the STOP condition, we read only one byte */
> + ? ? ? mcr |= U8500_I2C_MCR_STOP;
> +
> + ? ? ? /* Set the frame length to one byte, we support only 1 byte reads */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
> +
> + ? ? ? i2c_write_field(&i2c_regs->mcr, U8500_I2C_MCR_LENGTH_STOP_OP,
> + ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP, mcr);
> +
> + ? ? ? /*
> + ? ? ? ?* receive_data_polling
> + ? ? ? ?*/
> +
> + ? ? ? /* Wait until the Rx FIFO is not empty */
> + ? ? ? if (loop_till_bit_clear((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_RXFE,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER))
> + ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? /* Read the data byte from Rx FIFO */
> + ? ? ? *value = readb(&i2c_regs->rfr);
> +
> + ? ? ? /* Wait until the work is done */
> + ? ? ? if (loop_till_bit_set((void *)&i2c_regs->risr, U8500_I2C_INT_MTD,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER))
> + ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? /* Acknowledge the Master Transaction Done */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
> +
> + ? ? ? /* If MTD is set, Master Transaction Done Without Stop is set too */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * Internal simplified write function:
> + * ? i2c_regs: Pointer to I2C registers for current bus
> + * ? chip: ? ? I2C chip address, range 0..127
> + * ? addr: ? ? Memory (register) address within the chip
> + * ? alen: ? ? Number of bytes to use for addr (typically 1, 2 for larger
> + * ? ? ? ? ? ? memories, 0 for register type devices with only one register)
> + * ? data: ? ? Where to read the data
> + * ? len: ? ? ?How many bytes to write
> + *
> + * ? Returns: ?0 on success, not 0 on failure
> + */
> +static int __i2c_write(struct u8500_i2c_regs *i2c_regs, u8 chip, uint addr,
> + ? ? ? ? ? ? ? int alen, u8 *data, int len)
> +{
> + ? ? ? int i;
> + ? ? ? u32 mcr = 0;
> +
> + ? ? ? /* Set the address mode to 7 bit */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
> +
> + ? ? ? /* Store the slave address in the master control register */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_A7, U8500_I2C_MCR_SHIFT_A7, chip);
> +
> + ? ? ? /* Write operation */
> + ? ? ? mcr &= ~(U8500_I2C_MCR_OP);
> +
> + ? ? ? /* Current transaction is terminated by STOP condition */
> + ? ? ? mcr |= U8500_I2C_MCR_STOP;
> +
> + ? ? ? /* Frame length: addr byte + len */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH,
> + ? ? ? ? ? ? ? ? ? ? ? (alen + len));
> +
> + ? ? ? /* Write MCR register */
> + ? ? ? writel(mcr, &i2c_regs->mcr);
> +
> + ? ? ? if (i2c_write_addr(i2c_regs, addr, alen) != 0)
> + ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? for (i = 0; i < len; i++) {
> + ? ? ? ? ? ? ? /* Wait until the Tx FIFO is not full */
> + ? ? ? ? ? ? ? if (loop_till_bit_clear((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_TXFF,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER))
> + ? ? ? ? ? ? ? ? ? ? ? return -1;
> +
> + ? ? ? ? ? ? ? /* it is a 32 bit register with upper 24 reserved R/O */
> + ? ? ? ? ? ? ? writeb(data[i], &i2c_regs->tfr);
> + ? ? ? }
> +
> + ? ? ? /* Check for Master Transaction Done */
> + ? ? ? if (loop_till_bit_set((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_MTD,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER)) {
> + ? ? ? ? ? ? ? printf("i2c_write_byte error2: risr %08x\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? i2c_regs->risr);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? /* Acknowledge Master Transaction Done */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
> +
> + ? ? ? /* Acknowledge Master Transaction Done Without Stop */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * Probe the given I2C chip address. Returns 0 if a chip responded,
> + * not 0 on failure.
> + */
> +int i2c_probe(uchar chip)
> +{
> + ? ? ? u32 mcr = 0;
> + ? ? ? struct u8500_i2c_regs *i2c_regs;
> +
> + ? ? ? if (chip == CONFIG_SYS_I2C_SLAVE)
> + ? ? ? ? ? ? ? return 1;
> +
> + ? ? ? i2c_regs = i2c_dev[i2c_bus_num];
> +
> + ? ? ? /* Set the address mode to 7 bit */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_AM, U8500_I2C_MCR_SHIFT_AM, 1);
> +
> + ? ? ? /* Store the slave address in the master control register */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_A10, U8500_I2C_MCR_SHIFT_A7, chip);
> +
> + ? ? ? /* Read operation */
> + ? ? ? mcr |= U8500_I2C_MCR_OP;
> +
> + ? ? ? /* Set the frame length to one byte */
> + ? ? ? WRITE_FIELD(mcr, U8500_I2C_MCR_LENGTH, U8500_I2C_MCR_SHIFT_LENGTH, 1);
> +
> + ? ? ? /* Current transaction is terminated by STOP condition */
> + ? ? ? mcr |= U8500_I2C_MCR_STOP;
> +
> + ? ? ? /* Write MCR register */
> + ? ? ? writel(mcr, &i2c_regs->mcr);
> +
> + ? ? ? /* Wait until the Rx Fifo is not empty */
> + ? ? ? if (loop_till_bit_clear((void *)&i2c_regs->risr,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_INT_RXFE,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_ENDAD_COUNTER)) {
> + ? ? ? ? ? ? ? i2c_abort(i2c_regs);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? flush_fifo(i2c_regs);
> +
> + ? ? ? /* Acknowledge the Master Transaction Done */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTD);
> +
> + ? ? ? /* Acknowledge the Master Transaction Done Without Stop */
> + ? ? ? i2c_set_bit(&i2c_regs->icr, U8500_I2C_INT_MTDWS);
> +
> + ? ? ? return 0;
> +}
> +
> +/*
> + * Read/Write interface:
> + * ? chip: ? ?I2C chip address, range 0..127
> + * ? addr: ? ?Memory (register) address within the chip
> + * ? alen: ? ?Number of bytes to use for addr (typically 1, 2 for larger
> + * ? ? ? ? ? ? ?memories, 0 for register type devices with only one
> + * ? ? ? ? ? ? ?register)
> + * ? buffer: ?Where to read/write the data
> + * ? len: ? ? How many bytes to read/write
> + *
> + * ? Returns: 0 on success, not 0 on failure
> + */
> +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> + ? ? ? int i;
> + ? ? ? int rc;
> + ? ? ? struct u8500_i2c_regs *i2c_regs;
> +
> + ? ? ? if (alen > 2) {
> + ? ? ? ? ? ? ? debug("I2C read: addr len %d not supported\n", alen);
> + ? ? ? ? ? ? ? return 1;
> + ? ? ? }
> +
> + ? ? ? i2c_regs = i2c_dev[i2c_bus_num];
> +
> + ? ? ? for (i = 0; i < len; i++) {
> + ? ? ? ? ? ? ? rc = i2c_read_byte(i2c_regs, chip, addr + i, alen, &buffer[i]);
> + ? ? ? ? ? ? ? if (rc != 0) {
> + ? ? ? ? ? ? ? ? ? ? ? debug("I2C read: I/O error: %d\n", rc);
> + ? ? ? ? ? ? ? ? ? ? ? i2c_abort(i2c_regs);
> + ? ? ? ? ? ? ? ? ? ? ? return rc;
> + ? ? ? ? ? ? ? }
> + ? ? ? }
> +
> + ? ? ? return 0;
> +}
> +
> +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> + ? ? ? int rc;
> + ? ? ? struct u8500_i2c_regs *i2c_regs;
> + ? ? ? i2c_regs = i2c_dev[i2c_bus_num];
> +
> + ? ? ? rc = __i2c_write(i2c_regs, chip, addr, alen, buffer,
> + ? ? ? ? ? ? ? ? ? ? ? len);
> + ? ? ? if (rc != 0) {
> + ? ? ? ? ? ? ? debug("I2C write: I/O error\n");
> + ? ? ? ? ? ? ? i2c_abort(i2c_regs);
> + ? ? ? ? ? ? ? return rc;
> + ? ? ? }
> + ? ? ? return 0;
> +}
> +
> +int i2c_set_bus_num(unsigned int bus)
> +{
> + ? ? ? if (bus > ARRAY_SIZE(i2c_dev) - 1) {
> + ? ? ? ? ? ? ? debug("i2c_set_bus_num: only up to bus %d supported\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ARRAY_SIZE(i2c_dev)-1);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? i2c_bus_num = bus;
> +
> + ? ? ? if (!bus_initialized[i2c_bus_num])
> + ? ? ? ? ? ? ? i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> +
> + ? ? ? return 0;
> +}
> +
> +int i2c_set_bus_speed(unsigned int speed)
> +{
> +
> + ? ? ? if (speed > U8500_I2C_MAX_STANDARD_SCL) {
> + ? ? ? ? ? ? ? debug("i2c_set_bus_speed: only up to %d supported\n",
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? U8500_I2C_MAX_STANDARD_SCL);
> + ? ? ? ? ? ? ? return -1;
> + ? ? ? }
> +
> + ? ? ? /* sets as side effect i2c_bus_speed[i2c_bus_num] */
> + ? ? ? i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
> +
> + ? ? ? return 0;
> +}
> +
> +unsigned int i2c_get_bus_num(void)
> +{
> + ? ? ? return i2c_bus_num;
> +}
> +
> +unsigned int i2c_get_bus_speed(void)
> +{
> + ? ? ? return i2c_bus_speed[i2c_bus_num];
> +}
> diff --git a/drivers/i2c/u8500_i2c.h b/drivers/i2c/u8500_i2c.h
> new file mode 100644
> index 0000000..91dbd3e
> --- /dev/null
> +++ b/drivers/i2c/u8500_i2c.h
> @@ -0,0 +1,194 @@
> +/*
> + * Copyright (C) ST-Ericsson SA 2009
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * 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
> + */
> +
> +#ifndef _U8500_I2C_H_
> +#define _U8500_I2C_H_
> +
> +#include <asm/types.h>
> +#include <asm/io.h>
> +#include <asm/errno.h>
> +#include <asm/arch/u8500.h>
> +
> +struct u8500_i2c_regs {
> + ? ? ? u32 cr; ? ? ? ? ? ? ? ? /* Control Register ? ? ? ? ? ? ? ? ? ? ?0x00 */
> + ? ? ? u32 scr; ? ? ? ? ? ? ? ?/* Slave Address Register ? ? ? ? ? ? ? ?0x04 */
> + ? ? ? u32 hsmcr; ? ? ? ? ? ? ?/* HS Master code Register ? ? ? ? ? ? ? 0x08 */
> + ? ? ? u32 mcr; ? ? ? ? ? ? ? ?/* Master Control Register ? ? ? ? ? ? ? 0x0C */
> + ? ? ? u32 tfr; ? ? ? ? ? ? ? ?/* Transmit Fifo Register ? ? ? ? ? ? ? ?0x10 */
> + ? ? ? u32 sr; ? ? ? ? ? ? ? ? /* Status Register ? ? ? ? ? ? ? ? ? ? ? 0x14 */
> + ? ? ? u32 rfr; ? ? ? ? ? ? ? ?/* Receiver Fifo Register ? ? ? ? ? ? ? ?0x18 */
> + ? ? ? u32 tftr; ? ? ? ? ? ? ? /* Transmit Fifo Threshold Register ? ? ?0x1C */
> + ? ? ? u32 rftr; ? ? ? ? ? ? ? /* Receiver Fifo Threshold Register ? ? ?0x20 */
> + ? ? ? u32 dmar; ? ? ? ? ? ? ? /* DMA register ? ? ? ? ? ? ? ? ? ? ? ? ?0x24 */
> + ? ? ? u32 brcr; ? ? ? ? ? ? ? /* Baud Rate Counter Register ? ? ? ? ? ?0x28 */
> + ? ? ? u32 imscr; ? ? ? ? ? ? ?/* Interrupt Mask Set and Clear Register 0x2C */
> + ? ? ? u32 risr; ? ? ? ? ? ? ? /* Raw interrupt status register ? ? ? ? 0x30 */
> + ? ? ? u32 misr; ? ? ? ? ? ? ? /* Masked interrupt status register ? ? ?0x34 */
> + ? ? ? u32 icr; ? ? ? ? ? ? ? ?/* Interrupt Set and Clear Register ? ? ?0x38 */
> + ? ? ? u32 reserved_1[(0xFE0 - 0x3c) >> 2]; ? ?/* Reserved 0x03C to 0xFE0 */
> + ? ? ? u32 periph_id_0; ? ? ? ?/* peripheral ID 0 ? ? ? ? ? ? ? ? ? ? ?0xFE0 */
> + ? ? ? u32 periph_id_1; ? ? ? ?/* peripheral ID 1 ? ? ? ? ? ? ? ? ? ? ?0xFE4 */
> + ? ? ? u32 periph_id_2; ? ? ? ?/* peripheral ID 2 ? ? ? ? ? ? ? ? ? ? ?0xFE8 */
> + ? ? ? u32 periph_id_3; ? ? ? ?/* peripheral ID 3 ? ? ? ? ? ? ? ? ? ? ?0xFEC */
> + ? ? ? u32 cell_id_0; ? ? ? ? ?/* I2C cell ? ID 0 ? ? ? ? ? ? ? ? ? ? ?0xFF0 */
> + ? ? ? u32 cell_id_1; ? ? ? ? ?/* I2C cell ? ID 1 ? ? ? ? ? ? ? ? ? ? ?0xFF4 */
> + ? ? ? u32 cell_id_2; ? ? ? ? ?/* I2C cell ? ID 2 ? ? ? ? ? ? ? ? ? ? ?0xFF8 */
> + ? ? ? u32 cell_id_3; ? ? ? ? ?/* I2C cell ? ID 3 ? ? ? ? ? ? ? ? ? ? ?0xFFC */
> +};
> +
> +
> +/* Control Register */
> +
> +/* Mask values for control register mask */
> +#define U8500_I2C_CR_PE ? ? ? ? ?0x0001 ? ? ? ?/* Peripheral enable */
> +#define U8500_I2C_CR_OM ? ? ? ? ?0x0006 ? ? ? ?/* Operation mode */
> +#define U8500_I2C_CR_SAM ? ? ? ? 0x0008 ? ? ? ?/* Slave Addressing mode */
> +#define U8500_I2C_CR_SM ? ? ? ? ?0x0030 ? ? ? ?/* Speed mode */
> +#define U8500_I2C_CR_SGCM ? ? ? ?0x0040 ? ? ? ?/* Slave General call mode */
> +#define U8500_I2C_CR_FTX ? ? ? ? 0x0080 ? ? ? ?/* Flush Transmit */
> +#define U8500_I2C_CR_FRX ? ? ? ? 0x0100 ? ? ? ?/* Flush Receive */
> +#define U8500_I2C_CR_DMA_TX_EN ? 0x0200 ? ? ? ?/* DMA TX Enable */
> +#define U8500_I2C_CR_DMA_RX_EN ? 0x0400 ? ? ? ?/* DMA Rx Enable */
> +#define U8500_I2C_CR_DMA_SLE ? ? 0x0800 ? ? ? ?/* DMA Synchronization Logic enable */
> +#define U8500_I2C_CR_LM ? ? ? ? ?0x1000 ? ? ? ?/* Loop back mode */
> +#define U8500_I2C_CR_FON ? ? ? ? 0x6000 ? ? ? ?/* Filtering On */
> +
> +/* shift valus for control register bit fields */
> +#define U8500_I2C_CR_SHIFT_PE ? ? ? ? ?0 ? ? ? /* Peripheral enable */
> +#define U8500_I2C_CR_SHIFT_OM ? ? ? ? ?1 ? ? ? /* Operation mode */
> +#define U8500_I2C_CR_SHIFT_SAM ? ? ? ? 3 ? ? ? /* Slave Addressing mode */
> +#define U8500_I2C_CR_SHIFT_SM ? ? ? ? ?4 ? ? ? /* Speed mode */
> +#define U8500_I2C_CR_SHIFT_SGCM ? ? ? ? ? ? ? ?6 ? ? ? /* Slave General call mode */
> +#define U8500_I2C_CR_SHIFT_FTX ? ? ? ? 7 ? ? ? /* Flush Transmit */
> +#define U8500_I2C_CR_SHIFT_FRX ? ? ? ? 8 ? ? ? /* Flush Receive */
> +#define U8500_I2C_CR_SHIFT_DMA_TX_EN ? 9 ? ? ? /* DMA TX Enable */
> +#define U8500_I2C_CR_SHIFT_DMA_RX_EN ? 10 ? ? ?/* DMA Rx Enable */
> +#define U8500_I2C_CR_SHIFT_DMA_SLE ? ? 11 ? ? ?/* DMA Synch Logic enable */
> +#define U8500_I2C_CR_SHIFT_LM ? ? ? ? ?12 ? ? ?/* Loop back mode */
> +#define U8500_I2C_CR_SHIFT_FON ? ? ? ? 13 ? ? ?/* Filtering On */
> +
> +/* bus operation modes */
> +#define U8500_I2C_BUS_SLAVE_MODE ? ? ? ? ? ? ? 0
> +#define U8500_I2C_BUS_MASTER_MODE ? ? ? ? ? ? ?1
> +#define U8500_I2C_BUS_MASTER_SLAVE_MODE ? ? ? ?2
> +
> +
> +/* Slave control register*/
> +
> +/* Mask values slave control register */
> +#define U8500_I2C_SCR_ADDR ? ? ? ? ? ? ? ? ? 0x3FF
> +#define U8500_I2C_SCR_DATA_SETUP_TIME ? ? ? ?0xFFFF0000
> +
> +/* Shift values for Slave control register */
> +#define U8500_I2C_SCR_SHIFT_ADDR ? ? ? ? ? ? ? 0
> +#define U8500_I2C_SCR_SHIFT_DATA_SETUP_TIME ? ?16
> +
> +
> +/* Master Control Register */
> +
> +/* Mask values for Master control register */
> +#define U8500_I2C_MCR_OP ? ? ? 0x00000001 ? ? ?/* Operation */
> +#define U8500_I2C_MCR_A7 ? ? ? 0x000000FE ? ? ?/* LSB bits of Address */
> +#define U8500_I2C_MCR_EA10 ? ? 0x00000700 ? ? ?/* Extended Address */
> +#define U8500_I2C_MCR_SB ? ? ? 0x00000800 ? ? ?/* Start byte procedure */
> +#define U8500_I2C_MCR_AM ? ? ? 0x00003000 ? ? ?/* Address type */
> +#define U8500_I2C_MCR_STOP ? ? 0x00004000 ? ? ?/* stop condition */
> +#define U8500_I2C_MCR_LENGTH ? 0x03FF8000 ? ? ?/* Frame length */
> +#define U8500_I2C_MCR_A10 ? ? ?0x000007FE ? ? ?/* Enable 10 bit address */
> +/* mask for length field,stop and operation ?*/
> +#define U8500_I2C_MCR_LENGTH_STOP_OP ? 0x3FFC001
> +
> +/* Shift values for Master control values */
> +#define U8500_I2C_MCR_SHIFT_OP ? ? ? ? 0 ? ? ? /* Operation */
> +#define U8500_I2C_MCR_SHIFT_A7 ? ? ? ? 1 ? ? ? /* LSB bits of Address */
> +#define U8500_I2C_MCR_SHIFT_EA10 ? ? ? 8 ? ? ? /* Extended Address */
> +#define U8500_I2C_MCR_SHIFT_SB ? ? ? ? 11 ? ? ?/* Start byte procedure */
> +#define U8500_I2C_MCR_SHIFT_AM ? ? ? ? 12 ? ? ?/* Address type */
> +#define U8500_I2C_MCR_SHIFT_STOP ? ? ? 14 ? ? ?/* stop condition */
> +#define U8500_I2C_MCR_SHIFT_LENGTH ? ? 15 ? ? ?/* Frame length */
> +#define U8500_I2C_MCR_SHIFT_A10 ? ? ? ? ? ? ? ?1 ? ? ? /* Enable 10 bit address */
> +
> +#define U8500_I2C_MCR_SHIFT_LENGTH_STOP_OP ? ? 0
> +
> +
> +/* Status Register */
> +
> +/* Mask values for Status register */
> +#define U8500_I2C_SR_OP ? ? ? ?0x00000003 ? ? ?/* Operation */
> +#define U8500_I2C_SR_STATUS ? ?0x0000000C ? ? ?/* Controller Status */
> +#define U8500_I2C_SR_CAUSE ? ? 0x00000070 ? ? ?/* Abort Cause */
> +#define U8500_I2C_SR_TYPE ? ? ?0x00000180 ? ? ?/* Receive Type */
> +#define U8500_I2C_SR_LENGTH ? ?0x000FF700 ? ? ?/* Transfer length */
> +
> +/* Shift values for Status register */
> +#define U8500_I2C_SR_SHIFT_OP ? ? ? ? ?0 ? ? ? /* Operation */
> +#define U8500_I2C_SR_SHIFT_STATUS ? ? ?2 ? ? ? /* Controller Status */
> +#define U8500_I2C_SR_SHIFT_CAUSE ? ? ? 4 ? ? ? /* Abort Cause */
> +#define U8500_I2C_SR_SHIFT_TYPE ? ? ? ?7 ? ? ? /* Receive Type */
> +#define U8500_I2C_SR_SHIFT_LENGTH ? ? ?9 ? ? ? /* Transfer length */
> +
> +/* abort cause */
> +#define ? ? ? ?U8500_I2C_NACK_ADDR ? ? 0
> +#define ? ? ? ?U8500_I2C_NACK_DATA ? ? 1
> +#define ? ? ? ?U8500_I2C_ACK_MCODE ? ? 2
> +#define ? ? ? ?U8500_I2C_ARB_LOST ? ? ?3
> +#define ? ? ? ?U8500_I2C_BERR_START ? ?4
> +#define ? ? ? ?U8500_I2C_BERR_STOP ? ? 5
> +#define ? ? ? ?U8500_I2C_OVFL ?6
> +
> +
> +/* Baud rate counter registers */
> +
> +/* Mask values for Baud rate counter register */
> +#define U8500_I2C_BRCR_BRCNT2 ?0xFFFF ? ? ? ? ?/* Baud Rate Cntr BRCR for HS */
> +#define U8500_I2C_BRCR_BRCNT1 ?0xFFFF0000 ? ? ?/* BRCR for Standard and Fast */
> +
> +/* Shift values for the Baud rate counter register */
> +#define U8500_I2C_BRCR_SHIFT_BRCNT2 ? ?0
> +#define U8500_I2C_BRCR_SHIFT_BRCNT1 ? ?16
> +
> +
> +/* Interrupt Register ?*/
> +
> +/* Mask values for Interrupt registers */
> +#define U8500_I2C_INT_TXFE ? ? 0x00000001 ? ? ?/* Tx fifo empty */
> +#define U8500_I2C_INT_TXFNE ? ?0x00000002 ? ? ?/* Tx Fifo nearly empty */
> +#define U8500_I2C_INT_TXFF ? ? 0x00000004 ? ? ?/* Tx Fifo Full */
> +#define U8500_I2C_INT_TXFOVR ? 0x00000008 ? ? ?/* Tx Fifo over run */
> +#define U8500_I2C_INT_RXFE ? ? 0x00000010 ? ? ?/* Rx Fifo Empty */
> +#define U8500_I2C_INT_RXFNF ? ?0x00000020 ? ? ?/* Rx Fifo nearly empty */
> +#define U8500_I2C_INT_RXFF ? ? 0x00000040 ? ? ?/* Rx Fifo Full ?*/
> +#define U8500_I2C_INT_RFSR ? ? 0x00010000 ? ? ?/* Read From slave request */
> +#define U8500_I2C_INT_RFSE ? ? 0x00020000 ? ? ?/* Read from slave empty */
> +#define U8500_I2C_INT_WTSR ? ? 0x00040000 ? ? ?/* Write to Slave request */
> +#define U8500_I2C_INT_MTD ? ? ?0x00080000 ? ? ?/* Master Transcation Done*/
> +#define U8500_I2C_INT_STD ? ? ?0x00100000 ? ? ?/* Slave Transaction Done */
> +#define U8500_I2C_INT_MAL ? ? ?0x01000000 ? ? ?/* Master Arbitation Lost */
> +#define U8500_I2C_INT_BERR ? ? 0x02000000 ? ? ?/* Bus Error */
> +#define U8500_I2C_INT_MTDWS ? ?0x10000000 ? ? ?/* Master Tran Done wo/ Stop */
> +
> +/* Max clocks (Hz) */
> +#define U8500_I2C_MAX_STANDARD_SCL ? ? 100000
> +#define U8500_I2C_MAX_FAST_SCL ? ? ? ? 400000
> +#define U8500_I2C_MAX_HIGH_SPEED_SCL ? 3400000
> +
> +#endif /* _U8500_I2C_H_ */
> --
> 1.7.1
>
>

Heiko, can you commit this to the i2c tree?  Thanks, it is needed for
the board patches in this series.

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

* [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-28 18:52     ` John Rigby
@ 2011-04-29  5:34       ` Heiko Schocher
  0 siblings, 0 replies; 42+ messages in thread
From: Heiko Schocher @ 2011-04-29  5:34 UTC (permalink / raw)
  To: u-boot

Hello John,

John Rigby wrote:
> On Tue, Apr 19, 2011 at 2:42 PM, John Rigby <john.rigby@linaro.org> wrote:
>> From: Michael Brandt <michael.brandt@stericsson.com>
>>
>> Signed-off-by: John Rigby <john.rigby@linaro.org>
>> CC: Heiko Schocher <hs@denx.de>
>> ---
>> v2: Incorporate suggestions from Heiko Schocher
>> v3: Fix line length problem reported by Heiko Schocher
>> v4: No changes just rebased to latest and included for completeness
>>  drivers/i2c/Makefile    |    1 +
>>  drivers/i2c/u8500_i2c.c |  613 +++++++++++++++++++++++++++++++++++++++++++++++
>>  drivers/i2c/u8500_i2c.h |  194 +++++++++++++++
>>  3 files changed, 808 insertions(+), 0 deletions(-)
>>  create mode 100644 drivers/i2c/u8500_i2c.c
>>  create mode 100644 drivers/i2c/u8500_i2c.h
>>
[...]
> 
> Heiko, can you commit this to the i2c tree?  Thanks, it is needed for
> the board patches in this series.

I gave this patch my Acked-by here:

http://lists.denx.de/pipermail/u-boot/2011-April/090241.html

so, it can picked up, from the custodian, who applies the whole
series. I think Albert Aribaud will pick it up (Actually for some
days on vacation).

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

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

* [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options
  2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
                     ` (9 preceding siblings ...)
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
@ 2011-05-12  8:05   ` John Rigby
  2011-05-12 17:10     ` Wolfgang Denk
  10 siblings, 1 reply; 42+ messages in thread
From: John Rigby @ 2011-05-12  8:05 UTC (permalink / raw)
  To: u-boot

Two new options:

CONFIG_PL011_SERIAL_RLCR

Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
have separate receive and transmit line control registers.  Set
this variable to initialize the extra register.

CONFIG_PL011_SERIAL_FLUSH_ON_INIT

On some platforms (e.g. U8500) U-Boot is loaded by a second stage
boot loader that has already initialized the UART.  Define this
variable to flush the UART at init time.
empty fifo on init

Signed-off-by: John Rigby <john.rigby@linaro.org>
Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
---
v2: No changes
v3: Enable changes with new CONFIG_* options instead of platform.
Document new CONFIG_* options in README.
v4: Added delay before writing to RLCR.
Removed Rabin as author at his request.
v5: Fixed commit message p1011 to pl011

 README                        |   12 ++++++++++++
 drivers/serial/serial_pl01x.c |   30 +++++++++++++++++++++++++++---
 drivers/serial/serial_pl01x.h |    4 ++++
 3 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/README b/README
index 76b1500..68ef2b2 100644
--- a/README
+++ b/README
@@ -475,6 +475,18 @@ The following options need to be configured:
 		define this to a list of base addresses for each (supported)
 		port. See e.g. include/configs/versatile.h
 
+		CONFIG_PL011_SERIAL_RLCR
+
+		Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
+		have separate receive and transmit line control registers.  Set
+		this variable to initialize the extra register.
+
+		CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+
+		On some platforms (e.g. U8500) U-Boot is loaded by a second stage
+		boot loader that has already initialized the UART.  Define this
+		variable to flush the UART at init time.
+
 
 - Console Interface:
 		Depending on board, define exactly one serial port
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index 5dfcde8..7a064ff 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -111,6 +111,15 @@ int serial_init (void)
 	unsigned int divider;
 	unsigned int remainder;
 	unsigned int fraction;
+	unsigned int lcr;
+
+#ifdef CONFIG_PL011_SERIAL_FLUSH_ON_INIT
+	/* Empty RX fifo if necessary */
+	if (readl(&regs->pl011_cr) & UART_PL011_CR_UARTEN) {
+		while (!(readl(&regs->fr) & UART_PL01x_FR_RXFE))
+			readl(&regs->dr);
+	}
+#endif
 
 	/* First, disable everything */
 	writel(0, &regs->pl011_cr);
@@ -131,9 +140,24 @@ int serial_init (void)
 	writel(fraction, &regs->pl011_fbrd);
 
 	/* Set the UART to be 8 bits, 1 stop bit, no parity, fifo enabled */
-	writel(UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN,
-	       &regs->pl011_lcrh);
-
+	lcr = UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN;
+	writel(lcr, &regs->pl011_lcrh);
+
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	{
+		int i;
+
+		/*
+		 * Program receive line control register after waiting
+		 * 10 bus cycles.  Delay be writing to readonly register
+		 * 10 times
+		 */
+		for (i = 0; i < 10; i++)
+			writel(lcr, &regs->fr);
+
+		writel(lcr, &regs->pl011_rlcr);
+	}
+#endif
 	/* Finally, enable the UART */
 	writel(UART_PL011_CR_UARTEN | UART_PL011_CR_TXE | UART_PL011_CR_RXE,
 	       &regs->pl011_cr);
diff --git a/drivers/serial/serial_pl01x.h b/drivers/serial/serial_pl01x.h
index b670c24..96ee381 100644
--- a/drivers/serial/serial_pl01x.h
+++ b/drivers/serial/serial_pl01x.h
@@ -43,7 +43,11 @@ struct pl01x_regs {
 	u32	pl010_lcrl;	/* 0x10 Line control register, low byte */
 	u32	pl010_cr;	/* 0x14 Control register */
 	u32	fr;		/* 0x18 Flag register (Read only) */
+#ifdef CONFIG_PL011_SERIAL_RLCR
+	u32	pl011_rlcr;	/* 0x1c Receive line control register */
+#else
 	u32	reserved;
+#endif
 	u32	ilpr;		/* 0x20 IrDA low-power counter register */
 	u32	pl011_ibrd;	/* 0x24 Integer baud rate register */
 	u32	pl011_fbrd;	/* 0x28 Fractional baud rate register */
-- 
1.7.1

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

* [U-Boot] [PATCHv3 0/4] ST-Ericsson U8500 support
  2011-04-28 18:41         ` John Rigby
@ 2011-05-12 13:41           ` John Rigby
  0 siblings, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-05-12 13:41 UTC (permalink / raw)
  To: u-boot

On Thu, Apr 28, 2011 at 8:41 PM, John Rigby <john.rigby@linaro.org> wrote:
> On Thu, Apr 28, 2011 at 9:40 AM, Albert ARIBAUD
> <albert.u.boot@aribaud.net> wrote:
>> Le 28/04/2011 16:47, John Rigby a ?crit :
>>
>>>> ?armv7: Add ST-Ericsson u8500 arch
>>>> ?armv7: Add support for ST-Ericsson U8500 href platform
>>
>> Applying these on top of the current u-boot-arm/master and trying a MAKEALL
>> u8500_href (with an ELDK 4.2 toolchain) results in
>>
>> Configuring for u8500_href board...
>> u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No such
>> file or directory
>> u8500_href.c:30:49: error: ../../../drivers/mmc/arm_pl180_mmci.h: No such
>> file or directory
>> u8500_href.c: In function 'hrefplus_mmc_power_init':
>> u8500_href.c:258: warning: implicit declaration of function 'prcmu_i2c_read'
>> u8500_href.c:265: warning: implicit declaration of function
>> 'prcmu_i2c_write'
>> u8500_href.c: In function 'board_mmc_init':
>> u8500_href.c:453: warning: implicit declaration of function
>> 'arm_pl180_mmci_init'
>>
>> Amicalement,
>> --
>> Albert.
>>
> Ok, we have a bit of a dependency problem. ?I will followup on the
> pending mmc and i2c patches and once they have been committed ping
> you.
>
Heiko has acked the i2c patch and indicated it was ok for you to
commit it with the others.  The soc and board patches apply cleanly
and build now that the mmc driver is in.  So I think these can go in
now.

I will ping Wolfgang about the pl011 serial patch.

Thanks,
John

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

* [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options
  2011-05-12  8:05   ` [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options John Rigby
@ 2011-05-12 17:10     ` Wolfgang Denk
  0 siblings, 0 replies; 42+ messages in thread
From: Wolfgang Denk @ 2011-05-12 17:10 UTC (permalink / raw)
  To: u-boot

Dear John Rigby,

In message <1305187511-8455-1-git-send-email-john.rigby@linaro.org> you wrote:
> Two new options:
> 
> CONFIG_PL011_SERIAL_RLCR
> 
> Some vendor versions of PL011 serial ports (e.g. ST-Ericsson U8500)
> have separate receive and transmit line control registers.  Set
> this variable to initialize the extra register.
> 
> CONFIG_PL011_SERIAL_FLUSH_ON_INIT
> 
> On some platforms (e.g. U8500) U-Boot is loaded by a second stage
> boot loader that has already initialized the UART.  Define this
> variable to flush the UART at init time.
> empty fifo on init
> 
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> Signed-off-by: Rabin Vincent <rabin.vincent@stericsson.com>
> ---
> v2: No changes
> v3: Enable changes with new CONFIG_* options instead of platform.
> Document new CONFIG_* options in README.
> v4: Added delay before writing to RLCR.
> Removed Rabin as author at his request.
> v5: Fixed commit message p1011 to pl011
> 
>  README                        |   12 ++++++++++++
>  drivers/serial/serial_pl01x.c |   30 +++++++++++++++++++++++++++---
>  drivers/serial/serial_pl01x.h |    4 ++++
>  3 files changed, 43 insertions(+), 3 deletions(-)

Applied, thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"We don't have to protect the environment -- the Second Coming is  at
hand."                                                   - James Watt

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

* [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
@ 2011-05-19 21:54     ` John Rigby
  2011-06-01 17:34     ` Albert ARIBAUD
  1 sibling, 0 replies; 42+ messages in thread
From: John Rigby @ 2011-05-19 21:54 UTC (permalink / raw)
  To: u-boot

On Tue, Apr 19, 2011 at 2:42 PM, John Rigby <john.rigby@linaro.org> wrote:
> Based on ST-Ericsson internal git repo.
>
> Signed-off-by: Mathieu Poirier <mathieu.poirier@linaro.org>
> Signed-off-by: John Rigby <john.rigby@linaro.org>
> CC: Albert Aribaud <albert.aribaud@free.fr>
> ---
> v2: cleanup, mostly removal of unused defines
> v3: remove prototype from sys_proto.h as suggested by Wolfgang
> v4: incorporate changes suggested by Albert:
> ?Add copyright to arch/arm/cpu/armv7/u8500/lowlevel.S
> ?Remove confusing/incorrect timer comment in arch/arm/cpu/armv7/u8500/timer.c
> ?Remove reset timer functions from ..../timer.c

Albert, can this and parts 3 and 4 go in for rc2?  As I said before
Heiko acked the I2C patch and indicated it was ok with him for it to
go in via your tree.

Thanks,
John

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

* [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
  2011-05-19 21:54     ` John Rigby
@ 2011-06-01 17:34     ` Albert ARIBAUD
  1 sibling, 0 replies; 42+ messages in thread
From: Albert ARIBAUD @ 2011-06-01 17:34 UTC (permalink / raw)
  To: u-boot

Hi John,

Le 19/04/2011 22:42, John Rigby a ?crit :
> Based on ST-Ericsson internal git repo.
>
> Signed-off-by: Mathieu Poirier<mathieu.poirier@linaro.org>
> Signed-off-by: John Rigby<john.rigby@linaro.org>
> CC: Albert Aribaud<albert.aribaud@free.fr>
> ---
> v2: cleanup, mostly removal of unused defines
> v3: remove prototype from sys_proto.h as suggested by Wolfgang
> v4: incorporate changes suggested by Albert:
>    Add copyright to arch/arm/cpu/armv7/u8500/lowlevel.S
>    Remove confusing/incorrect timer comment in arch/arm/cpu/armv7/u8500/timer.c
>    Remove reset timer functions from ..../timer.c

Applied to u-boot-arm/master, thanks.

Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
  2011-04-28 18:52     ` John Rigby
@ 2011-06-01 17:34     ` Albert ARIBAUD
  1 sibling, 0 replies; 42+ messages in thread
From: Albert ARIBAUD @ 2011-06-01 17:34 UTC (permalink / raw)
  To: u-boot

Hi John,

Le 19/04/2011 22:42, John Rigby a ?crit :
> From: Michael Brandt<michael.brandt@stericsson.com>
>
> Signed-off-by: John Rigby<john.rigby@linaro.org>
> CC: Heiko Schocher<hs@denx.de>
> ---
> v2: Incorporate suggestions from Heiko Schocher
> v3: Fix line length problem reported by Heiko Schocher
> v4: No changes just rebased to latest and included for completeness

Applied to u-boot-arm/master, thanks.

Amicalement,
-- 
Albert.

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

* [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform
  2011-04-19 20:42   ` [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
@ 2011-06-01 17:35     ` Albert ARIBAUD
  0 siblings, 0 replies; 42+ messages in thread
From: Albert ARIBAUD @ 2011-06-01 17:35 UTC (permalink / raw)
  To: u-boot

Hi John,

Le 19/04/2011 22:42, John Rigby a ?crit :
> Minimal platform support to boot linux from SD.
>
> Supported devices/hw limited to external MMC/SD slot,
> GPIO, I2C and minimal PRCMU.
>
> Signed-off-by: John Rigby<john.rigby@linaro.org>
> CC: Albert Aribaud<albert.aribaud@free.fr>
> ---
> This board support requires mmc driver patch set from Matt Waddel.
> v2: cleanup, mostly removal of unused defines and include files
> v3: incorporate changes suggested by Wolfgang including:

Applied (manually) to u-boot-arm/master, thanks.

Amicalement,
-- 
Albert.

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

end of thread, other threads:[~2011-06-01 17:35 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-03-22 20:40 [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
2011-03-22 20:40 ` [U-Boot] [PATCH 1/4] p101x: extra init for u8500 John Rigby
2011-03-22 20:40 ` [U-Boot] [PATCH 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
2011-04-11 18:04   ` Wolfgang Denk
2011-03-22 20:40 ` [U-Boot] [PATCH 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
2011-03-23  7:00   ` Heiko Schocher
2011-03-22 20:40 ` [U-Boot] [PATCH 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
2011-03-22 20:46 ` [U-Boot] [PATCH 0/4] ST-Ericsson U8500 support John Rigby
2011-04-02 16:19 ` [U-Boot] [PATCHv2 " John Rigby
2011-04-11 17:33   ` John Rigby
2011-04-11 19:52     ` Albert ARIBAUD
2011-04-12  6:17   ` [U-Boot] [PATCHv3 " John Rigby
2011-04-28 14:47     ` John Rigby
2011-04-28 15:40       ` Albert ARIBAUD
2011-04-28 18:41         ` John Rigby
2011-05-12 13:41           ` John Rigby
2011-04-12  6:17   ` [U-Boot] [PATCHv3 1/4] Serial: p1011: new vendor init options John Rigby
2011-04-12  6:17   ` [U-Boot] [PATCHv3 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
2011-04-12  7:25     ` Albert ARIBAUD
2011-04-12  6:17   ` [U-Boot] [PATCHv3 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
2011-04-12  6:47     ` Heiko Schocher
2011-04-12  6:17   ` [U-Boot] [PATCHv3 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
2011-04-19 20:42   ` [U-Boot] [PATCHv4 1/4] Serial: p1011: new vendor init options John Rigby
2011-04-19 20:59     ` Kumar Gala
2011-04-19 20:42   ` [U-Boot] [PATCHv4 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
2011-05-19 21:54     ` John Rigby
2011-06-01 17:34     ` Albert ARIBAUD
2011-04-19 20:42   ` [U-Boot] [PATCHv4 3/4] I2C: Add driver for ST-Ericsson U8500 i2c John Rigby
2011-04-28 18:52     ` John Rigby
2011-04-29  5:34       ` Heiko Schocher
2011-06-01 17:34     ` Albert ARIBAUD
2011-04-19 20:42   ` [U-Boot] [PATCHv4 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
2011-06-01 17:35     ` Albert ARIBAUD
2011-05-12  8:05   ` [U-Boot] [PATCH 1/4] Serial: pl011: new vendor init options John Rigby
2011-05-12 17:10     ` Wolfgang Denk
2011-04-02 16:19 ` [U-Boot] [PATCHv2 1/4] p101x: extra init for u8500 John Rigby
2011-04-11 17:48   ` Wolfgang Denk
2011-04-02 16:19 ` [U-Boot] [PATCHv2 2/4] armv7: Add ST-Ericsson u8500 arch John Rigby
2011-04-02 16:19 ` [U-Boot] [PATCHv2 3/4] I2C: add driver of st-ericsson u8500 i2c John Rigby
2011-04-04  5:45   ` Heiko Schocher
2011-04-02 16:19 ` [U-Boot] [PATCHv2 4/4] armv7: Add support for ST-Ericsson U8500 href platform John Rigby
2011-04-11 18:09   ` Wolfgang Denk

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