* Patch by Gary Jennejohn, 01 Oct 2004:
  - add support for CMC PU2 board
  - add support for I2C on at91rm9200

* Patch by Gary Jennejohn, 28 Sep 2004:
  fix baudrate handling on at91rm9200
diff --git a/board/cmc_pu2/Makefile b/board/cmc_pu2/Makefile
new file mode 100644
index 0000000..f94bd99
--- /dev/null
+++ b/board/cmc_pu2/Makefile
@@ -0,0 +1,47 @@
+#
+# (C) Copyright 2003
+# Wolfgang Denk, DENX Software Engineering, wd@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	= lib$(BOARD).a
+
+OBJS	:= at91rm9200dk.o at45.o dm9161.o flash.o
+SOBJS	:= memsetup.o
+
+$(LIB):	$(OBJS) $(SOBJS)
+	$(AR) crv $@ $(OBJS) $(SOBJS)
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+.depend:	Makefile $(SOBJS:.o=.S) $(OBJS:.o=.c)
+		$(CC) -M $(CPPFLAGS) $(SOBJS:.o=.S) $(OBJS:.o=.c) > $@
+
+-include .depend
+
+#########################################################################
diff --git a/board/cmc_pu2/at45.c b/board/cmc_pu2/at45.c
new file mode 100644
index 0000000..3c00132
--- /dev/null
+++ b/board/cmc_pu2/at45.c
@@ -0,0 +1,621 @@
+/* Driver for ATMEL DataFlash support
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <config.h>
+#include <common.h>
+#include <asm/hardware.h>
+
+#ifdef CONFIG_HAS_DATAFLASH
+#include <dataflash.h>
+
+#define AT91C_SPI_CLK	10000000	/* Max Value = 10MHz to be compliant to
+the Continuous Array Read function */
+
+/* AC Characteristics */
+/* DLYBS = tCSS = 250ns min and DLYBCT = tCSH = 250ns */
+#define DATAFLASH_TCSS	(0xC << 16)
+#define DATAFLASH_TCHS	(0x1 << 24)
+
+#define AT91C_TIMEOUT_WRDY			200000
+#define AT91C_SPI_PCS0_SERIAL_DATAFLASH		0xE     /* Chip Select 0 : NPCS0 %1110 */
+#define AT91C_SPI_PCS3_DATAFLASH_CARD		0x7     /* Chip Select 3 : NPCS3 %0111 */
+
+void AT91F_SpiInit(void) {
+
+/*-------------------------------------------------------------------*/
+/*	SPI DataFlash Init								*/
+/*-------------------------------------------------------------------*/
+	/* Configure PIOs */
+	AT91C_BASE_PIOA->PIO_ASR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
+				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
+	AT91C_BASE_PIOA->PIO_PDR = AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI | AT91C_PA5_NPCS2 |
+				   AT91C_PA6_NPCS3 | AT91C_PA0_MISO | AT91C_PA2_SPCK;
+	/* Enable CLock */
+	AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
+
+	/* Reset the SPI */
+	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
+
+	/* Configure SPI in Master Mode with No CS selected !!! */
+	AT91C_BASE_SPI->SPI_MR = AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
+
+	/* Configure CS0 and CS3 */
+	*(AT91C_SPI_CSR + 0) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT &
+	DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
+
+	*(AT91C_SPI_CSR + 3) = AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) | (AT91C_SPI_DLYBCT &
+	DATAFLASH_TCHS) | ((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
+
+}
+
+void AT91F_SpiEnable(int cs) {
+	switch(cs) {
+	case 0:	/* Configure SPI CS0 for Serial DataFlash AT45DBxx */
+		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
+		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) & AT91C_SPI_PCS);
+		break;
+	case 3:	/* Configure SPI CS3 for Serial DataFlash Card */
+		/* Set up PIO SDC_TYPE to switch on DataFlash Card and not MMC/SDCard */
+		AT91C_BASE_PIOB->PIO_PER = AT91C_PIO_PB7;	/* Set in PIO mode */
+		AT91C_BASE_PIOB->PIO_OER = AT91C_PIO_PB7;	/* Configure in output */
+		/* Clear Output */
+		AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
+		/* Configure PCS */
+		AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
+		AT91C_BASE_SPI->SPI_MR |= ((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
+		break;
+	}
+
+	/* SPI_Enable */
+	AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN;
+}
+
+/*----------------------------------------------------------------------------*/
+/* \fn    AT91F_SpiWrite						      */
+/* \brief Set the PDC registers for a transfert				      */
+/*----------------------------------------------------------------------------*/
+unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
+{
+	unsigned int timeout;
+
+	pDesc->state = BUSY;
+
+	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
+
+	/* Initialize the Transmit and Receive Pointer */
+	AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
+	AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
+
+	/* Intialize the Transmit and Receive Counters */
+	AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
+	AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
+
+	if ( pDesc->tx_data_size != 0 ) {
+		/* Initialize the Next Transmit and Next Receive Pointer */
+		AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
+		AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
+
+		/* Intialize the Next Transmit and Next Receive Counters */
+		AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
+		AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
+	}
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked();
+	timeout = 0;
+
+	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
+	while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) && ((timeout = get_timer_masked() ) < CFG_SPI_WRITE_TOUT));
+	AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
+	pDesc->state = IDLE;
+
+	if (timeout >= CFG_SPI_WRITE_TOUT){
+		printf("Error Timeout\n\r");
+		return DATAFLASH_ERROR;
+	}
+
+	return DATAFLASH_OK;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashSendCommand					*/
+/* \brief Generic function to send a command to the dataflash		*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashSendCommand(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char OpCode,
+	unsigned int CmdSize,
+	unsigned int DataflashAddress)
+{
+    unsigned int adr;
+
+	if ( (pDataFlash->pDataFlashDesc->state) != IDLE)
+		return DATAFLASH_BUSY;
+
+	/* process the address to obtain page address and byte address */
+	adr = ((DataflashAddress / (pDataFlash->pDevice->pages_size)) << pDataFlash->pDevice->page_offset) + (DataflashAddress % (pDataFlash->pDevice->pages_size));
+
+	/* fill the  command  buffer */
+	pDataFlash->pDataFlashDesc->command[0] = OpCode;
+	if (pDataFlash->pDevice->pages_number >= 16384) {
+		pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x0F000000) >> 24);
+		pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x00FF0000) >> 16);
+		pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((adr & 0x0000FF00) >> 8);
+		pDataFlash->pDataFlashDesc->command[4] = (unsigned char)(adr & 0x000000FF);
+	} else {
+		pDataFlash->pDataFlashDesc->command[1] = (unsigned char)((adr & 0x00FF0000) >> 16);
+		pDataFlash->pDataFlashDesc->command[2] = (unsigned char)((adr & 0x0000FF00) >> 8);
+		pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(adr & 0x000000FF) ;
+		pDataFlash->pDataFlashDesc->command[4] = 0;
+	}
+	pDataFlash->pDataFlashDesc->command[5] = 0;
+	pDataFlash->pDataFlashDesc->command[6] = 0;
+	pDataFlash->pDataFlashDesc->command[7] = 0;
+
+	/* Initialize the SpiData structure for the spi write fuction */
+	pDataFlash->pDataFlashDesc->tx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->tx_cmd_size =  CmdSize ;
+	pDataFlash->pDataFlashDesc->rx_cmd_pt   =  pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->rx_cmd_size =  CmdSize ;
+
+	/* send the command and read the data */
+	return AT91F_SpiWrite (pDataFlash->pDataFlashDesc);
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashGetStatus					*/
+/* \brief Read the status register of the dataflash			*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashGetStatus(AT91PS_DataflashDesc pDesc)
+{
+	AT91S_DataFlashStatus status;
+
+	/* if a transfert is in progress ==> return 0 */
+	if( (pDesc->state) != IDLE)
+		return DATAFLASH_BUSY;
+
+	/* first send the read status command (D7H) */
+	pDesc->command[0] = DB_STATUS;
+	pDesc->command[1] = 0;
+
+	pDesc->DataFlash_state  = GET_STATUS;
+	pDesc->tx_data_size 	= 0 ;	/* Transmit the command and receive response */
+	pDesc->tx_cmd_pt 		= pDesc->command ;
+	pDesc->rx_cmd_pt 		= pDesc->command ;
+	pDesc->rx_cmd_size 		= 2 ;
+	pDesc->tx_cmd_size 		= 2 ;
+	status = AT91F_SpiWrite (pDesc);
+
+	pDesc->DataFlash_state = *( (unsigned char *) (pDesc->rx_cmd_pt) +1);
+
+	return status;
+}
+
+
+/*----------------------------------------------------------------------*/
+/* \fn    AT91F_DataFlashWaitReady					*/
+/* \brief wait for dataflash ready (bit7 of the status register == 1)	*/
+/*----------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWaitReady(AT91PS_DataflashDesc pDataFlashDesc, unsigned int timeout)
+{
+	pDataFlashDesc->DataFlash_state = IDLE;
+
+	do {
+		AT91F_DataFlashGetStatus(pDataFlashDesc);
+		timeout--;
+	} while( ((pDataFlashDesc->DataFlash_state & 0x80) != 0x80) && (timeout > 0) );
+
+	if((pDataFlashDesc->DataFlash_state & 0x80) != 0x80)
+		return DATAFLASH_ERROR;
+
+	return DATAFLASH_OK;
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashContinuousRead 				*/
+/* Object              : Continuous stream Read 				*/
+/* Input Parameters    : DataFlash Service					*/
+/*						: <src> = dataflash address	*/
+/*                     : <*dataBuffer> = data buffer pointer			*/
+/*                     : <sizeToRead> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashContinuousRead (
+	AT91PS_DataFlash pDataFlash,
+	int src,
+	unsigned char *dataBuffer,
+	int sizeToRead )
+{
+	AT91S_DataFlashStatus status;
+	/* Test the size to read in the device */
+	if ( (src + sizeToRead) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
+		return DATAFLASH_MEMORY_OVERFLOW;
+
+	pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer;
+	pDataFlash->pDataFlashDesc->rx_data_size = sizeToRead;
+	pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer;
+	pDataFlash->pDataFlashDesc->tx_data_size = sizeToRead;
+
+	status = AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src);
+	/* Send the command to the dataflash */
+	return(status);
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashPagePgmBuf				*/
+/* Object              : Main memory page program through buffer 1 or buffer 2	*/
+/* Input Parameters    : DataFlash Service					*/
+/*						: <*src> = Source buffer	*/
+/*                     : <dest> = dataflash destination address			*/
+/*                     : <SizeToWrite> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashPagePgmBuf(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	unsigned int dest,
+	unsigned int SizeToWrite)
+{
+	int cmdsize;
+	pDataFlash->pDataFlashDesc->tx_data_pt = src ;
+	pDataFlash->pDataFlashDesc->tx_data_size = SizeToWrite ;
+	pDataFlash->pDataFlashDesc->rx_data_pt = src;
+	pDataFlash->pDataFlashDesc->rx_data_size = SizeToWrite;
+
+	cmdsize = 4;
+	/* Send the command to the dataflash */
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_MainMemoryToBufferTransfert			*/
+/* Object              : Read a page in the SRAM Buffer 1 or 2			*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_MainMemoryToBufferTransfert(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned int page)
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */
+	if ((BufferCommand != DB_PAGE_2_BUF1_TRF) && (BufferCommand != DB_PAGE_2_BUF2_TRF))
+		return DATAFLASH_BAD_COMMAND;
+
+	/* no data to transmit or receive */
+	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
+}
+
+
+/*----------------------------------------------------------------------------- */
+/* Function Name       : AT91F_DataFlashWriteBuffer				*/
+/* Object              : Write data to the internal sram buffer 1 or 2		*/
+/* Input Parameters    : DataFlash Service					*/
+/*			: <BufferCommand> = command to write buffer1 or buffer2	*/
+/*                     : <*dataBuffer> = data buffer to write			*/
+/*                     : <bufferAddress> = address in the internal buffer	*/
+/*                     : <SizeToWrite> = data buffer size			*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWriteBuffer (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned char *dataBuffer,
+	unsigned int bufferAddress,
+	int SizeToWrite )
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */
+	if ((BufferCommand != DB_BUF1_WRITE) && (BufferCommand != DB_BUF2_WRITE))
+		return DATAFLASH_BAD_COMMAND;
+
+	/* buffer address must be lower than page size */
+	if (bufferAddress > pDataFlash->pDevice->pages_size)
+		return DATAFLASH_BAD_ADDRESS;
+
+	if ( (pDataFlash->pDataFlashDesc->state)  != IDLE)
+		return DATAFLASH_BUSY;
+
+	/* Send first Write Command */
+	pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
+	pDataFlash->pDataFlashDesc->command[1] = 0;
+	if (pDataFlash->pDevice->pages_number >= 16384) {
+	    	pDataFlash->pDataFlashDesc->command[2] = 0;
+	    	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
+	    	pDataFlash->pDataFlashDesc->command[4] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
+		cmdsize = 5;
+	} else {
+	    	pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress &  pDataFlash->pDevice->byte_mask)) >> 8) ;
+	    	pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress  & 0x00FF) ;
+	    	pDataFlash->pDataFlashDesc->command[4] = 0;
+		cmdsize = 4;
+	}
+
+	pDataFlash->pDataFlashDesc->tx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
+	pDataFlash->pDataFlashDesc->rx_cmd_pt 	 = pDataFlash->pDataFlashDesc->command ;
+	pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
+
+	pDataFlash->pDataFlashDesc->rx_data_pt 	= dataBuffer ;
+	pDataFlash->pDataFlashDesc->tx_data_pt 	= dataBuffer ;
+	pDataFlash->pDataFlashDesc->rx_data_size 	= SizeToWrite ;
+	pDataFlash->pDataFlashDesc->tx_data_size 	= SizeToWrite ;
+
+	return AT91F_SpiWrite(pDataFlash->pDataFlashDesc);
+}
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PageErase                                        */
+/* Object              : Erase a page 						*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PageErase(
+	AT91PS_DataFlash pDataFlash,
+	unsigned int page)
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */
+	/* no data to transmit or receive */
+    	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_ERASE, cmdsize, page*pDataFlash->pDevice->pages_size));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_BlockErase                                       */
+/* Object              : Erase a Block 						*/
+/* Input Parameters    : DataFlash Service					*/
+/*                     : Page concerned						*/
+/*                     : 							*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_BlockErase(
+	AT91PS_DataFlash pDataFlash,
+	unsigned int block)
+{
+	int cmdsize;
+	/* Test if the buffer command is legal */
+	/* no data to transmit or receive */
+    	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	return(AT91F_DataFlashSendCommand (pDataFlash, DB_BLOCK_ERASE,cmdsize, block*8*pDataFlash->pDevice->pages_size));
+}
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_WriteBufferToMain				*/
+/* Object              : Write buffer to the main memory			*/
+/* Input Parameters    : DataFlash Service					*/
+/*		: <BufferCommand> = command to send to buffer1 or buffer2	*/
+/*                     : <dest> = main memory address				*/
+/* Return value		: State of the dataflash				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_WriteBufferToMain (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char BufferCommand,
+	unsigned int dest )
+{
+	int cmdsize;
+	/* Test if the buffer command is correct */
+	if ((BufferCommand != DB_BUF1_PAGE_PGM) &&
+	    (BufferCommand != DB_BUF1_PAGE_ERASE_PGM) &&
+	    (BufferCommand != DB_BUF2_PAGE_PGM) &&
+	    (BufferCommand != DB_BUF2_PAGE_ERASE_PGM) )
+		return DATAFLASH_BAD_COMMAND;
+
+	/* no data to transmit or receive */
+	pDataFlash->pDataFlashDesc->tx_data_size = 0;
+
+	cmdsize = 4;
+	if (pDataFlash->pDevice->pages_number >= 16384)
+		cmdsize = 5;
+	/* Send the command to the dataflash */
+	return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_PartialPageWrite					*/
+/* Object              : Erase partielly a page					*/
+/* Input Parameters    : <page> = page number					*/
+/*			: <AdrInpage> = adr to begin the fading			*/
+/*                     : <length> = Number of bytes to erase			*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_PartialPageWrite (
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	unsigned int dest,
+	unsigned int size)
+{
+	unsigned int page;
+	unsigned int AdrInPage;
+
+	page = dest / (pDataFlash->pDevice->pages_size);
+	AdrInPage = dest % (pDataFlash->pDevice->pages_size);
+
+	/* Read the contents of the page in the Sram Buffer */
+	AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+	/*Update the SRAM buffer */
+	AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
+
+	AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+	/* Erase page if a 128 Mbits device */
+	if (pDataFlash->pDevice->pages_number >= 16384) {
+		AT91F_PageErase(pDataFlash, page);
+		/* Rewrite the modified Sram Buffer in the main memory */
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+	}
+
+	/* Rewrite the modified Sram Buffer in the main memory */
+	return(AT91F_WriteBufferToMain(pDataFlash, DB_BUF1_PAGE_ERASE_PGM, (page*pDataFlash->pDevice->pages_size)));
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashWrite					*/
+/* Object              :							*/
+/* Input Parameters    : <*src> = Source buffer					*/
+/*                     : <dest> = dataflash adress				*/
+/*                     : <size> = data buffer size				*/
+/*------------------------------------------------------------------------------*/
+AT91S_DataFlashStatus AT91F_DataFlashWrite(
+	AT91PS_DataFlash pDataFlash,
+	unsigned char *src,
+	int dest,
+	int size )
+{
+	unsigned int length;
+	unsigned int page;
+	unsigned int status;
+
+	AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+	if ( (dest + size) > (pDataFlash->pDevice->pages_size * (pDataFlash->pDevice->pages_number)))
+		return DATAFLASH_MEMORY_OVERFLOW;
+
+	/* If destination does not fit a page start address */
+	if ((dest % ((unsigned int)(pDataFlash->pDevice->pages_size)))  != 0 ) {
+		length = pDataFlash->pDevice->pages_size - (dest % ((unsigned int)(pDataFlash->pDevice->pages_size)));
+
+		if (size < length)
+			length = size;
+
+		if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+		/* Update size, source and destination pointers */
+		size -= length;
+		dest += length;
+		src += length;
+	}
+
+	while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
+		/* program dataflash page */
+		page = (unsigned int)dest / (pDataFlash->pDevice->pages_size);
+
+		status = AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, 0, pDataFlash->pDevice->pages_size);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+		status = AT91F_PageErase(pDataFlash, page);
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+		if (!status)
+			return DATAFLASH_ERROR;
+
+		status = AT91F_WriteBufferToMain (pDataFlash, DB_BUF1_PAGE_PGM, dest);
+		if(!status)
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+
+		/* Update size, source and destination pointers */
+		size -= pDataFlash->pDevice->pages_size ;
+		dest += pDataFlash->pDevice->pages_size ;
+		src  += pDataFlash->pDevice->pages_size ;
+	}
+
+	/* If still some bytes to read */
+	if ( size > 0 ) {
+		/* program dataflash page */
+		if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
+			return DATAFLASH_ERROR;
+
+		AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
+	}
+	return DATAFLASH_OK;
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataFlashRead 					*/
+/* Object              : Read a block in dataflash				*/
+/* Input Parameters    : 							*/
+/* Return value		: 							*/
+/*------------------------------------------------------------------------------*/
+int AT91F_DataFlashRead(
+	AT91PS_DataFlash pDataFlash,
+	unsigned long addr,
+	unsigned long size,
+	char *buffer)
+{
+	unsigned long SizeToRead;
+
+	AT91F_SpiEnable(pDataFlash->pDevice->cs);
+
+	if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
+		return -1;
+
+	while (size) {
+		SizeToRead = (size < 0x8000)? size:0x8000;
+
+		if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
+			return -1;
+
+		if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
+			return -1;
+
+		size -= SizeToRead;
+		addr += SizeToRead;
+		buffer += SizeToRead;
+	}
+
+	return DATAFLASH_OK;
+}
+
+
+/*------------------------------------------------------------------------------*/
+/* Function Name       : AT91F_DataflashProbe 					*/
+/* Object              : 							*/
+/* Input Parameters    : 							*/
+/* Return value	       : Dataflash status register				*/
+/*------------------------------------------------------------------------------*/
+int AT91F_DataflashProbe(int cs, AT91PS_DataflashDesc pDesc)
+{
+	AT91F_SpiEnable(cs);
+	AT91F_DataFlashGetStatus(pDesc);
+	return((pDesc->command[1] == 0xFF)? 0: pDesc->command[1] & 0x3C);
+}
+
+#endif
diff --git a/board/cmc_pu2/at91rm9200dk.c b/board/cmc_pu2/at91rm9200dk.c
new file mode 100644
index 0000000..606ea48
--- /dev/null
+++ b/board/cmc_pu2/at91rm9200dk.c
@@ -0,0 +1,118 @@
+/*
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Marius Groeger <mgroeger@sysgo.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 <common.h>
+#include <asm/arch/AT91RM9200.h>
+
+/* ------------------------------------------------------------------------- */
+/*
+ * Miscelaneous platform dependent initialisations
+ */
+
+int board_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* Enable Ctrlc */
+	console_init_f ();
+
+	/* Correct IRDA resistor problem */
+	/* Set PA23_TXD in Output */
+	(AT91PS_PIO) AT91C_BASE_PIOA->PIO_OER = AT91C_PA23_TXD2;
+
+	/* memory and cpu-speed are setup before relocation */
+	/* so we do _nothing_ here */
+
+	/* arch number of AT91RM9200DK-Board */
+	gd->bd->bi_arch_number = 251;
+	/* adress of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
+
+	return 0;
+}
+
+int dram_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	gd->bd->bi_dram[0].start = PHYS_SDRAM;
+	gd->bd->bi_dram[0].size = PHYS_SDRAM_SIZE;
+	return 0;
+}
+
+/*
+ * Disk On Chip (NAND) Millenium initialization.
+ * The NAND lives in the CS2* space
+ */
+#if (CONFIG_COMMANDS & CFG_CMD_NAND)
+extern ulong nand_probe (ulong physadr);
+
+#define AT91_SMARTMEDIA_BASE 0x40000000	/* physical address to access memory on NCS3 */
+void nand_init (void)
+{
+	/* Setup Smart Media, fitst enable the address range of CS3 */
+	*AT91C_EBI_CSA |= AT91C_EBI_CS3A_SMC_SmartMedia;
+	/* set the bus interface characteristics based on
+	   tDS Data Set up Time 30 - ns
+	   tDH Data Hold Time 20 - ns
+	   tALS ALE Set up Time 20 - ns
+	   16ns at 60 MHz ~= 3  */
+/*memory mapping structures */
+#define SM_ID_RWH	(5 << 28)
+#define SM_RWH		(1 << 28)
+#define SM_RWS		(0 << 24)
+#define SM_TDF		(1 << 8)
+#define SM_NWS		(3)
+	AT91C_BASE_SMC2->SMC2_CSR[3] = (SM_RWH | SM_RWS |
+		AT91C_SMC2_ACSS_STANDARD | AT91C_SMC2_DBW_8 |
+		SM_TDF | AT91C_SMC2_WSEN | SM_NWS);
+
+	/* enable the SMOE line PC0=SMCE, A21=CLE, A22=ALE */
+	*AT91C_PIOC_ASR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
+		AT91C_PC3_BFBAA_SMWE;
+	*AT91C_PIOC_PDR = AT91C_PC0_BFCK | AT91C_PC1_BFRDY_SMOE |
+		AT91C_PC3_BFBAA_SMWE;
+
+	/* Configure PC2 as input (signal READY of the SmartMedia) */
+	*AT91C_PIOC_PER = AT91C_PC2_BFAVD;	/* enable direct output enable */
+	*AT91C_PIOC_ODR = AT91C_PC2_BFAVD;	/* disable output */
+
+	/* Configure PB1 as input (signal Card Detect of the SmartMedia) */
+	*AT91C_PIOB_PER = AT91C_PIO_PB1;	/* enable direct output enable */
+	*AT91C_PIOB_ODR = AT91C_PIO_PB1;	/* disable output */
+
+	/* PIOB and PIOC clock enabling */
+	*AT91C_PMC_PCER = 1 << AT91C_ID_PIOB;
+	*AT91C_PMC_PCER = 1 << AT91C_ID_PIOC;
+
+	if (*AT91C_PIOB_PDSR & AT91C_PIO_PB1)
+		printf ("  No SmartMedia card inserted\n");
+#ifdef DEBUG
+	printf ("  SmartMedia card inserted\n");
+
+	printf ("Probing at 0x%.8x\n", AT91_SMARTMEDIA_BASE);
+#endif
+	printf ("%4lu MB\n", nand_probe(AT91_SMARTMEDIA_BASE) >> 20);
+}
+#endif
diff --git a/board/cmc_pu2/config.mk b/board/cmc_pu2/config.mk
new file mode 100644
index 0000000..9ce161e
--- /dev/null
+++ b/board/cmc_pu2/config.mk
@@ -0,0 +1 @@
+TEXT_BASE = 0x21f00000
diff --git a/board/cmc_pu2/dm9161.c b/board/cmc_pu2/dm9161.c
new file mode 100644
index 0000000..73537c0
--- /dev/null
+++ b/board/cmc_pu2/dm9161.c
@@ -0,0 +1,243 @@
+/*
+ * (C) Copyright 2003
+ * Author : Hamid Ikdoumi (Atmel)
+ *
+ * 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 <at91rm9200_net.h>
+#include <net.h>
+#include <dm9161.h>
+
+#ifdef CONFIG_DRIVER_ETHER
+
+#if (CONFIG_COMMANDS & CFG_CMD_NET)
+
+/*
+ * Name:
+ *	dm9161_IsPhyConnected
+ * Description:
+ *	Reads the 2 PHY ID registers
+ * Arguments:
+ *	p_mac - pointer to AT91S_EMAC struct
+ * Return value:
+ *	TRUE - if id read successfully
+ *	FALSE- if error
+ */
+static unsigned int dm9161_IsPhyConnected (AT91PS_EMAC p_mac)
+{
+	unsigned short Id1, Id2;
+
+	at91rm9200_EmacEnableMDIO (p_mac);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID1, &Id1);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_PHYID2, &Id2);
+	at91rm9200_EmacDisableMDIO (p_mac);
+
+	if ((Id1 == (DM9161_PHYID1_OUI >> 6)) &&
+		((Id2 >> 10) == (DM9161_PHYID1_OUI & DM9161_LSB_MASK)))
+		return TRUE;
+
+	return FALSE;
+}
+
+/*
+ * Name:
+ *	dm9161_GetLinkSpeed
+ * Description:
+ *	Link parallel detection status of MAC is checked and set in the
+ *	MAC configuration registers
+ * Arguments:
+ *	p_mac - pointer to MAC
+ * Return value:
+ *	TRUE - if link status set succesfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_GetLinkSpeed (AT91PS_EMAC p_mac)
+{
+	unsigned short stat1, stat2;
+
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &stat1))
+		return FALSE;
+
+	if (!(stat1 & DM9161_LINK_STATUS))	/* link status up? */
+		return FALSE;
+
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_DSCSR, &stat2))
+		return FALSE;
+
+	if ((stat1 & DM9161_100BASE_TX_FD) && (stat2 & DM9161_100FDX)) {
+		/*set Emac for 100BaseTX and Full Duplex  */
+		p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_10BASE_T_FD) && (stat2 & DM9161_10FDX)) {
+		/*set MII for 10BaseT and Full Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_100BASE_T4_HD) && (stat2 & DM9161_100HDX)) {
+		/*set MII for 100BaseTX and Half Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_SPD;
+		return TRUE;
+	}
+
+	if ((stat1 & DM9161_10BASE_T_HD) && (stat2 & DM9161_10HDX)) {
+		/*set MII for 10BaseT and Half Duplex  */
+		p_mac->EMAC_CFG &= ~(AT91C_EMAC_SPD | AT91C_EMAC_FD);
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+/*
+ * Name:
+ *	dm9161_InitPhy
+ * Description:
+ *	MAC starts checking its link by using parallel detection and
+ *	Autonegotiation and the same is set in the MAC configuration registers
+ * Arguments:
+ *	p_mac - pointer to struct AT91S_EMAC
+ * Return value:
+ *	TRUE - if link status set succesfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_InitPhy (AT91PS_EMAC p_mac)
+{
+	UCHAR ret = TRUE;
+	unsigned short IntValue;
+
+	at91rm9200_EmacEnableMDIO (p_mac);
+
+	if (!dm9161_GetLinkSpeed (p_mac)) {
+		/* Try another time */
+		ret = dm9161_GetLinkSpeed (p_mac);
+	}
+
+	/* Disable PHY Interrupts */
+	at91rm9200_EmacReadPhy (p_mac, DM9161_MDINTR, &IntValue);
+	/* clear FDX, SPD, Link, INTR masks */
+	IntValue &= ~(DM9161_FDX_MASK | DM9161_SPD_MASK |
+		      DM9161_LINK_MASK | DM9161_INTR_MASK);
+	at91rm9200_EmacWritePhy (p_mac, DM9161_MDINTR, &IntValue);
+	at91rm9200_EmacDisableMDIO (p_mac);
+
+	return (ret);
+}
+
+
+/*
+ * Name:
+ *	dm9161_AutoNegotiate
+ * Description:
+ *	MAC Autonegotiates with the partner status of same is set in the
+ *	MAC configuration registers
+ * Arguments:
+ *	dev - pointer to struct net_device
+ * Return value:
+ *	TRUE - if link status set successfully
+ *	FALSE - if link status not set
+ */
+static UCHAR dm9161_AutoNegotiate (AT91PS_EMAC p_mac, int *status)
+{
+	unsigned short value;
+	unsigned short PhyAnar;
+	unsigned short PhyAnalpar;
+
+	/* Set dm9161 control register */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+	value &= ~DM9161_AUTONEG;	/* remove autonegotiation enable */
+	value |= DM9161_ISOLATE;	/* Electrically isolate PHY */
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	/* Set the Auto_negotiation Advertisement Register */
+	/* MII advertising for Next page, 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3 */
+	PhyAnar = DM9161_NP | DM9161_TX_FDX | DM9161_TX_HDX |
+		  DM9161_10_FDX | DM9161_10_HDX | DM9161_AN_IEEE_802_3;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_ANAR, &PhyAnar))
+		return FALSE;
+
+	/* Read the Control Register     */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	value |= DM9161_SPEED_SELECT | DM9161_AUTONEG | DM9161_DUPLEX_MODE;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+	/* Restart Auto_negotiation  */
+	value |= DM9161_RESTART_AUTONEG;
+	if (!at91rm9200_EmacWritePhy (p_mac, DM9161_BMCR, &value))
+		return FALSE;
+
+	/*check AutoNegotiate complete */
+	udelay (10000);
+	at91rm9200_EmacReadPhy (p_mac, DM9161_BMSR, &value);
+	if (!(value & DM9161_AUTONEG_COMP))
+		return FALSE;
+
+	/* Get the AutoNeg Link partner base page */
+	if (!at91rm9200_EmacReadPhy (p_mac, DM9161_ANLPAR, &PhyAnalpar))
+		return FALSE;
+
+	if ((PhyAnar & DM9161_TX_FDX) && (PhyAnalpar & DM9161_TX_FDX)) {
+		/*set MII for 100BaseTX and Full Duplex  */
+		p_mac->EMAC_CFG |= AT91C_EMAC_SPD | AT91C_EMAC_FD;
+		return TRUE;
+	}
+
+	if ((PhyAnar & DM9161_10_FDX) && (PhyAnalpar & DM9161_10_FDX)) {
+		/*set MII for 10BaseT and Full Duplex  */
+		p_mac->EMAC_CFG = (p_mac->EMAC_CFG &
+				~(AT91C_EMAC_SPD | AT91C_EMAC_FD))
+				| AT91C_EMAC_FD;
+		return TRUE;
+	}
+	return FALSE;
+}
+
+
+/*
+ * Name:
+ *	at91rm92000_GetPhyInterface
+ * Description:
+ *	Initialise the interface functions to the PHY
+ * Arguments:
+ *	None
+ * Return value:
+ *	None
+ */
+void at91rm92000_GetPhyInterface(AT91PS_PhyOps p_phyops)
+{
+	p_phyops->Init = dm9161_InitPhy;
+	p_phyops->IsPhyConnected = dm9161_IsPhyConnected;
+	p_phyops->GetLinkSpeed = dm9161_GetLinkSpeed;
+	p_phyops->AutoNegotiate = dm9161_AutoNegotiate;
+}
+
+#endif	/* CONFIG_COMMANDS & CFG_CMD_NET */
+
+#endif	/* CONFIG_DRIVER_ETHER */
diff --git a/board/cmc_pu2/flash.c b/board/cmc_pu2/flash.c
new file mode 100644
index 0000000..5220fcf
--- /dev/null
+++ b/board/cmc_pu2/flash.c
@@ -0,0 +1,507 @@
+/*
+ * (C) Copyright 2002
+ * Lineo, Inc. <www.lineo.com>
+ * Bernhard Kuhn <bkuhn@lineo.com>
+ *
+ * (C) Copyright 2002
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Alex Zuepke <azu@sysgo.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 <common.h>
+
+ulong myflush(void);
+
+
+/* Flash Organization Structure */
+typedef struct OrgDef
+{
+	unsigned int sector_number;
+	unsigned int sector_size;
+} OrgDef;
+
+
+/* Flash Organizations */
+OrgDef OrgAT49BV16x4[] =
+{
+	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
+	{  2, 32*1024 },	/*   2 * 32 kBytes sectors */
+	{ 30, 64*1024 },	/*  30 * 64 kBytes sectors */
+};
+
+OrgDef OrgAT49BV16x4A[] =
+{
+	{  8,  8*1024 },	/*   8 *  8 kBytes sectors */
+	{ 31, 64*1024 },	/*  31 * 64 kBytes sectors */
+};
+
+OrgDef OrgAT49BV6416[] =
+{
+	{   8,  8*1024 },	/*   8 *  8 kBytes sectors */
+	{ 127, 64*1024 },	/* 127 * 64 kBytes sectors */
+};
+
+flash_info_t    flash_info[CFG_MAX_FLASH_BANKS];
+
+/* AT49BV1614A Codes */
+#define FLASH_CODE1		0xAA
+#define FLASH_CODE2		0x55
+#define ID_IN_CODE		0x90
+#define ID_OUT_CODE		0xF0
+
+
+#define CMD_READ_ARRAY		0x00F0
+#define CMD_UNLOCK1		0x00AA
+#define CMD_UNLOCK2		0x0055
+#define CMD_ERASE_SETUP		0x0080
+#define CMD_ERASE_CONFIRM	0x0030
+#define CMD_PROGRAM		0x00A0
+#define CMD_UNLOCK_BYPASS	0x0020
+#define CMD_SECTOR_UNLOCK	0x0070
+
+#define MEM_FLASH_ADDR1		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00005555<<1)))
+#define MEM_FLASH_ADDR2		(*(volatile u16 *)(CFG_FLASH_BASE + (0x00002AAA<<1)))
+
+#define BIT_ERASE_DONE		0x0080
+#define BIT_RDY_MASK		0x0080
+#define BIT_PROGRAM_ERROR	0x0020
+#define BIT_TIMEOUT		0x80000000 /* our flag */
+
+#define READY 1
+#define ERR   2
+#define TMO   4
+
+/*-----------------------------------------------------------------------
+ */
+void flash_identification (flash_info_t * info)
+{
+	volatile u16 manuf_code, device_code, add_device_code;
+
+	MEM_FLASH_ADDR1 = FLASH_CODE1;
+	MEM_FLASH_ADDR2 = FLASH_CODE2;
+	MEM_FLASH_ADDR1 = ID_IN_CODE;
+
+	manuf_code = *(volatile u16 *) CFG_FLASH_BASE;
+	device_code = *(volatile u16 *) (CFG_FLASH_BASE + 2);
+	add_device_code = *(volatile u16 *) (CFG_FLASH_BASE + (3 << 1));
+
+	MEM_FLASH_ADDR1 = FLASH_CODE1;
+	MEM_FLASH_ADDR2 = FLASH_CODE2;
+	MEM_FLASH_ADDR1 = ID_OUT_CODE;
+
+	/* Vendor type */
+	info->flash_id = ATM_MANUFACT & FLASH_VENDMASK;
+	printf ("Atmel: ");
+
+	if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV1614 & FLASH_TYPEMASK)) {
+
+		if ((add_device_code & FLASH_TYPEMASK) ==
+			(ATM_ID_BV1614A & FLASH_TYPEMASK)) {
+			info->flash_id |= ATM_ID_BV1614A & FLASH_TYPEMASK;
+			printf ("AT49BV1614A (16Mbit)\n");
+		} else {				/* AT49BV1614 Flash */
+			info->flash_id |= ATM_ID_BV1614 & FLASH_TYPEMASK;
+			printf ("AT49BV1614 (16Mbit)\n");
+		}
+
+	} else if ((device_code & FLASH_TYPEMASK) == (ATM_ID_BV6416 & FLASH_TYPEMASK)) {
+		info->flash_id |= ATM_ID_BV6416 & FLASH_TYPEMASK;
+		printf ("AT49BV6416 (64Mbit)\n");
+	}
+}
+
+ushort flash_number_sector(OrgDef *pOrgDef, unsigned int nb_blocks)
+{
+	int i, nb_sectors = 0;
+
+	for (i=0; i<nb_blocks; i++){
+		nb_sectors += pOrgDef[i].sector_number;
+	}
+
+	return nb_sectors;
+}
+
+void flash_unlock_sector(flash_info_t * info, unsigned int sector)
+{
+	volatile u16 *addr = (volatile u16 *) (info->start[sector]);
+
+	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+	*addr = CMD_SECTOR_UNLOCK;
+}
+
+
+ulong flash_init (void)
+{
+	int i, j, k;
+	unsigned int flash_nb_blocks, sector;
+	unsigned int start_address;
+	OrgDef *pOrgDef;
+
+	ulong size = 0;
+
+	for (i = 0; i < CFG_MAX_FLASH_BANKS; i++) {
+		ulong flashbase = 0;
+
+		flash_identification (&flash_info[i]);
+
+		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+			(ATM_ID_BV1614 & FLASH_TYPEMASK)) {
+
+			pOrgDef = OrgAT49BV16x4;
+			flash_nb_blocks = sizeof (OrgAT49BV16x4) / sizeof (OrgDef);
+		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+			(ATM_ID_BV1614A & FLASH_TYPEMASK)){	/* AT49BV1614A Flash */
+
+			pOrgDef = OrgAT49BV16x4A;
+			flash_nb_blocks = sizeof (OrgAT49BV16x4A) / sizeof (OrgDef);
+		} else if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+			(ATM_ID_BV6416 & FLASH_TYPEMASK)){	/* AT49BV6416 Flash */
+
+			pOrgDef = OrgAT49BV6416;
+			flash_nb_blocks = sizeof (OrgAT49BV6416) / sizeof (OrgDef);
+		} else {
+			flash_nb_blocks = 0;
+			pOrgDef = OrgAT49BV16x4;
+		}
+
+		flash_info[i].sector_count = flash_number_sector(pOrgDef, flash_nb_blocks);
+		memset (flash_info[i].protect, 0, flash_info[i].sector_count);
+
+		if (i == 0)
+			flashbase = PHYS_FLASH_1;
+		else
+			panic ("configured too many flash banks!\n");
+
+		sector = 0;
+		start_address = flashbase;
+		flash_info[i].size = 0;
+
+		for (j = 0; j < flash_nb_blocks; j++) {
+			for (k = 0; k < pOrgDef[j].sector_number; k++) {
+				flash_info[i].start[sector++] = start_address;
+				start_address += pOrgDef[j].sector_size;
+				flash_info[i].size += pOrgDef[j].sector_size;
+			}
+		}
+
+		size += flash_info[i].size;
+
+		if ((flash_info[i].flash_id & FLASH_TYPEMASK) ==
+			(ATM_ID_BV6416 & FLASH_TYPEMASK)){	/* AT49BV6416 Flash */
+
+			/* Unlock all sectors at reset */
+			for (j=0; j<flash_info[i].sector_count; j++){
+				flash_unlock_sector(&flash_info[i], j);
+			}
+		}
+	}
+
+	/* Protect binary boot image */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_FLASH_BASE,
+		       CFG_FLASH_BASE + CFG_BOOT_SIZE - 1, &flash_info[0]);
+
+	/* Protect environment variables */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_ENV_ADDR,
+		       CFG_ENV_ADDR + CFG_ENV_SIZE - 1, &flash_info[0]);
+
+	/* Protect U-Boot gzipped image */
+	flash_protect (FLAG_PROTECT_SET,
+		       CFG_U_BOOT_BASE,
+		       CFG_U_BOOT_BASE + CFG_U_BOOT_SIZE - 1, &flash_info[0]);
+
+	return size;
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info (flash_info_t * info)
+{
+	int i;
+
+	switch (info->flash_id & FLASH_VENDMASK) {
+	case (ATM_MANUFACT & FLASH_VENDMASK):
+		printf ("Atmel: ");
+		break;
+	default:
+		printf ("Unknown Vendor ");
+		break;
+	}
+
+	switch (info->flash_id & FLASH_TYPEMASK) {
+	case (ATM_ID_BV1614 & FLASH_TYPEMASK):
+		printf ("AT49BV1614 (16Mbit)\n");
+		break;
+	case (ATM_ID_BV1614A & FLASH_TYPEMASK):
+		printf ("AT49BV1614A (16Mbit)\n");
+		break;
+	case (ATM_ID_BV6416 & FLASH_TYPEMASK):
+		printf ("AT49BV6416 (64Mbit)\n");
+		break;
+	default:
+		printf ("Unknown Chip Type\n");
+		goto Done;
+		break;
+	}
+
+	printf ("  Size: %ld MB in %d Sectors\n",
+		info->size >> 20, 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");
+
+Done:	;
+}
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t * info, int s_first, int s_last)
+{
+	ulong result;
+	int iflag, cflag, prot, sect;
+	int rc = ERR_OK;
+	int chip1;
+
+	/* first look for protection bits */
+
+	if (info->flash_id == FLASH_UNKNOWN)
+		return ERR_UNKNOWN_FLASH_TYPE;
+
+	if ((s_first < 0) || (s_first > s_last)) {
+		return ERR_INVAL;
+	}
+
+	if ((info->flash_id & FLASH_VENDMASK) !=
+		(ATM_MANUFACT & FLASH_VENDMASK)) {
+		return ERR_UNKNOWN_FLASH_VENDOR;
+	}
+
+	prot = 0;
+	for (sect = s_first; sect <= s_last; ++sect) {
+		if (info->protect[sect]) {
+			prot++;
+		}
+	}
+	if (prot)
+		return ERR_PROTECTED;
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	cflag = icache_status ();
+	icache_disable ();
+	iflag = disable_interrupts ();
+
+	/* Start erase on unprotected sectors */
+	for (sect = s_first; sect <= s_last && !ctrlc (); sect++) {
+		printf ("Erasing sector %2d ... ", sect);
+
+		/* arm simple, non interrupt dependent timer */
+		reset_timer_masked ();
+
+		if (info->protect[sect] == 0) {	/* not protected */
+			volatile u16 *addr = (volatile u16 *) (info->start[sect]);
+
+			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+			MEM_FLASH_ADDR1 = CMD_ERASE_SETUP;
+
+			MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+			MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+			*addr = CMD_ERASE_CONFIRM;
+
+			/* wait until flash is ready */
+			chip1 = 0;
+
+			do {
+				result = *addr;
+
+				/* check timeout */
+				if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+					MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+					chip1 = TMO;
+					break;
+				}
+
+				if (!chip1 && (result & 0xFFFF) & BIT_ERASE_DONE)
+					chip1 = READY;
+
+			} while (!chip1);
+
+			MEM_FLASH_ADDR1 = CMD_READ_ARRAY;
+
+			if (chip1 == ERR) {
+				rc = ERR_PROG_ERROR;
+				goto outahere;
+			}
+			if (chip1 == TMO) {
+				rc = ERR_TIMOUT;
+				goto outahere;
+			}
+
+			printf ("ok.\n");
+		} else {			/* it was protected */
+			printf ("protected!\n");
+		}
+	}
+
+	if (ctrlc ())
+		printf ("User Interrupt!\n");
+
+outahere:
+	/* allow flash to settle - wait 10 ms */
+	udelay_masked (10000);
+
+	if (iflag)
+		enable_interrupts ();
+
+	if (cflag)
+		icache_enable ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash
+ */
+
+volatile static int write_word (flash_info_t * info, ulong dest,
+								ulong data)
+{
+	volatile u16 *addr = (volatile u16 *) dest;
+	ulong result;
+	int rc = ERR_OK;
+	int cflag, iflag;
+	int chip1;
+
+	/*
+	 * Check if Flash is (sufficiently) erased
+	 */
+	result = *addr;
+	if ((result & data) != data)
+		return ERR_NOT_ERASED;
+
+
+	/*
+	 * Disable interrupts which might cause a timeout
+	 * here. Remember that our exception vectors are
+	 * at address 0 in the flash, and we don't want a
+	 * (ticker) exception to happen while the flash
+	 * chip is in programming mode.
+	 */
+	cflag = icache_status ();
+	icache_disable ();
+	iflag = disable_interrupts ();
+
+	MEM_FLASH_ADDR1 = CMD_UNLOCK1;
+	MEM_FLASH_ADDR2 = CMD_UNLOCK2;
+	MEM_FLASH_ADDR1 = CMD_PROGRAM;
+	*addr = data;
+
+	/* arm simple, non interrupt dependent timer */
+	reset_timer_masked ();
+
+	/* wait until flash is ready */
+	chip1 = 0;
+	do {
+		result = *addr;
+
+		/* check timeout */
+		if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
+			chip1 = ERR | TMO;
+			break;
+		}
+		if (!chip1 && ((result & 0x80) == (data & 0x80)))
+			chip1 = READY;
+
+	} while (!chip1);
+
+	*addr = CMD_READ_ARRAY;
+
+	if (chip1 == ERR || *addr != data)
+		rc = ERR_PROG_ERROR;
+
+	if (iflag)
+		enable_interrupts ();
+
+	if (cflag)
+		icache_enable ();
+
+	return rc;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash.
+ */
+
+int write_buff (flash_info_t * info, uchar * src, ulong addr, ulong cnt)
+{
+	ulong wp, data;
+	int rc;
+
+	if (addr & 1) {
+		printf ("unaligned destination not supported\n");
+		return ERR_ALIGN;
+	};
+
+	if ((int) src & 1) {
+		printf ("unaligned source not supported\n");
+		return ERR_ALIGN;
+	};
+
+	wp = addr;
+
+	while (cnt >= 2) {
+		data = *((volatile u16 *) src);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 2;
+		wp += 2;
+		cnt -= 2;
+	}
+
+	if (cnt == 1) {
+		data = (*((volatile u8 *) src)) | (*((volatile u8 *) (wp + 1)) <<
+										   8);
+		if ((rc = write_word (info, wp, data)) != 0) {
+			return (rc);
+		}
+		src += 1;
+		wp += 1;
+		cnt -= 1;
+	};
+
+	return ERR_OK;
+}
diff --git a/board/cmc_pu2/memsetup.S b/board/cmc_pu2/memsetup.S
new file mode 100644
index 0000000..168cd6b
--- /dev/null
+++ b/board/cmc_pu2/memsetup.S
@@ -0,0 +1,200 @@
+/*
+ * Memory Setup stuff - taken from blob memsetup.S
+ *
+ * Copyright (C) 1999 2000 2001 Erik Mouw (J.A.K.Mouw@its.tudelft.nl) and
+ *                     Jan-Derk Bakker (J.D.Bakker@its.tudelft.nl)
+ *
+ * Modified for the at91rm9200dk board by
+ * (C) Copyright 2004
+ * Gary Jennejohn, DENX Software Engineering, <gj@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 <config.h>
+#include <version.h>
+
+#ifdef CONFIG_BOOTBINFUNC
+/*
+ * some parameters for the board
+ *
+ * This is based on rm9200dk.cfg for the BDI2000 from ABATRON which in
+ * turn is based on the boot.bin code from ATMMEL
+ *
+ */
+
+/* flash */
+#define MC_PUIA 0xFFFFFF10
+#define MC_PUIA_VAL 0x00000000
+#define MC_PUP 0xFFFFFF50
+#define MC_PUP_VAL 0x00000000
+#define MC_PUER 0xFFFFFF54
+#define MC_PUER_VAL 0x00000000
+#define MC_ASR 0xFFFFFF04
+#define MC_ASR_VAL 0x00000000
+#define MC_AASR 0xFFFFFF08
+#define MC_AASR_VAL 0x00000000
+#define EBI_CFGR 0xFFFFFF64
+#define EBI_CFGR_VAL 0x00000000
+#define SMC2_CSR 0xFFFFFF70
+#define SMC2_CSR_VAL 0x00003284 /* 16bit, 2 TDF, 4 WS */
+
+/* clocks */
+#define PLLAR 0xFFFFFC28
+#define PLLAR_VAL 0x20263E04 /* 179.712000 MHz for PCK */
+#define PLLBR 0xFFFFFC2C
+#define PLLBR_VAL 0x10483E0E /* 48.054857 MHz (divider by 2 for USB) */
+#define MCKR 0xFFFFFC30
+#define MCKR_VAL 0x00000202 /* PCK/3 = MCK Master Clock = 59.904000MHz from PLLA */
+
+/* sdram */
+#define PIOC_ASR 0xFFFFF870
+#define PIOC_ASR_VAL 0xFFFF0000 /* Configure PIOC as peripheral (D16/D31) */
+#define PIOC_BSR 0xFFFFF804
+#define PIOC_BSR_VAL 0x00000000
+#define PIOC_PDR 0xFFFFF804
+#define PIOC_PDR_VAL 0xFFFF0000
+#define EBI_CSA 0xFFFFFF60
+#define EBI_CSA_VAL 0x00000002 /* CS1=SDRAM */
+#define SDRC_CR 0xFFFFFF98
+#define SDRC_CR_VAL 0x2188c155
+#define SDRAM 0x20000000 /* address of the SDRAM */
+#define SDRAM1 0x20000080 /* address of the SDRAM */
+#define SDRAM_VAL 0x00000000 /* value written to SDRAM */
+#define SDRC_MR 0xFFFFFF90
+#define SDRC_MR_VAL 0x00000002 /* Precharge All */
+#define SDRC_MR_VAL1 0x00000004 /* refresh */
+#define SDRC_MR_VAL2 0x00000003 /* Load Mode Register */
+#define SDRC_MR_VAL3 0x00000000 /* Normal Mode */
+#define SDRC_TR 0xFFFFFF94
+#define SDRC_TR_VAL 0x000002E0 /* Write refresh rate */
+
+
+_TEXT_BASE:
+	.word	TEXT_BASE
+
+.globl memsetup
+memsetup:
+	/* memory control configuration */
+	/* this isn't very elegant, but  what the heck */
+	ldr     r0, =SMRDATA
+	ldr	r1, _TEXT_BASE
+	sub	r0, r0, r1
+	add     r2, r0, #80
+0:
+	/* the address */
+	ldr     r1, [r0], #4
+	/* the value */
+	ldr     r3, [r0], #4
+	str     r3, [r1]
+	cmp     r2, r0
+	bne     0b
+	/* delay - this is all done by guess */
+	ldr 	r0, =0x00001000
+1:
+	subs    r0, r0, #1              
+	bhi     1b
+	ldr     r0, =SMRDATA1
+	ldr	r1, _TEXT_BASE
+	sub	r0, r0, r1
+	add     r2, r0, #176
+2:
+	/* the address */
+	ldr     r1, [r0], #4
+	/* the value */
+	ldr     r3, [r0], #4
+	str     r3, [r1]
+	cmp     r2, r0
+	bne     2b
+
+	/* everything is fine now */
+	mov	pc, lr
+
+	.ltorg
+
+SMRDATA:
+	.word MC_PUIA
+	.word MC_PUIA_VAL
+	.word MC_PUP
+	.word MC_PUP_VAL
+	.word MC_PUER
+	.word MC_PUER_VAL
+	.word MC_ASR
+	.word MC_ASR_VAL
+	.word MC_AASR
+	.word MC_AASR_VAL
+	.word EBI_CFGR
+	.word EBI_CFGR_VAL
+	.word SMC2_CSR
+	.word SMC2_CSR_VAL
+	.word PLLAR
+	.word PLLAR_VAL
+	.word PLLBR
+	.word PLLBR_VAL
+	.word MCKR
+	.word MCKR_VAL
+	/* SMRDATA is 80 bytes long */
+	/* here there's a delay of 100 */
+SMRDATA1:
+	.word PIOC_ASR
+	.word PIOC_ASR_VAL
+	.word PIOC_BSR
+	.word PIOC_BSR_VAL
+	.word PIOC_PDR
+	.word PIOC_PDR_VAL
+	.word EBI_CSA
+	.word EBI_CSA_VAL
+	.word SDRC_CR
+	.word SDRC_CR_VAL
+	.word SDRC_MR
+	.word SDRC_MR_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRC_MR
+	.word SDRC_MR_VAL1
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRC_MR
+	.word SDRC_MR_VAL2
+	.word SDRAM1
+	.word SDRAM_VAL
+	.word SDRC_TR
+	.word SDRC_TR_VAL
+	.word SDRAM
+	.word SDRAM_VAL
+	.word SDRC_MR
+	.word SDRC_MR_VAL3
+	.word SDRAM
+	.word SDRAM_VAL
+	/* SMRDATA1 is 176 bytes long */
+#endif /* CONFIG_BOOTBINFUNC */
diff --git a/board/cmc_pu2/u-boot.lds b/board/cmc_pu2/u-boot.lds
new file mode 100644
index 0000000..0282898
--- /dev/null
+++ b/board/cmc_pu2/u-boot.lds
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <gj@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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  cpu/at91rm9200/start.o	(.text)
+	  *(.text)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+
+	. = ALIGN(4);
+	.data : { *(.data) }
+
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	__u_boot_cmd_start = .;
+	.u_boot_cmd : { *(.u_boot_cmd) }
+	__u_boot_cmd_end = .;
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}