diff --git a/Makefile b/Makefile
index 332c79a2bcf55219f0c0df605a67223eae76307d..44cd35754dcb758ba87bda28193b4a4681164c57 100644
--- a/Makefile
+++ b/Makefile
@@ -1890,7 +1890,7 @@ CPUAT91_RAM_config \
 CPUAT91_config	:	unconfig
 	@mkdir -p $(obj)include
 	@echo "#define CONFIG_$(@:_config=) 1"	>$(obj)include/config.h
-	@$(MKCONFIG) -n $@ -a cpuat91 arm arm920t cpuat91 eukrea at91rm9200
+	@$(MKCONFIG) -n $@ -a cpuat91 arm arm920t cpuat91 eukrea at91
 
 #########################################################################
 ## ARM926EJ-S Systems
diff --git a/arch/arm/cpu/arm926ejs/at91/Makefile b/arch/arm/cpu/arm926ejs/at91/Makefile
index 4f467be91c2ce8f2c5cc0828088eadd6cf05f096..def3980b63496ab3cbca212a1d856f6c82953976 100644
--- a/arch/arm/cpu/arm926ejs/at91/Makefile
+++ b/arch/arm/cpu/arm926ejs/at91/Makefile
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_AT91SAM9263)	+= at91sam9263_devices.o
 COBJS-$(CONFIG_AT91SAM9RL)	+= at91sam9rl_devices.o
 COBJS-$(CONFIG_AT91SAM9M10G45)	+= at91sam9m10g45_devices.o
 COBJS-$(CONFIG_AT91SAM9G45)	+= at91sam9m10g45_devices.o
+COBJS-$(CONFIG_AT91_EFLASH)	+= eflash.o
 COBJS-$(CONFIG_AT91_LED)	+= led.o
 COBJS-y += clock.o
 COBJS-y += cpu.o
diff --git a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
index 77d49ab1c762fb20ea0550e73801952d2ea8cc6a..87b04426b9b4d3fd53dcf79da5951feddb57e284 100644
--- a/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
+++ b/arch/arm/cpu/arm926ejs/at91/at91sam9260_devices.c
@@ -28,12 +28,27 @@
 #include <asm/arch/gpio.h>
 #include <asm/arch/io.h>
 
+/*
+ * if CONFIG_AT91_GPIO_PULLUP ist set, keep pullups on on all
+ * peripheral pins. Good to have if hardware is soldered optionally
+ * or in case of SPI no slave is selected. Avoid lines to float
+ * needlessly. Use a short local PUP define.
+ *
+ * Due to errata "TXD floats when CTS is inactive" pullups are always
+ * on for TXD pins.
+ */
+#ifdef CONFIG_AT91_GPIO_PULLUP
+# define PUP CONFIG_AT91_GPIO_PULLUP
+#else
+# define PUP 0
+#endif
+
 void at91_serial0_hw_init(void)
 {
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
 	at91_set_a_periph(AT91_PIO_PORTB, 4, 1);		/* TXD0 */
-	at91_set_a_periph(AT91_PIO_PORTB, 5, 0);		/* RXD0 */
+	at91_set_a_periph(AT91_PIO_PORTB, 5, PUP);		/* RXD0 */
 	writel(1 << AT91SAM9260_ID_US0, &pmc->pcer);
 }
 
@@ -42,7 +57,7 @@ void at91_serial1_hw_init(void)
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
 	at91_set_a_periph(AT91_PIO_PORTB, 6, 1);		/* TXD1 */
-	at91_set_a_periph(AT91_PIO_PORTB, 7, 0);		/* RXD1 */
+	at91_set_a_periph(AT91_PIO_PORTB, 7, PUP);		/* RXD1 */
 	writel(1 << AT91SAM9260_ID_US1, &pmc->pcer);
 }
 
@@ -51,7 +66,7 @@ void at91_serial2_hw_init(void)
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
 	at91_set_a_periph(AT91_PIO_PORTB, 8, 1);		/* TXD2 */
-	at91_set_a_periph(AT91_PIO_PORTB, 9, 0);		/* RXD2 */
+	at91_set_a_periph(AT91_PIO_PORTB, 9, PUP);		/* RXD2 */
 	writel(1 << AT91SAM9260_ID_US2, &pmc->pcer);
 }
 
@@ -59,7 +74,7 @@ void at91_serial3_hw_init(void)
 {
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
-	at91_set_a_periph(AT91_PIO_PORTB, 14, 0);		/* DRXD */
+	at91_set_a_periph(AT91_PIO_PORTB, 14, PUP);		/* DRXD */
 	at91_set_a_periph(AT91_PIO_PORTB, 15, 1);		/* DTXD */
 	writel(1 << AT91_ID_SYS, &pmc->pcer);
 }
@@ -88,9 +103,9 @@ void at91_spi0_hw_init(unsigned long cs_mask)
 {
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
-	at91_set_a_periph(AT91_PIO_PORTA, 0, 0);	/* SPI0_MISO */
-	at91_set_a_periph(AT91_PIO_PORTA, 1, 0);	/* SPI0_MOSI */
-	at91_set_a_periph(AT91_PIO_PORTA, 2, 0);	/* SPI0_SPCK */
+	at91_set_a_periph(AT91_PIO_PORTA, 0, PUP);	/* SPI0_MISO */
+	at91_set_a_periph(AT91_PIO_PORTA, 1, PUP);	/* SPI0_MOSI */
+	at91_set_a_periph(AT91_PIO_PORTA, 2, PUP);	/* SPI0_SPCK */
 
 	/* Enable clock */
 	writel(1 << AT91SAM9260_ID_SPI0, &pmc->pcer);
@@ -125,9 +140,9 @@ void at91_spi1_hw_init(unsigned long cs_mask)
 {
 	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 
-	at91_set_a_periph(AT91_PIO_PORTB, 0, 0);	/* SPI1_MISO */
-	at91_set_a_periph(AT91_PIO_PORTB, 1, 0);	/* SPI1_MOSI */
-	at91_set_a_periph(AT91_PIO_PORTB, 2, 0);	/* SPI1_SPCK */
+	at91_set_a_periph(AT91_PIO_PORTB, 0, PUP);	/* SPI1_MISO */
+	at91_set_a_periph(AT91_PIO_PORTB, 1, PUP);	/* SPI1_MOSI */
+	at91_set_a_periph(AT91_PIO_PORTB, 2, PUP);	/* SPI1_SPCK */
 
 	/* Enable clock */
 	writel(1 << AT91SAM9260_ID_SPI1, &pmc->pcer);
@@ -194,3 +209,24 @@ void at91_macb_hw_init(void)
 #endif
 }
 #endif
+
+#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+void at91_mci_hw_init(void)
+{
+	at91_set_a_periph(AT91_PIO_PORTA, 8, 1);	/* MCCK */
+#if defined(CONFIG_ATMEL_MCI_PORTB)
+	at91_set_b_periph(AT91_PIO_PORTA, 1, 1);	/* MCCDB */
+	at91_set_b_periph(AT91_PIO_PORTA, 0, 1);	/* MCDB0 */
+	at91_set_b_periph(AT91_PIO_PORTA, 5, 1);	/* MCDB1 */
+	at91_set_b_periph(AT91_PIO_PORTA, 4, 1);	/* MCDB2 */
+	at91_set_b_periph(AT91_PIO_PORTA, 3, 1);	/* MCDB3 */
+#else
+	at91_set_a_periph(AT91_PIO_PORTA, 7, 1);	/* MCCDA */
+	at91_set_a_periph(AT91_PIO_PORTA, 6, 1);	/* MCDA0 */
+	at91_set_a_periph(AT91_PIO_PORTA, 9, 1);	/* MCDA1 */
+	at91_set_a_periph(AT91_PIO_PORTA, 10, 1);	/* MCDA2 */
+	at91_set_a_periph(AT91_PIO_PORTA, 11, 1);	/* MCDA3 */
+#endif
+}
+#endif
+
diff --git a/arch/arm/cpu/arm926ejs/at91/eflash.c b/arch/arm/cpu/arm926ejs/at91/eflash.c
new file mode 100644
index 0000000000000000000000000000000000000000..2e851dbd2c8e3d716a65728ec5b2373b471d4938
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/at91/eflash.c
@@ -0,0 +1,271 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, EMK Elektronik, reinhard.meyer@emk-elektronik.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
+ */
+
+/*
+ * this driver supports the enhanced embedded flash in the Atmel
+ * AT91SAM9XE devices with the following geometry:
+ *
+ * AT91SAM9XE128: 1 plane of  8 regions of 32 pages (total  256 pages)
+ * AT91SAM9XE256: 1 plane of 16 regions of 32 pages (total  512 pages)
+ * AT91SAM9XE512: 1 plane of 32 regions of 32 pages (total 1024 pages)
+ * (the exact geometry is read from the flash at runtime, so any
+ *  future devices should already be covered)
+ *
+ * Regions can be write/erase protected.
+ * Whole (!) pages can be individually written with erase on the fly.
+ * Writing partial pages will corrupt the rest of the page.
+ *
+ * The flash is presented to u-boot with each region being a sector,
+ * having the following effects:
+ * Each sector can be hardware protected (protect on/off).
+ * Each page in a sector can be rewritten anytime.
+ * Since pages are erased when written, the "erase" does nothing.
+ * The first "CONFIG_EFLASH_PROTSECTORS" cannot be unprotected
+ * by u-Boot commands.
+ *
+ * Note: Redundant environment will not work in this flash since
+ * it does use partial page writes. Make sure the environent spans
+ * whole pages!
+ */
+
+/*
+ * optional TODOs (nice to have features):
+ *
+ * make the driver coexist with other NOR flash drivers
+ *	(use an index into flash_info[], requires work
+ *	in those other drivers, too)
+ * Make the erase command fill the sectors with 0xff
+ *	(if the flashes grow larger in the future and
+ *	someone puts a jffs2 into them)
+ * do a read-modify-write for partially programmed pages
+ */
+#include <common.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/io.h>
+#include <asm/arch/at91_common.h>
+#include <asm/arch/at91_eefc.h>
+#include <asm/arch/at91_dbu.h>
+
+/* checks to detect configuration errors */
+#if CONFIG_SYS_MAX_FLASH_BANKS!=1
+#error eflash: this driver can only handle 1 bank
+#endif
+
+/* global structure */
+flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
+static u32 pagesize;
+
+unsigned long flash_init (void)
+{
+	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+	at91_dbu_t *dbu = (at91_dbu_t *) 0xfffff200;
+	u32 id, size, nplanes, planesize, nlocks;
+	u32 addr, i, tmp=0;
+
+	debug("eflash: init\n");
+
+	flash_info[0].flash_id = FLASH_UNKNOWN;
+
+	/* check if its an AT91ARM9XE SoC */
+	if ((readl(&dbu->cidr) & AT91_DBU_CID_ARCH_MASK) != AT91_DBU_CID_ARCH_9XExx) {
+		puts("eflash: not an AT91SAM9XE\n");
+		return 0;
+	}
+
+	/* now query the eflash for its structure */
+	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GETD, &eefc->fcr);
+	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+		;
+	id = readl(&eefc->frr);		/* word 0 */
+	size = readl(&eefc->frr);	/* word 1 */
+	pagesize = readl(&eefc->frr);	/* word 2 */
+	nplanes = readl(&eefc->frr);	/* word 3 */
+	planesize = readl(&eefc->frr);	/* word 4 */
+	debug("id=%08x size=%u pagesize=%u planes=%u planesize=%u\n",
+		id, size, pagesize, nplanes, planesize);
+	for (i=1; i<nplanes; i++) {
+		tmp = readl(&eefc->frr);	/* words 5..4+nplanes-1 */
+	};
+	nlocks = readl(&eefc->frr);	/* word 4+nplanes */
+	debug("nlocks=%u\n", nlocks);
+	/* since we are going to use the lock regions as sectors, check count */
+	if (nlocks > CONFIG_SYS_MAX_FLASH_SECT) {
+		printf("eflash: number of lock regions(%u) "\
+			"> CONFIG_SYS_MAX_FLASH_SECT. reducing...\n",
+			nlocks);
+		nlocks = CONFIG_SYS_MAX_FLASH_SECT;
+	}
+	flash_info[0].size = size;
+	flash_info[0].sector_count = nlocks;
+	flash_info[0].flash_id = id;
+
+	addr = AT91SAM9XE_FLASH_BASE;
+	for (i=0; i<nlocks; i++) {
+		tmp = readl(&eefc->frr);	/* words 4+nplanes+1.. */
+		flash_info[0].start[i] = addr;
+		flash_info[0].protect[i] = 0;
+		addr += tmp;
+	};
+
+	/* now read the protection information for all regions */
+	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
+	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+		;
+	for (i=0; i<flash_info[0].sector_count; i++) {
+		if (i%32 == 0)
+			tmp = readl(&eefc->frr);
+		flash_info[0].protect[i] = (tmp >> (i%32)) & 1;
+#if defined(CONFIG_EFLASH_PROTSECTORS)
+		if (i < CONFIG_EFLASH_PROTSECTORS)
+			flash_info[0].protect[i] = 1;
+#endif
+	}
+
+	return size;
+}
+
+void flash_print_info (flash_info_t *info)
+{
+	int i;
+
+	puts("AT91SAM9XE embedded flash\n  Size: ");
+	print_size(info->size, " in ");
+	printf("%d Sectors\n", info->sector_count);
+
+	printf("  Sector Start Addresses:");
+	for (i=0; i<info->sector_count; ++i) {
+		if ((i % 5) == 0)
+			printf("\n   ");
+		printf(" %08lX%s",
+			info->start[i],
+			info->protect[i] ? " (RO)" : "     "
+		);
+	}
+	printf ("\n");
+	return;
+}
+
+int flash_real_protect (flash_info_t *info, long sector, int prot)
+{
+	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+	u32 pagenum = (info->start[sector]-AT91SAM9XE_FLASH_BASE)/pagesize;
+	u32 i, tmp=0;
+
+	debug("protect sector=%ld prot=%d\n", sector, prot);
+
+#if defined(CONFIG_EFLASH_PROTSECTORS)
+	if (sector < CONFIG_EFLASH_PROTSECTORS) {
+		if (!prot) {
+			printf("eflash: sector %lu cannot be unprotected\n",
+				sector);
+		}
+		return 1; /* return anyway, caller does not care for result */
+	}
+#endif
+	if (prot) {
+		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_SLB |
+			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+	} else {
+		writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_CLB |
+			(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+	}
+	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+		;
+	/* now re-read the protection information for all regions */
+	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_GLB, &eefc->fcr);
+	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+		;
+	for (i=0; i<info->sector_count; i++) {
+		if (i%32 == 0)
+			tmp = readl(&eefc->frr);
+		info->protect[i] = (tmp >> (i%32)) & 1;
+	}
+	return 0;
+}
+
+static u32 erase_write_page (u32 pagenum)
+{
+	at91_eefc_t *eefc = (at91_eefc_t *) 0xfffffa00;
+
+	debug("erase+write page=%u\n", pagenum);
+
+	/* give erase and write page command */
+	writel(AT91_EEFC_FCR_KEY | AT91_EEFC_FCR_FCMD_EWP |
+		(pagenum << AT91_EEFC_FCR_FARG_SHIFT), &eefc->fcr);
+	while ((readl(&eefc->fsr) & AT91_EEFC_FSR_FRDY) == 0)
+		;
+	/* return status */
+	return readl(&eefc->fsr)
+		& (AT91_EEFC_FSR_FCMDE | AT91_EEFC_FSR_FLOCKE);
+}
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+	debug("erase first=%d last=%d\n", s_first, s_last);
+	puts("this flash does not need and support erasing!\n");
+	return 0;
+}
+
+/*
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+	u32 pagenum;
+	u32 *src32, *dst32;
+	u32 i;
+
+	debug("write src=%08lx addr=%08lx cnt=%lx\n",
+		(ulong)src, addr, cnt);
+
+	/* REQUIRE addr to be on a page start, abort if not */
+	if (addr % pagesize) {
+		printf ("eflash: start %08lx is not on page start\n"\
+			"        write aborted\n", addr);
+		return 1;
+	}
+
+	/* now start copying data */
+	pagenum = (addr-AT91SAM9XE_FLASH_BASE)/pagesize;
+	src32 = (u32 *) src;
+	dst32 = (u32 *) addr;
+	while (cnt > 0) {
+		i = pagesize / 4;
+		/* fill page buffer */
+		while (i--)
+			*dst32++ = *src32++;
+		/* write page */
+		if (erase_write_page(pagenum))
+			return 1;
+		pagenum++;
+		if (cnt > pagesize)
+			cnt -= pagesize;
+		else
+			cnt = 0;
+	}
+	return 0;
+}
+
diff --git a/arch/arm/cpu/arm926ejs/at91/reset.c b/arch/arm/cpu/arm926ejs/at91/reset.c
index 1b67e77887f762f4ebda6c3394824a67866e0b6b..d2569d8baea7c71ef3203dede7a327e3f5a6ca4a 100644
--- a/arch/arm/cpu/arm926ejs/at91/reset.c
+++ b/arch/arm/cpu/arm926ejs/at91/reset.c
@@ -27,18 +27,19 @@
 #include <asm/arch/at91_rstc.h>
 #include <asm/arch/io.h>
 
-/*
- * Reset the cpu by setting up the watchdog timer and let him time out.
- */
+/* Reset the cpu by telling the reset controller to do so */
 void reset_cpu(ulong ignored)
 {
 	at91_rstc_t *rstc = (at91_rstc_t *) AT91_RSTC_BASE;
 
-	/* this is the way Linux does it */
-
-	writel(AT91_RSTC_KEY | AT91_RSTC_CR_PROCRST | AT91_RSTC_CR_PERRST,
-		&rstc->cr);
-
-	while (1);
-	/* Never reached */
+	writel(AT91_RSTC_KEY
+		| AT91_RSTC_CR_PROCRST	/* Processor Reset */
+		| AT91_RSTC_CR_PERRST	/* Peripheral Reset */
+#ifdef CONFIG_AT91RESET_EXTRST
+		| AT91_RSTC_CR_EXTRST	/* External Reset (assert nRST pin) */
+#endif
+		, &rstc->cr);
+	/* never reached */
+	while (1)
+		;
 }
diff --git a/arch/arm/cpu/arm926ejs/at91/timer.c b/arch/arm/cpu/arm926ejs/at91/timer.c
index d21eebfb4eb1766cc43909c7f2e3046aab615d1e..8efc34bcf12061d81244e6736c45b38b54e32b17 100644
--- a/arch/arm/cpu/arm926ejs/at91/timer.c
+++ b/arch/arm/cpu/arm926ejs/at91/timer.c
@@ -138,8 +138,5 @@ ulong get_timer(ulong base)
  */
 ulong get_tbclk(void)
 {
-	ulong tbclk;
-
-	tbclk = CONFIG_SYS_HZ;
-	return tbclk;
+	return timer_freq;
 }
diff --git a/arch/arm/include/asm/arch-at91/at91_common.h b/arch/arm/include/asm/arch-at91/at91_common.h
index 01840eede41f94ed58d104301249a7b2a6ce02e1..0067190a20e9ca027ad3a82f2a70ecc166a5311b 100644
--- a/arch/arm/include/asm/arch-at91/at91_common.h
+++ b/arch/arm/include/asm/arch-at91/at91_common.h
@@ -27,6 +27,7 @@
 
 void at91_can_hw_init(void);
 void at91_macb_hw_init(void);
+void at91_mci_hw_init(void);
 void at91_serial_hw_init(void);
 void at91_serial0_hw_init(void);
 void at91_serial1_hw_init(void);
diff --git a/arch/arm/include/asm/arch-at91/at91_dbu.h b/arch/arm/include/asm/arch-at91/at91_dbu.h
new file mode 100644
index 0000000000000000000000000000000000000000..3429293535988e0fff312fd9c30748cbe8d8f129
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_dbu.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Debug Unit
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_DBU_H
+#define AT91_DBU_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_dbu {
+	u32	cr;	/* Control Register WO */
+	u32	mr;	/* Mode Register  RW */
+	u32	ier;	/* Interrupt Enable Register WO */
+	u32	idr;	/* Interrupt Disable Register WO */
+	u32	imr;	/* Interrupt Mask Register RO */
+	u32	sr;	/* Status Register RO */
+	u32	rhr;	/* Receive Holding Register RO */
+	u32	thr;	/* Transmit Holding Register WO */
+	u32	brgr;	/* Baud Rate Generator Register RW */
+	u32	res1[7];/* 0x0024 - 0x003C Reserved */
+	u32	cidr;	/* Chip ID Register RO */
+	u32	exid;	/* Chip ID Extension Register RO */
+	u32	fnr;	/* Force NTRST Register RW */
+} at91_dbu_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_DBU_CID_ARCH_MASK		0x0ff00000
+#define AT91_DBU_CID_ARCH_9xx		0x01900000
+#define AT91_DBU_CID_ARCH_9XExx	0x02900000
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_eefc.h b/arch/arm/include/asm/arch-at91/at91_eefc.h
new file mode 100644
index 0000000000000000000000000000000000000000..d45b3deca48ae0a435513f89b7b1289b98d327dd
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_eefc.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Enhanced Embedded Flash Controller
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_EEFC_H
+#define AT91_EEFC_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_eefc {
+	u32	fmr;	/* Flash Mode Register RW */
+	u32	fcr;	/* Flash Command Register WO */
+	u32	fsr;	/* Flash Status Register RO */
+	u32	frr;	/* Flash Result Register RO */
+} at91_eefc_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_EEFC_FMR_FWS_MASK	0x00000f00
+#define AT91_EEFC_FMR_FRDY_BIT	0x00000001
+
+#define AT91_EEFC_FCR_KEY		0x5a000000
+#define AT91_EEFC_FCR_FARG_MASK	0x00ffff00
+#define AT91_EEFC_FCR_FARG_SHIFT	8
+#define AT91_EEFC_FCR_FCMD_GETD	0x0
+#define AT91_EEFC_FCR_FCMD_WP		0x1
+#define AT91_EEFC_FCR_FCMD_WPL		0x2
+#define AT91_EEFC_FCR_FCMD_EWP		0x3
+#define AT91_EEFC_FCR_FCMD_EWPL	0x4
+#define AT91_EEFC_FCR_FCMD_EA		0x5
+#define AT91_EEFC_FCR_FCMD_SLB		0x8
+#define AT91_EEFC_FCR_FCMD_CLB		0x9
+#define AT91_EEFC_FCR_FCMD_GLB		0xA
+#define AT91_EEFC_FCR_FCMD_SGPB	0xB
+#define AT91_EEFC_FCR_FCMD_CGPB	0xC
+#define AT91_EEFC_FCR_FCMD_GGPB	0xD
+
+#define AT91_EEFC_FSR_FRDY	1
+#define AT91_EEFC_FSR_FCMDE	2
+#define AT91_EEFC_FSR_FLOCKE	4
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_gpbr.h b/arch/arm/include/asm/arch-at91/at91_gpbr.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf1d790dd9dbe8f6c7b0cf61ec617999c49266aa
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_gpbr.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * General Purpose Backup Registers
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_GPBR_H
+#define AT91_GPBR_H
+
+/*
+ * The Atmel AT91SAM9 series has a small resource of 4 nonvolatile
+ * 32 Bit registers (buffered by the Vbu power).
+ *
+ * Please consider carefully before using this resource for tasks
+ * that do not really need nonvolatile registers. Maybe you can
+ * store information in EEPROM or FLASH instead.
+ *
+ * However, if you use a GPBR please document its use here and
+ * reference the define in your code!
+ *
+ * known typical uses of the GPBRs:
+ * GPBR[0]: offset for RTT timekeeping (u-boot, kernel)
+ * GPBR[1]: unused
+ * GPBR[2]: unused
+ * GPBR[3]: bootcount (u-boot)
+ */
+#define AT91_GPBR_INDEX_TIMEOFF 0
+#define AT91_GPBR_INDEX_BOOTCOUNT 3
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_gpbr {
+	u32 reg[4];
+} at91_gpbr_t;
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91_pit.h b/arch/arm/include/asm/arch-at91/at91_pit.h
index 5615a0206caaa19e4d362544d527e2e28c61ccee..61aca79418a6c8d0d8ca2ee153511a68181a7318 100644
--- a/arch/arm/include/asm/arch-at91/at91_pit.h
+++ b/arch/arm/include/asm/arch-at91/at91_pit.h
@@ -25,7 +25,7 @@ typedef struct at91_pit {
 
 #define		AT91_PIT_MR_IEN		0x02000000
 #define		AT91_PIT_MR_EN		0x01000000
-#define		AT91_PIT_MR_PIV_MASK	(x & 0x000fffff)
+#define		AT91_PIT_MR_PIV_MASK(x)	(x & 0x000fffff)
 #define		AT91_PIT_MR_PIV(x)	(x & AT91_PIT_MR_PIV_MASK)
 
 #ifdef CONFIG_AT91_LEGACY
diff --git a/arch/arm/include/asm/arch-at91/at91_rtt.h b/arch/arm/include/asm/arch-at91/at91_rtt.h
new file mode 100644
index 0000000000000000000000000000000000000000..e0253ef8214b545fc788d9a2a465acfcb6c376e6
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/at91_rtt.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.de
+ *
+ * Real-time Timer
+ * Based on AT91SAM9XE datasheet
+ *
+ * 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.
+ */
+
+#ifndef AT91_RTT_H
+#define AT91_RTT_H
+
+#ifndef __ASSEMBLY__
+
+typedef struct at91_rtt {
+	u32	mr;	/* Mode Register   RW 0x00008000 */
+	u32	ar;	/* Alarm Register  RW 0xFFFFFFFF */
+	u32	vr;	/* Value Register  RO 0x00000000 */
+	u32	sr;	/* Status Register RO 0x00000000 */
+} at91_rtt_t;
+
+#endif /* __ASSEMBLY__ */
+
+#define AT91_RTT_MR_RTPRES	0x0000ffff
+#define AT91_RTT_MR_ALMIEN	0x00010000
+#define AT91_RTT_RTTINCIEN	0x00020000
+#define AT91_RTT_RTTRST	0x00040000
+
+#define AT91_RTT_SR_ALMS	0x00000001
+#define AT91_RTT_SR_RTTINC	0x00000002
+
+#endif
diff --git a/arch/arm/include/asm/arch-at91/at91sam9260.h b/arch/arm/include/asm/arch-at91/at91sam9260.h
index ec0431803696fdfcc356f736c4f25b6ec7d9a131..cb34a94a3b396d4f21a3a4aa8f404c6085c2dc96 100644
--- a/arch/arm/include/asm/arch-at91/at91sam9260.h
+++ b/arch/arm/include/asm/arch-at91/at91sam9260.h
@@ -59,7 +59,15 @@
 #define AT91_RTT_BASE		0xfffffd20
 #define AT91_PIT_BASE		0xfffffd30
 #define AT91_WDT_BASE		0xfffffd40
-#define AT91_GPR_BASE		0xfffffd50
+/*
+ * The AT91SAM9XE has the GPBRs at a different address than
+ * the AT91SAM9260/9G20.
+ */
+#ifdef CONFIG_AT91SAM9XE
+# define AT91_GPR_BASE		0xfffffd60
+#else
+# define AT91_GPR_BASE		0xfffffd50
+#endif
 
 #ifdef CONFIG_AT91_LEGACY
 
@@ -140,10 +148,12 @@
 /*
  * Cpu Name
  */
-#if defined(CONFIG_AT91SAM9260)
-#define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9260"
+#if defined(CONFIG_AT91SAM9XE)
+# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9XE"
+#elif defined(CONFIG_AT91SAM9260)
+# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9260"
 #elif defined(CONFIG_AT91SAM9G20)
-#define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9G20"
+# define CONFIG_SYS_AT91_CPU_NAME	"AT91SAM9G20"
 #endif
 
 #endif
diff --git a/arch/arm/include/asm/arch-at91/clk.h b/arch/arm/include/asm/arch-at91/clk.h
index f642dd99585f4248299c3d3ebfbbe41727d2a34f..457e6c9b2b57ed202a4b9634092d30c1f704f3ae 100644
--- a/arch/arm/include/asm/arch-at91/clk.h
+++ b/arch/arm/include/asm/arch-at91/clk.h
@@ -59,5 +59,10 @@ static inline unsigned long get_twi_clk_rate(unsigned int dev_id)
 	return get_mck_clk_rate();
 }
 
+static inline unsigned long get_mci_clk_rate(void)
+{
+	return get_mck_clk_rate();
+}
+
 int at91_clock_init(unsigned long main_clock);
 #endif /* __ASM_ARM_ARCH_CLK_H__ */
diff --git a/arch/arm/include/asm/arch-at91/hardware.h b/arch/arm/include/asm/arch-at91/hardware.h
index 4ddb3155d7c45e9fc23fa86767d1676906ab7f69..9f732a738e2a4dfcbae3a73cbdadb7954ae8742f 100644
--- a/arch/arm/include/asm/arch-at91/hardware.h
+++ b/arch/arm/include/asm/arch-at91/hardware.h
@@ -20,6 +20,7 @@
 #include <asm/arch-at91/at91rm9200.h>
 #elif defined(CONFIG_AT91SAM9260) || defined(CONFIG_AT91SAM9G20)
 #include <asm/arch/at91sam9260.h>
+#define AT91_BASE_MCI	AT91SAM9260_BASE_MCI
 #define AT91_BASE_SPI	AT91SAM9260_BASE_SPI0
 #define AT91_ID_UHP	AT91SAM9260_ID_UHP
 #define AT91_PMC_UHP	AT91SAM926x_PMC_UHP
diff --git a/board/esd/meesc/meesc.c b/board/esd/meesc/meesc.c
index 694bd743588fa320aad3e5a25adf6044e07a186d..41fa3e1567a07f741a54f9c65daafcdd64b23059 100644
--- a/board/esd/meesc/meesc.c
+++ b/board/esd/meesc/meesc.c
@@ -3,7 +3,7 @@
  * Stelian Pop <stelian.pop@leadtechdesign.com>
  * Lead Tech Design <www.leadtechdesign.com>
  *
- * (C) Copyright 2009
+ * (C) Copyright 2009-2010
  * Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
  * esd electronic system design gmbh <www.esd.eu>
  *
@@ -28,13 +28,13 @@
 
 #include <common.h>
 #include <asm/arch/at91sam9263.h>
-#include <asm/arch/at91sam9_matrix.h>
 #include <asm/arch/at91sam9_smc.h>
 #include <asm/arch/at91_common.h>
 #include <asm/arch/at91_pmc.h>
 #include <asm/arch/at91_rstc.h>
+#include <asm/arch/at91_matrix.h>
+#include <asm/arch/at91_pio.h>
 #include <asm/arch/clk.h>
-#include <asm/arch/gpio.h>
 #include <asm/arch/hardware.h>
 #include <asm/arch/io.h>
 #include <netdev.h>
@@ -52,10 +52,10 @@ int get_hw_rev(void)
 	if (hw_rev >= 0)
 		return hw_rev;
 
-	hw_rev = at91_get_gpio_value(AT91_PIN_PB19);
-	hw_rev |= at91_get_gpio_value(AT91_PIN_PB20) << 1;
-	hw_rev |= at91_get_gpio_value(AT91_PIN_PB21) << 2;
-	hw_rev |= at91_get_gpio_value(AT91_PIN_PB22) << 3;
+	hw_rev = at91_get_pio_value(AT91_PIO_PORTB, 19);
+	hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 20) << 1;
+	hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 21) << 2;
+	hw_rev |= at91_get_pio_value(AT91_PIO_PORTB, 22) << 3;
 
 	if (hw_rev == 15)
 		hw_rev = 0;
@@ -67,44 +67,44 @@ int get_hw_rev(void)
 static void meesc_nand_hw_init(void)
 {
 	unsigned long csa;
+	at91_smc_t 	*smc 	= (at91_smc_t *) AT91_SMC0_BASE;
+	at91_matrix_t 	*matrix = (at91_matrix_t *) AT91_MATRIX_BASE;
 
 	/* Enable CS3 */
-	csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
-	at91_sys_write(AT91_MATRIX_EBI0CSA,
-		csa | AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA);
+	csa = readl(&matrix->csa[0]) | AT91_MATRIX_CSA_EBI_CS3A;
+	writel(csa, &matrix->csa[0]);
 
 	/* Configure SMC CS3 for NAND/SmartMedia */
-	at91_sys_write(AT91_SMC_SETUP(3),
-		AT91_SMC_NWESETUP_(1) | AT91_SMC_NCS_WRSETUP_(0) |
-		AT91_SMC_NRDSETUP_(1) | AT91_SMC_NCS_RDSETUP_(0));
-	at91_sys_write(AT91_SMC_PULSE(3),
-		AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3) |
-		AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
-	at91_sys_write(AT91_SMC_CYCLE(3),
-		AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
-	at91_sys_write(AT91_SMC_MODE(3),
-		AT91_SMC_READMODE | AT91_SMC_WRITEMODE |
-		AT91_SMC_EXNWMODE_DISABLE |
-#ifdef CONFIG_SYS_NAND_DBW_16
-		AT91_SMC_DBW_16 |
-#else /* CONFIG_SYS_NAND_DBW_8 */
-		AT91_SMC_DBW_8 |
-#endif
-		AT91_SMC_TDF_(2));
+	writel(AT91_SMC_SETUP_NWE(1) | AT91_SMC_SETUP_NCS_WR(0) |
+		AT91_SMC_SETUP_NRD(1) | AT91_SMC_SETUP_NCS_RD(0),
+		&smc->cs[3].setup);
+
+	writel(AT91_SMC_PULSE_NWE(3) | AT91_SMC_PULSE_NCS_WR(3) |
+		AT91_SMC_PULSE_NRD(3) | AT91_SMC_PULSE_NCS_RD(3),
+		&smc->cs[3].pulse);
+
+	writel(AT91_SMC_CYCLE_NWE(5) | AT91_SMC_CYCLE_NRD(5),
+		&smc->cs[3].cycle);
+	writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_WM_NWE |
+		AT91_SMC_MODE_EXNW_DISABLE |
+		AT91_SMC_MODE_DBW_8 |
+		AT91_SMC_MODE_TDF_CYCLE(2),
+		&smc->cs[3].mode);
 
 	/* Configure RDY/BSY */
-	at91_set_gpio_input(CONFIG_SYS_NAND_READY_PIN, 1);
+	at91_set_pio_input(CONFIG_SYS_NAND_READY_PIN, 1);
 
 	/* Enable NandFlash */
-	at91_set_gpio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
+	at91_set_pio_output(CONFIG_SYS_NAND_ENABLE_PIN, 1);
 }
 #endif /* CONFIG_CMD_NAND */
 
 #ifdef CONFIG_MACB
 static void meesc_macb_hw_init(void)
 {
+	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
 	/* Enable clock */
-	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9263_ID_EMAC);
+	writel(1 << AT91SAM9263_ID_EMAC, &pmc->pcer);
 	at91_macb_hw_init();
 }
 #endif
@@ -117,26 +117,27 @@ static void meesc_macb_hw_init(void)
  */
 static void meesc_ethercat_hw_init(void)
 {
+	at91_smc_t 	*smc1 	= (at91_smc_t *) AT91_SMC1_BASE;
+
 	/* Configure SMC EBI1_CS0 for EtherCAT */
-	at91_sys_write(AT91_SMC1_SETUP(0),
-		AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0) |
-		AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
-	at91_sys_write(AT91_SMC1_PULSE(0),
-		AT91_SMC_NWEPULSE_(4) | AT91_SMC_NCS_WRPULSE_(9) |
-		AT91_SMC_NRDPULSE_(4) | AT91_SMC_NCS_RDPULSE_(9));
-	at91_sys_write(AT91_SMC1_CYCLE(0),
-		AT91_SMC_NWECYCLE_(10) | AT91_SMC_NRDCYCLE_(5));
+	writel(AT91_SMC_SETUP_NWE(0) | AT91_SMC_SETUP_NCS_WR(0) |
+		AT91_SMC_SETUP_NRD(0) | AT91_SMC_SETUP_NCS_RD(0),
+		&smc1->cs[0].setup);
+	writel(AT91_SMC_PULSE_NWE(4) | AT91_SMC_PULSE_NCS_WR(9) |
+		AT91_SMC_PULSE_NRD(5) | AT91_SMC_PULSE_NCS_RD(9),
+		&smc1->cs[0].pulse);
+	writel(AT91_SMC_CYCLE_NWE(10) | AT91_SMC_CYCLE_NRD(6),
+		&smc1->cs[0].cycle);
 	/*
 	 * Configure behavior at external wait signal, byte-select mode, 16 bit
 	 * data bus width, none data float wait states and TDF optimization
 	 */
-	at91_sys_write(AT91_SMC1_MODE(0),
-		AT91_SMC_READMODE | AT91_SMC_EXNWMODE_READY |
-		AT91_SMC_BAT_SELECT | AT91_SMC_DBW_16 | AT91_SMC_TDF_(0) |
-		AT91_SMC_TDFMODE);
+	writel(AT91_SMC_MODE_RM_NRD | AT91_SMC_MODE_EXNW_READY |
+		AT91_SMC_MODE_DBW_16 | AT91_SMC_MODE_TDF_CYCLE(0) |
+		AT91_SMC_MODE_TDF, &smc1->cs[0].mode);
 
 	/* Configure RDY/BSY */
-	at91_set_B_periph(AT91_PIN_PE20, 0);	/* EBI1_NWAIT */
+	at91_set_b_periph(AT91_PIO_PORTE, 20, 0);	/* EBI1_NWAIT */
 }
 
 int dram_init(void)
@@ -150,7 +151,7 @@ int board_eth_init(bd_t *bis)
 {
 	int rc = 0;
 #ifdef CONFIG_MACB
-	rc = macb_eth_initialize(0, (void *)AT91SAM9263_BASE_EMAC, 0x00);
+	rc = macb_eth_initialize(0, (void *)AT91_EMAC_BASE, 0x00);
 #endif
 	return rc;
 }
@@ -175,7 +176,7 @@ int checkboard(void)
 		gd->bd->bi_arch_number = MACH_TYPE_ETHERCAN2;
 		puts("Board: EtherCAN/2 Gateway");
 		/* switch on LED1D */
-		at91_set_gpio_output(AT91_PIN_PB12, 1);
+		at91_set_pio_output(AT91_PIO_PORTB, 12, 1);
 		break;
 	default:
 		/* assume, no ET1100 present, arch number of EtherCAN/2-Board */
@@ -222,8 +223,9 @@ u32 get_board_rev(void)
 #ifdef CONFIG_MISC_INIT_R
 int misc_init_r(void)
 {
-	char *str;
-	char buf[32];
+	char		*str;
+	char		buf[32];
+	at91_pmc_t	*pmc = (at91_pmc_t *) AT91_PMC_BASE;
 
 	/*
 	 * Normally the processor clock has a divisor of 2.
@@ -231,10 +233,9 @@ int misc_init_r(void)
 	 * Check the user has set environment mdiv to 4 to change the divisor.
 	 */
 	if ((str = getenv("mdiv")) && (strcmp(str, "4") == 0)) {
-		at91_sys_write(AT91_PMC_MCKR,
-			(at91_sys_read(AT91_PMC_MCKR) & ~AT91_PMC_MDIV) |
-			AT91SAM9_PMC_MDIV_4);
-		at91_clock_init(0);
+		writel((readl(&pmc->mckr) & ~AT91_PMC_MDIV) |
+			AT91SAM9_PMC_MDIV_4, &pmc->mckr);
+		at91_clock_init(CONFIG_SYS_AT91_MAIN_CLOCK);
 		serial_setbrg();
 		/* Notify the user that the clock is not default */
 		printf("Setting master clock to %s MHz\n",
@@ -247,10 +248,14 @@ int misc_init_r(void)
 
 int board_init(void)
 {
+	at91_pmc_t	*pmc	= (at91_pmc_t *) AT91_PMC_BASE;
+
 	/* Peripheral Clock Enable Register */
-	at91_sys_write(AT91_PMC_PCER,	1 << AT91SAM9263_ID_PIOA |
-					1 << AT91SAM9263_ID_PIOB |
-					1 << AT91SAM9263_ID_PIOCDE);
+	writel(1 << AT91SAM9263_ID_PIOA |
+		1 << AT91SAM9263_ID_PIOB |
+		1 << AT91SAM9263_ID_PIOCDE |
+		1 << AT91SAM9263_ID_UHP,
+		&pmc->pcer);
 
 	/* initialize ET1100 Controller */
 	meesc_ethercat_hw_init();
@@ -270,6 +275,9 @@ int board_init(void)
 #endif
 #ifdef CONFIG_AT91_CAN
 	at91_can_hw_init();
+#endif
+#ifdef CONFIG_USB_OHCI_NEW
+	at91_uhp_hw_init();
 #endif
 	return 0;
 }
diff --git a/board/eukrea/cpuat91/cpuat91.c b/board/eukrea/cpuat91/cpuat91.c
index 0017962d4200740d420e6cc86f70f5e785aab449..cd4d42c6b79791835e8927a0b780703343adfa23 100644
--- a/board/eukrea/cpuat91/cpuat91.c
+++ b/board/eukrea/cpuat91/cpuat91.c
@@ -1,5 +1,5 @@
 /*
- * (C) Copyright 2006 Eukrea Electromatique <www.eukrea.com>
+ * (C) Copyright 2006-2010 Eukrea Electromatique <www.eukrea.com>
  * Eric Benard <eric@eukrea.com>
  * based on at91rm9200dk.c which is :
  * (C) Copyright 2002
@@ -27,13 +27,11 @@
 
 #include <common.h>
 #include <netdev.h>
-#include <asm/arch/AT91RM9200.h>
-#include <asm/io.h>
 
-#if defined(CONFIG_DRIVER_ETHER)
-#include <at91rm9200_net.h>
-#include <ks8721.h>
-#endif
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/at91_pio.h>
+#include <asm/arch/at91_pmc.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -61,31 +59,7 @@ int dram_init(void)
 	return 0;
 }
 
-#if defined(CONFIG_DRIVER_ETHER)
-#if defined(CONFIG_CMD_NET)
-
-/*
- * Name:
- *	at91rm9200_GetPhyInterface
- * Description:
- *	Initialise the interface functions to the PHY
- * Arguments:
- *	None
- * Return value:
- *	None
- */
-void at91rm9200_GetPhyInterface(AT91PS_PhyOps p_phyops)
-{
-	p_phyops->Init = ks8721_initphy;
-	p_phyops->IsPhyConnected = ks8721_isphyconnected;
-	p_phyops->GetLinkSpeed = ks8721_getlinkspeed;
-	p_phyops->AutoNegotiate = ks8721_autonegotiate;
-}
-
-#endif	/* CONFIG_CMD_NET */
-#endif	/* CONFIG_DRIVER_ETHER */
 #ifdef CONFIG_DRIVER_AT91EMAC
-
 int board_eth_init(bd_t *bis)
 {
 	int rc = 0;
@@ -93,3 +67,20 @@ int board_eth_init(bd_t *bis)
 	return rc;
 }
 #endif
+
+#ifdef CONFIG_SOFT_I2C
+void i2c_init_board(void)
+{
+	u32 pin;
+	at91_pmc_t *pmc = (at91_pmc_t *) AT91_PMC_BASE;
+	at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE;
+
+	writel(1 << AT91_ID_PIOA, &pmc->pcer);
+	pin = AT91_PMX_AA_TWD | AT91_PMX_AA_TWCK;
+	writel(pin, &pio->pioa.idr);
+	writel(pin, &pio->pioa.pudr);
+	writel(pin, &pio->pioa.per);
+	writel(pin, &pio->pioa.oer);
+	writel(pin, &pio->pioa.sodr);
+}
+#endif
diff --git a/doc/README.atmel_mci b/doc/README.atmel_mci
new file mode 100644
index 0000000000000000000000000000000000000000..18b1bdf7e5df58217bf52d648232e145cce8ea25
--- /dev/null
+++ b/doc/README.atmel_mci
@@ -0,0 +1,86 @@
+How to use SD/MMC cards with Atmel SoCs having MCI hardware
+-----------------------------------------------------------
+2010-08-16 Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
+
+This is a new approach to use Atmel MCI hardware with the
+general MMC framework. Therefore it benefits from that
+framework's abilities to handle SDHC Cards and the ability
+to write blocks.
+
+- AT91SAM9XE512 (tested, will definitely work with XE128 and XE256)
+- AT91SAM9260 (not tested, but MCI is to AT91SAM9XE)
+- AT91SAM9G20 (not tested, should work)
+
+It should work with all other ATMEL devices that have MCI,
+including AVR32.
+
+The generic driver does NOT assign port pins to the MCI block
+nor does it start the MCI clock. This has to be handled in a
+board/SoC specific manner before the driver is initialized:
+
+example: this is added to at91sam9260_devices.c:
+
+#if defined(CONFIG_ATMEL_MCI) || defined(CONFIG_GENERIC_ATMEL_MCI)
+void at91_mci_hw_init(void)
+{
+	at91_set_a_periph(AT91_PIO_PORTA, 8, PUP);	/* MCCK */
+#if defined(CONFIG_ATMEL_MCI_PORTB)
+	at91_set_b_periph(AT91_PIO_PORTA, 1, PUP);	/* MCCDB */
+	at91_set_b_periph(AT91_PIO_PORTA, 0, PUP);	/* MCDB0 */
+	at91_set_b_periph(AT91_PIO_PORTA, 5, PUP);	/* MCDB1 */
+	at91_set_b_periph(AT91_PIO_PORTA, 4, PUP);	/* MCDB2 */
+	at91_set_b_periph(AT91_PIO_PORTA, 3, PUP);	/* MCDB3 */
+#else
+	at91_set_a_periph(AT91_PIO_PORTA, 7, PUP);	/* MCCDA */
+	at91_set_a_periph(AT91_PIO_PORTA, 6, PUP);	/* MCDA0 */
+	at91_set_a_periph(AT91_PIO_PORTA, 9, PUP);	/* MCDA1 */
+	at91_set_a_periph(AT91_PIO_PORTA, 10, PUP);	/* MCDA2 */
+	at91_set_a_periph(AT91_PIO_PORTA, 11, PUP);	/* MCDA3 */
+#endif
+}
+#endif
+
+the board specific file need added:
+...
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+# include <mmc.h>
+#endif
+...
+#ifdef CONFIG_GENERIC_ATMEL_MCI
+/* this is a weak define that we are overriding */
+int board_mmc_init(bd_t *bd)
+{
+	/* Enable clock */
+	at91_sys_write(AT91_PMC_PCER, 1 << AT91SAM9260_ID_MCI);
+	at91_mci_hw_init();
+
+	/* This calls the atmel_mci_init in gen_atmel_mci.c */
+	return atmel_mci_init((void *)AT91_BASE_MCI);
+}
+
+/* this is a weak define that we are overriding */
+int board_mmc_getcd(u8 *cd, struct mmc *mmc)
+{
+	/*
+	 * the only currently existing use of this function
+	 * (fsl_esdhc.c) suggests this function must return
+	 * *cs = TRUE if a card is NOT detected -> in most
+	 * cases the value of the pin when the detect switch
+	 * closes to GND
+	 */
+	*cd = at91_get_gpio_value (CONFIG_SYS_MMC_CD_PIN) ? 1 : 0;
+	return 0;
+}
+
+#endif
+
+and the board definition files needs:
+
+/* SD/MMC card */
+#define CONFIG_MMC			1
+#define CONFIG_GENERIC_MMC		1
+#define CONFIG_GENERIC_ATMEL_MCI	1
+#define CONFIG_ATMEL_MCI_PORTB		1	/* Atmel XE-EK uses port B */
+#define CONFIG_SYS_MMC_CD_PIN		AT91_PIN_PC9
+#define CONFIG_CMD_MMC			1
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 8dfd8a32ba63c8da34200de1d9cbb02d2c8bfaa3..6603d74294be073511758ae51249cda143af58c8 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -25,12 +25,13 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libmmc.a
 
-COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_ATMEL_MCI) += atmel_mci.o
 COBJS-$(CONFIG_BFIN_SDH) += bfin_sdh.o
-COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
+COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
+COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
+COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_PXA_MMC) += pxa_mmc.o
 COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
 
diff --git a/drivers/mmc/atmel_mci.h b/drivers/mmc/atmel_mci.h
index 5b4f5c99b6dea1c31a66419f479a21e2a22a3cab..823a77d91b3bc99ca2a2330483bf394956ab12ba 100644
--- a/drivers/mmc/atmel_mci.h
+++ b/drivers/mmc/atmel_mci.h
@@ -22,7 +22,45 @@
 #ifndef __CPU_AT32AP_ATMEL_MCI_H__
 #define __CPU_AT32AP_ATMEL_MCI_H__
 
-/* Atmel MultiMedia Card Interface (MCI) registers */
+#ifndef __ASSEMBLY__
+
+/*
+ * Structure for struct SoC access.
+ * Names starting with '_' are fillers.
+ */
+typedef struct atmel_mci {
+	/*	reg	Offset */
+	u32	cr;	/* 0x00 */
+	u32	mr;	/* 0x04 */
+	u32	dtor;	/* 0x08 */
+	u32	sdcr;	/* 0x0c */
+	u32	argr;	/* 0x10 */
+	u32	cmdr;	/* 0x14 */
+	u32	_18;	/* 0x18 */
+	u32	_1c;	/* 0x1c */
+	u32	rspr;	/* 0x20 */
+	u32	rspr1;	/* 0x24 */
+	u32	rspr2;	/* 0x28 */
+	u32	rspr3;	/* 0x2c */
+	u32	rdr;	/* 0x30 */
+	u32	tdr;	/* 0x34 */
+	u32	_38;	/* 0x38 */
+	u32	_3c;	/* 0x3c */
+	u32	sr;	/* 0x40 */
+	u32	ier;	/* 0x44 */
+	u32	idr;	/* 0x48 */
+	u32	imr;	/* 0x4c */
+} atmel_mci_t;
+
+#endif /* __ASSEMBLY__ */
+
+/*
+ * NOTICE: Use of registers offsets is depreciated.
+ * These defines will be removed once the old driver
+ * is taken out of commision.
+ *
+ * Atmel MultiMedia Card Interface (MCI) registers
+ */
 #define MMCI_CR					0x0000
 #define MMCI_MR					0x0004
 #define MMCI_DTOR				0x0008
@@ -192,7 +230,13 @@
 		    << MMCI_##name##_OFFSET))		\
 	 | MMCI_BF(name,value))
 
-/* Register access macros */
+/*
+ * NOTICE: Use of registers offsets is depreciated.
+ * These defines will be removed once the old driver
+ * is taken out of commision.
+ *
+ * Register access macros
+ */
 #define mmci_readl(reg)					\
 	readl((void *)MMCI_BASE + MMCI_##reg)
 #define mmci_writel(reg,value)				\
diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c
new file mode 100644
index 0000000000000000000000000000000000000000..fa4df9943a7906481b94f3d83db199b43791bbe4
--- /dev/null
+++ b/drivers/mmc/gen_atmel_mci.c
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2010
+ * Rob Emanuele <rob@emanuele.us>
+ * Reinhard Meyer, EMK Elektronik <reinhard.meyer@emk-elektronik.de>
+ *
+ * Original Driver:
+ * Copyright (C) 2004-2006 Atmel Corporation
+ *
+ * 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 <mmc.h>
+#include <part.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <asm/byteorder.h>
+#include <asm/arch/clk.h>
+#include <asm/arch/memory-map.h>
+#include "atmel_mci.h"
+
+#ifndef CONFIG_SYS_MMC_CLK_OD
+# define CONFIG_SYS_MMC_CLK_OD	150000
+#endif
+
+#define MMC_DEFAULT_BLKLEN	512
+
+#if defined(CONFIG_ATMEL_MCI_PORTB)
+# define MCI_BUS 1
+#else
+# define MCI_BUS 0
+#endif
+
+static int initialized = 0;
+
+/*
+ * Print command and status:
+ *
+ * - always when DEBUG is defined
+ * - on command errors
+ */
+static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
+{
+	printf("gen_atmel_mci: CMDR %08x (%2u) ARGR %08x (SR: %08x) %s\n",
+		cmdr, cmdr&0x3F, arg, status, msg);
+}
+
+/* Setup for MCI Clock and Block Size */
+static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
+{
+	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+	u32 bus_hz = get_mci_clk_rate();
+	u32 clkdiv = 255;
+
+	debug("mci: bus_hz is %u, setting clock %u Hz, block size %u\n",
+		bus_hz, hz, blklen);
+	if (hz > 0) {
+		/* find lowest clkdiv yielding a rate <= than requested */
+		for (clkdiv=0; clkdiv<255; clkdiv++) {
+			if ((bus_hz / (clkdiv+1) / 2) <= hz)
+				break;
+		}
+	}
+	printf("mci: setting clock %u Hz, block size %u\n",
+		(bus_hz / (clkdiv+1)) / 2, blklen);
+
+	blklen &= 0xfffc;
+	/* On some platforms RDPROOF and WRPROOF are ignored */
+	writel((MMCI_BF(CLKDIV, clkdiv)
+		 | MMCI_BF(BLKLEN, blklen)
+		 | MMCI_BIT(RDPROOF)
+		 | MMCI_BIT(WRPROOF)), &mci->mr);
+	initialized = 1;
+}
+
+/* Return the CMDR with flags for a given command and data packet */
+static u32 mci_encode_cmd(
+	struct mmc_cmd *cmd, struct mmc_data *data, u32* error_flags)
+{
+	u32 cmdr = 0;
+
+	/* Default Flags for Errors */
+	*error_flags |= (MMCI_BIT(DTOE) | MMCI_BIT(RDIRE) | MMCI_BIT(RENDE) |
+		MMCI_BIT(RINDE) | MMCI_BIT(RTOE));
+
+	/* Default Flags for the Command */
+	cmdr |= MMCI_BIT(MAXLAT);
+
+	if (data) {
+		cmdr |= MMCI_BF(TRCMD, 1);
+		if (data->blocks > 1)
+			cmdr |= MMCI_BF(TRTYP, 1);
+		if (data->flags & MMC_DATA_READ)
+			cmdr |= MMCI_BIT(TRDIR);
+	}
+
+	if (cmd->resp_type & MMC_RSP_CRC)
+		*error_flags |= MMCI_BIT(RCRCE);
+	if (cmd->resp_type & MMC_RSP_136)
+		cmdr |= MMCI_BF(RSPTYP, 2);
+	else if (cmd->resp_type & MMC_RSP_BUSY)
+		cmdr |= MMCI_BF(RSPTYP, 3);
+	else if (cmd->resp_type & MMC_RSP_PRESENT)
+		cmdr |= MMCI_BF(RSPTYP, 1);
+
+	return cmdr | MMCI_BF(CMDNB, cmd->cmdidx);
+}
+
+/* Entered into function pointer in mci_send_cmd */
+static u32 mci_data_read(atmel_mci_t *mci, u32* data, u32 error_flags)
+{
+	u32 status;
+
+	do {
+		status = readl(&mci->sr);
+		if (status & (error_flags | MMCI_BIT(OVRE)))
+			goto io_fail;
+	} while (!(status & MMCI_BIT(RXRDY)));
+
+	if (status & MMCI_BIT(RXRDY)) {
+		*data = readl(&mci->rdr);
+		status = 0;
+	}
+io_fail:
+	return status;
+}
+
+/* Entered into function pointer in mci_send_cmd */
+static u32 mci_data_write(atmel_mci_t *mci, u32* data, u32 error_flags)
+{
+	u32 status;
+
+	do {
+		status = readl(&mci->sr);
+		if (status & (error_flags | MMCI_BIT(UNRE)))
+			goto io_fail;
+	} while (!(status & MMCI_BIT(TXRDY)));
+
+	if (status & MMCI_BIT(TXRDY)) {
+		writel(*data, &mci->tdr);
+		status = 0;
+	}
+io_fail:
+	return status;
+}
+
+/*
+ * Entered into mmc structure during driver init
+ *
+ * Sends a command out on the bus and deals with the block data.
+ * Takes the mmc pointer, a command pointer, and an optional data pointer.
+ */
+static int
+mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
+{
+	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+	u32 cmdr;
+	u32 error_flags = 0;
+	u32 status;
+
+	if (!initialized) {
+		puts ("MCI not initialized!\n");
+		return COMM_ERR;
+	}
+
+	/* Figure out the transfer arguments */
+	cmdr = mci_encode_cmd(cmd, data, &error_flags);
+
+	/* Send the command */
+	writel(cmd->cmdarg, &mci->argr);
+	writel(cmdr, &mci->cmdr);
+
+#ifdef DEBUG
+	dump_cmd(cmdr, cmd->cmdarg, 0, "DEBUG");
+#endif
+
+	/* Wait for the command to complete */
+	while (!((status = readl(&mci->sr)) & MMCI_BIT(CMDRDY)));
+
+	if (status & error_flags) {
+		dump_cmd(cmdr, cmd->cmdarg, status, "Command Failed");
+		return COMM_ERR;
+	}
+
+	/* Copy the response to the response buffer */
+	if (cmd->resp_type & MMC_RSP_136) {
+		cmd->response[0] = readl(&mci->rspr);
+		cmd->response[1] = readl(&mci->rspr1);
+		cmd->response[2] = readl(&mci->rspr2);
+		cmd->response[3] = readl(&mci->rspr3);
+	} else
+		cmd->response[0] = readl(&mci->rspr);
+
+	/* transfer all of the blocks */
+	if (data) {
+		u32 word_count, block_count;
+		u32* ioptr;
+		u32 sys_blocksize, dummy, i;
+		u32 (*mci_data_op)
+			(atmel_mci_t *mci, u32* data, u32 error_flags);
+
+		if (data->flags & MMC_DATA_READ) {
+			mci_data_op = mci_data_read;
+			sys_blocksize = mmc->read_bl_len;
+			ioptr = (u32*)data->dest;
+		} else {
+			mci_data_op = mci_data_write;
+			sys_blocksize = mmc->write_bl_len;
+			ioptr = (u32*)data->src;
+		}
+
+		status = 0;
+		for (block_count = 0;
+				block_count < data->blocks && !status;
+				block_count++) {
+			word_count = 0;
+			do {
+				status = mci_data_op(mci, ioptr, error_flags);
+				word_count++;
+				ioptr++;
+			} while (!status && word_count < (data->blocksize/4));
+#ifdef DEBUG
+			if (data->flags & MMC_DATA_READ)
+			{
+				printf("Read Data:\n");
+				print_buffer(0, data->dest, 1,
+					word_count*4, 0);
+			}
+#endif
+#ifdef DEBUG
+			if (!status && word_count < (sys_blocksize / 4))
+				printf("filling rest of block...\n");
+#endif
+			/* fill the rest of a full block */
+			while (!status && word_count < (sys_blocksize / 4)) {
+				status = mci_data_op(mci, &dummy,
+					error_flags);
+				word_count++;
+			}
+			if (status) {
+				dump_cmd(cmdr, cmd->cmdarg, status,
+					"Data Transfer Failed");
+				return COMM_ERR;
+			}
+		}
+
+		/* Wait for Transfer End */
+		i = 0;
+		do {
+			status = readl(&mci->sr);
+
+			if (status & error_flags) {
+				dump_cmd(cmdr, cmd->cmdarg, status,
+					"DTIP Wait Failed");
+				return COMM_ERR;
+			}
+			i++;
+		} while ((status & MMCI_BIT(DTIP)) && i < 10000);
+		if (status & MMCI_BIT(DTIP)) {
+			dump_cmd(cmdr, cmd->cmdarg, status,
+				"XFER DTIP never unset, ignoring");
+		}
+	}
+
+	return 0;
+}
+
+/* Entered into mmc structure during driver init */
+static void mci_set_ios(struct mmc *mmc)
+{
+	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+	int busw = (mmc->bus_width == 4) ? 1 : 0;
+
+	/* Set the clock speed */
+	mci_set_mode(mmc, mmc->clock, MMC_DEFAULT_BLKLEN);
+
+	/*
+	 * set the bus width and select slot for this interface
+	 * there is no capability for multiple slots on the same interface yet
+	 * Bitfield SCDBUS needs to be expanded to 2 bits for 8-bit buses
+	 */
+	writel(MMCI_BF(SCDBUS, busw) | MMCI_BF(SCDSEL, MCI_BUS), &mci->sdcr);
+}
+
+/* Entered into mmc structure during driver init */
+static int mci_init(struct mmc *mmc)
+{
+	atmel_mci_t *mci = (atmel_mci_t *)mmc->priv;
+
+	/* Initialize controller */
+	writel(MMCI_BIT(SWRST), &mci->cr);	/* soft reset */
+	writel(MMCI_BIT(PWSDIS), &mci->cr);	/* disable power save */
+	writel(MMCI_BIT(MCIEN), &mci->cr);	/* enable mci */
+
+	/* Initial Time-outs */
+	writel(0x5f, &mci->dtor);
+	/* Disable Interrupts */
+	writel(~0UL, &mci->idr);
+
+	/* Set default clocks and blocklen */
+	mci_set_mode(mmc, CONFIG_SYS_MMC_CLK_OD, MMC_DEFAULT_BLKLEN);
+
+	return 0;
+}
+
+/*
+ * This is the only exported function
+ *
+ * Call it with the MCI register base address
+ */
+int atmel_mci_init(void *regs)
+{
+	struct mmc *mmc = malloc(sizeof(struct mmc));
+
+	if (!mmc)
+		return -1;
+	strcpy(mmc->name, "mci");
+	mmc->priv = regs;
+	mmc->send_cmd = mci_send_cmd;
+	mmc->set_ios = mci_set_ios;
+	mmc->init = mci_init;
+
+	/* need to be able to pass these in on a board by board basis */
+	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->host_caps = MMC_MODE_4BIT;
+	/*
+	 * min and max frequencies determined by
+	 * max and min of clock divider
+	 */
+	mmc->f_min = get_mci_clk_rate() / (2*256);
+	mmc->f_max = get_mci_clk_rate() / (2*1);
+
+	mmc_register(mmc);
+
+	return 0;
+}
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 772a49a9021a41d46ef6c7aaf474be7a4f70553b..98734db77f6f93cdfe015f8cdeef7bf42e638200 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -27,6 +27,7 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)librtc.a
 
+COBJS-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
 COBJS-$(CONFIG_RTC_BFIN) += bfin_rtc.o
 COBJS-y += date.o
 COBJS-$(CONFIG_RTC_DS12887) += ds12887.o
diff --git a/drivers/rtc/at91sam9_rtt.c b/drivers/rtc/at91sam9_rtt.c
new file mode 100644
index 0000000000000000000000000000000000000000..de8e30d0d7ca6969fba033ea1cc0851a30effaec
--- /dev/null
+++ b/drivers/rtc/at91sam9_rtt.c
@@ -0,0 +1,100 @@
+/*
+ * (C) Copyright 2010
+ * Reinhard Meyer, reinhard.meyer@emk-elektronik.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
+ */
+
+/*
+ * Date & Time support for the internal Real-time Timer
+ * of AT91SAM9260 and compatibles.
+ * Compatible with the LinuX rtc driver workaround:
+ * The RTT cannot be written to, but only reset.
+ * The actual time is the sum of RTT and one of
+ * the four GPBR registers.
+ *
+ * The at91sam9260 has 4 GPBR (0-3).
+ * For their typical use see at91_gpbr.h !
+ *
+ * make sure u-boot and kernel use the same GPBR !
+ */
+
+#include <common.h>
+#include <command.h>
+#include <rtc.h>
+#include <asm/errno.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/io.h>
+#include <asm/arch/at91_rtt.h>
+#include <asm/arch/at91_gpbr.h>
+
+#if defined(CONFIG_CMD_DATE)
+
+int rtc_get (struct rtc_time *tmp)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE;
+	ulong tim;
+	ulong tim2;
+	ulong off;
+
+	do {
+		tim = readl(&rtt->vr);
+		tim2 = readl(&rtt->vr);
+	} while (tim!=tim2);
+	off = readl(&gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* off==0 means time is invalid, but we ignore that */
+	to_tm (tim+off, tmp);
+	return 0;
+}
+
+int rtc_set (struct rtc_time *tmp)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE;
+	ulong tim;
+
+	tim = mktime (tmp->tm_year, tmp->tm_mon, tmp->tm_mday,
+		      tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	/* clear alarm, set prescaler to 32768, clear counter */
+	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
+	writel(~0, &rtt->ar);
+	writel(tim, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* wait for counter clear to happen, takes less than a 1/32768th second */
+	while (readl(&rtt->vr) != 0)
+		;
+	return 0;
+}
+
+void rtc_reset (void)
+{
+	at91_rtt_t *rtt = (at91_rtt_t *) AT91_RTT_BASE;
+	at91_gpbr_t *gpbr = (at91_gpbr_t *) AT91_GPR_BASE;
+
+	/* clear alarm, set prescaler to 32768, clear counter */
+	writel(32768+AT91_RTT_RTTRST, &rtt->mr);
+	writel(~0, &rtt->ar);
+	writel(0, &gpbr->reg[AT91_GPBR_INDEX_TIMEOFF]);
+	/* wait for counter clear to happen, takes less than a 1/32768th second */
+	while (readl(&rtt->vr) != 0)
+		;
+}
+
+#endif
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index 317c0b41b6fbc6636303ef3a4196a63f16fa05bc..d0de9319684650989e987c3f0bb037035c0d6715 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -43,7 +43,7 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
 	u32			csrx;
 	void			*regs;
 
-	if (cs > 3 || !spi_cs_is_valid(bus, cs))
+	if (!spi_cs_is_valid(bus, cs))
 		return NULL;
 
 	switch (bus) {
@@ -168,8 +168,17 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 	 * somewhat quirky, and it doesn't really buy us much anyway
 	 * in the context of U-Boot.
 	 */
-	if (flags & SPI_XFER_BEGIN)
+	if (flags & SPI_XFER_BEGIN) {
 		spi_cs_activate(slave);
+		/*
+		 * sometimes the RDR is not empty when we get here,
+		 * in theory that should not happen, but it DOES happen.
+		 * Read it here to be on the safe side.
+		 * That also clears the OVRES flag. Required if the
+		 * following loop exits due to OVRES!
+		 */
+		spi_readl(as, RDR);
+	}
 
 	for (len_tx = 0, len_rx = 0; len_rx < len; ) {
 		status = spi_readl(as, SR);
diff --git a/include/configs/cpuat91.h b/include/configs/cpuat91.h
index 049298cfa3635bb5072cfde93d4bc290362c8f65..9ef4523de427dbc124d1c09c5f8d9e957d7a0da4 100644
--- a/include/configs/cpuat91.h
+++ b/include/configs/cpuat91.h
@@ -1,5 +1,5 @@
 /*
- * CPUAT91 by (C) Copyright 2006 Eric Benard
+ * CPUAT91 by (C) Copyright 2006-2010 Eric Benard
  * eric@eukrea.com
  *
  * Configuration settings for the CPUAT91 board.
@@ -23,15 +23,12 @@
  * MA 02111-1307 USA
  */
 
-#ifndef __CONFIG_H
-#define __CONFIG_H
-
-#define CONFIG_AT91_LEGACY
+#ifndef _CONFIG_CPUAT91_H
+#define _CONFIG_CPUAT91_H
 
 #ifdef CONFIG_CPUAT91_RAM
 #define CONFIG_SKIP_LOWLEVEL_INIT	1
 #define CONFIG_SKIP_RELOCATE_UBOOT	1
-#define CONFIG_CPUAT91			1
 #else
 #define CONFIG_BOOTDELAY		1
 #endif
@@ -43,6 +40,7 @@
 
 #define CONFIG_ARM920T			1
 #define CONFIG_AT91RM9200		1
+#define CONFIG_CPUAT91			1
 
 #undef CONFIG_USE_IRQ
 #define USE_920T_MMU			1
@@ -89,16 +87,36 @@
 #undef CONFIG_USART0
 #undef CONFIG_USART1
 
-#define CONFIG_HARD_I2C			1
+#undef CONFIG_HARD_I2C
+#define CONFIG_SOFT_I2C			1
+#define AT91_PIN_SDA			(1<<25)
+#define AT91_PIN_SCL			(1<<26)
+
+#define CONFIG_SYS_I2C_INIT_BOARD	1
+#define	CONFIG_SYS_I2C_SPEED		50000
+#define CONFIG_SYS_I2C_SLAVE		0
+
+#define I2C_INIT	i2c_init_board();
+#define I2C_ACTIVE	writel(AT91_PMX_AA_TWD, &pio->pioa.mddr);
+#define I2C_TRISTATE	writel(AT91_PMX_AA_TWD, &pio->pioa.mder);
+#define I2C_READ	((readl(&pio->pioa.pdsr) & AT91_PMX_AA_TWD) != 0)
+#define I2C_SDA(bit)						\
+	if (bit)						\
+		writel(AT91_PMX_AA_TWD, &pio->pioa.sodr);	\
+	else							\
+		writel(AT91_PMX_AA_TWD, &pio->pioa.codr);
+#define I2C_SCL(bit)						\
+	if (bit)						\
+		writel(AT91_PMX_AA_TWCK, &pio->pioa.sodr);	\
+	else							\
+		writel(AT91_PMX_AA_TWCK, &pio->pioa.codr);
+
+#define I2C_DELAY	udelay(2500000/CONFIG_SYS_I2C_SPEED)
 
-#if defined(CONFIG_HARD_I2C)
-#define	CONFIG_SYS_I2C_SPEED			50000
-#define CONFIG_SYS_I2C_SLAVE			0
 #define CONFIG_SYS_I2C_EEPROM_ADDR		0x54
 #define CONFIG_SYS_I2C_EEPROM_ADDR_LEN		1
 #define CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW	1
 #define	CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS	10
-#endif
 
 #define CONFIG_BOOTP_BOOTFILESIZE	1
 #define CONFIG_BOOTP_BOOTPATH		1
@@ -117,10 +135,8 @@
 #undef CONFIG_CMD_LOADS
 #undef CONFIG_CMD_NFS
 
-#if defined(CONFIG_HARD_I2C)
 #define CONFIG_CMD_EEPROM		1
 #define CONFIG_CMD_I2C			1
-#endif
 
 #define CONFIG_NR_DRAM_BANKS			1
 #define PHYS_SDRAM				0x20000000
@@ -148,6 +164,7 @@
 #define PHYS_FLASH_1				0x10000000
 #define CONFIG_SYS_FLASH_BASE			PHYS_FLASH_1
 #define CONFIG_SYS_MAX_FLASH_SECT		128
+#define CONFIG_SYS_FLASH_CFI_WIDTH		FLASH_CFI_16BIT
 
 #if defined(CONFIG_CMD_USB)
 #define CONFIG_USB_OHCI_NEW			1
@@ -206,7 +223,7 @@
 	"mtdparts=physmap-flash.0:"	\
 		"128k(u-boot)ro,"	\
 		"128k(u-boot-env),"	\
-		"1408k(kernel),"	\
+		"1792k(kernel),"	\
 		"-(rootfs)"
 
 #define CONFIG_BOOTARGS 		\
@@ -221,13 +238,13 @@
 		"1001FFFF; erase 10000000 1001FFFF; cp.b 21000000 "	\
 		"10000000 ${filesize}\0"				\
 	"flui=tftp 21000000 cpuat91/uImage; protect off 10040000 "	\
-		"1019ffff; erase 10040000 1019ffff; cp.b 21000000 "	\
+		"1019ffff; erase 10040000 101fffff; cp.b 21000000 "	\
 		"10040000 ${filesize}\0"				\
 	"flrfs=tftp 21000000 cpuat91/rootfs.jffs2; protect off "	\
-		"101a0000 10ffffff; erase 101a0000 10ffffff; cp.b "	\
-		"21000000 101A0000 ${filesize}\0"			\
+		"10200000 10ffffff; erase 10200000 10ffffff; cp.b "	\
+		"21000000 10200000 ${filesize}\0"			\
 	"ramargs=setenv bootargs $(bootargs) $(mtdparts)\0"		\
 	"flashboot=run ramargs;bootm 10040000\0"			\
 	"netboot=run ramargs;tftpboot 21000000 cpuat91/uImage;"		\
 		"bootm 21000000\0"
-#endif	/* __CONFIG_H */
+#endif	/* _CONFIG_CPUAT91_H */
diff --git a/include/configs/meesc.h b/include/configs/meesc.h
index e085f4a47c53e3176d0173f1212ec75674476dfb..dbb253143998c2774d58beae0fca239ff83ee261 100644
--- a/include/configs/meesc.h
+++ b/include/configs/meesc.h
@@ -3,7 +3,7 @@
  * Stelian Pop <stelian.pop@leadtechdesign.com>
  * Lead Tech Design <www.leadtechdesign.com>
  *
- * (C) Copyright 2009
+ * (C) Copyright 2009-2010
  * Daniel Gorsulowski <daniel.gorsulowski@esd.eu>
  * esd electronic system design gmbh <www.esd.eu>
  *
@@ -31,13 +31,12 @@
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
-#define CONFIG_AT91_LEGACY
-
 /* Common stuff */
-#define CONFIG_SYS_HZ			1000	/* decrementer freq */
 #define CONFIG_MEESC			1	/* Board is esd MEESC */
 #define CONFIG_ARM926EJS		1	/* This is an ARM926EJS Core */
 #define CONFIG_AT91SAM9263		1	/* It's an AT91SAM9263 SoC */
+#define CONFIG_SYS_AT91_MAIN_CLOCK	16000000/* 16.0 MHz crystal */
+#define CONFIG_SYS_HZ			1000	/* decrementer freq */
 #define CONFIG_DISPLAY_BOARDINFO	1
 #define CONFIG_DISPLAY_CPUINFO		1	/* display cpu info and speed */
 #define CONFIG_PREBOOT				/* enable preboot variable */
@@ -85,11 +84,11 @@
 #undef CONFIG_CMD_FPGA
 #undef CONFIG_CMD_LOADS
 #undef CONFIG_CMD_IMLS
-#undef CONFIG_CMD_USB
 
 #define CONFIG_CMD_PING				1
 #define CONFIG_CMD_DHCP				1
 #define CONFIG_CMD_NAND				1
+#define CONFIG_CMD_USB				1
 
 /* LED */
 #define CONFIG_AT91_LED				1
@@ -121,9 +120,9 @@
 #define CONFIG_SYS_NAND_MASK_ALE		(1 << 21)
 /* our CLE is AD22 */
 #define CONFIG_SYS_NAND_MASK_CLE		(1 << 22)
-#define CONFIG_SYS_NAND_ENABLE_PIN		AT91_PIN_PD15
-#define CONFIG_SYS_NAND_READY_PIN		AT91_PIN_PA22
-
+#define CONFIG_SYS_NAND_ENABLE_PIN		AT91_PIO_PORTD, 15
+#define CONFIG_SYS_NAND_READY_PIN		AT91_PIO_PORTA, 22
+#define CONFIG_SYS_64BIT_VSPRINTF		/* needed for nand_util.c */
 #endif
 
 /* Ethernet */
@@ -133,6 +132,17 @@
 #define CONFIG_NET_RETRY_COUNT			20
 #undef CONFIG_RESET_PHY_R
 
+/* USB */
+#define CONFIG_USB_ATMEL
+#define CONFIG_USB_OHCI_NEW			1
+#define CONFIG_DOS_PARTITION			1
+#define CONFIG_SYS_USB_OHCI_CPU_INIT		1
+#define CONFIG_SYS_USB_OHCI_REGS_BASE		0x00a00000
+#define CONFIG_SYS_USB_OHCI_SLOT_NAME		"at91sam9263"
+#define CONFIG_SYS_USB_OHCI_MAX_ROOT_PORTS	2
+#define CONFIG_USB_STORAGE			1
+#define CONFIG_CMD_FAT				1
+
 #define CONFIG_SYS_LOAD_ADDR			0x22000000 /* load address */
 
 #define CONFIG_SYS_MEMTEST_START		PHYS_SDRAM
diff --git a/include/configs/otc570.h b/include/configs/otc570.h
index fb0f576f45608e2d8879c989ef07b4e5f3095650..4a1cedec0fe8dfdb9f46a74a1faafd3af42ca240 100644
--- a/include/configs/otc570.h
+++ b/include/configs/otc570.h
@@ -35,6 +35,7 @@
 #define CONFIG_OTC570			1	/* Board is esd OTC570 */
 #define CONFIG_ARM926EJS		1	/* This is an ARM926EJS Core */
 #define CONFIG_AT91SAM9263		1	/* It's an AT91SAM9263 SoC */
+#define CONFIG_SYS_AT91_MAIN_CLOCK	16000000/* 16.0 MHz crystal */
 #define CONFIG_SYS_HZ			1000	/* decrementer freq */
 #define CONFIG_DISPLAY_BOARDINFO	1
 #define CONFIG_DISPLAY_CPUINFO		1	/* display cpu info and speed */
diff --git a/include/mmc.h b/include/mmc.h
index fcb237e81e4788c03408ceeb7d1fc94fcfc9b006..9f94f423fbf55a4536c0e736409e43ecc38cbd68 100644
--- a/include/mmc.h
+++ b/include/mmc.h
@@ -179,6 +179,16 @@ struct mmc_cid {
 	char pnm[7];
 };
 
+/*
+ * WARNING!
+ *
+ * This structure is used by atmel_mci.c only.
+ * It works for the AVR32 architecture but NOT
+ * for ARM/AT91 architectures.
+ * Its use is highly depreciated.
+ * After the atmel_mci.c driver for AVR32 has
+ * been replaced this structure will be removed.
+ */
 struct mmc_csd
 {
 	u8	csd_structure:2,
@@ -275,7 +285,10 @@ int mmc_set_dev(int dev_num);
 void print_mmc_devices(char separator);
 int board_mmc_getcd(u8 *cd, struct mmc *mmc);
 
-#ifndef CONFIG_GENERIC_MMC
+#ifdef CONFIG_GENERIC_MMC
+int atmel_mci_init(void *regs);
+#else
 int mmc_legacy_init(int verbose);
 #endif
+
 #endif /* _MMC_H_ */