www.pudn.com > uboot-DataFlash_1_01.zip > patch-u-boot-AT91RM9200-dataflash.dat
diff -purN u-boot-1.0.0.orig/CHANGELOG u-boot-1.0.0.test/CHANGELOG
--- u-boot-1.0.0.orig/CHANGELOG Thu Oct 30 22:49:38 2003
+++ u-boot-1.0.0.test/CHANGELOG Fri Nov 7 20:35:54 2003
@@ -2,6 +2,11 @@
Changes for U-Boot 1.0.0:
======================================================================
+* Patch by Nicolas Lacressonniere, 12 Nov 2003:
+ Modifications for Atmel AT91RM9200DK ARM920T based development kit
+ - Add Atmel DataFlash AT45DB1282 support
+ - Add the possibility to set the environment variables in DataFlash
+
* Fix parameter passing to standalone images with bootm command
* Patch by Kyle Harris, 30 Oct 2003:
diff -purN u-boot-1.0.0.orig/README u-boot-1.0.0.test/README
--- u-boot-1.0.0.orig/README Mon Oct 20 01:22:11 2003
+++ u-boot-1.0.0.test/README Fri Nov 7 20:24:42 2003
@@ -1742,6 +1742,20 @@ to save the current settings.
The size in bytes of the EEPROM device.
+- CFG_ENV_IS_IN_DATAFLASH:
+
+ Define this if you have a DataFlash memory device which you
+ want to use for the environment.
+
+ - CFG_ENV_OFFSET:
+ - CFG_ENV_ADDR:
+ - CFG_ENV_SIZE:
+
+ These three #defines specify the offset and size of the
+ environment area within the total memory of your DataFlash placed
+ at the specified address.
+
+
- CFG_SPI_INIT_OFFSET
Defines offset to the initial SPI buffer area in DPRAM. The
diff -purN u-boot-1.0.0.orig/common/Makefile u-boot-1.0.0.test/common/Makefile
--- u-boot-1.0.0.orig/common/Makefile Thu Oct 9 22:09:04 2003
+++ u-boot-1.0.0.test/common/Makefile Fri Nov 7 15:46:59 2003
@@ -42,7 +42,7 @@ COBJS = main.o ACEX1K.o altera.o bedbug.
cmd_reginfo.o cmd_scsi.o cmd_spi.o cmd_usb.o cmd_vfd.o \
command.o console.o devices.o dlmalloc.o docecc.o \
environment.o env_common.o \
- env_flash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
+ env_flash.o env_dataflash.o env_eeprom.o env_nvram.o env_nowhere.o exports.o \
flash.o fpga.o \
hush.o kgdb.o lists.o lynxkdi.o miiphybb.o miiphyutil.o \
s_record.o soft_i2c.o soft_spi.o spartan2.o \
diff -purN u-boot-1.0.0.orig/common/cmd_flash.c u-boot-1.0.0.test/common/cmd_flash.c
--- u-boot-1.0.0.orig/common/cmd_flash.c Tue Oct 14 21:43:56 2003
+++ u-boot-1.0.0.test/common/cmd_flash.c Fri Nov 7 16:31:36 2003
@@ -307,7 +307,9 @@ int do_protect (cmd_tbl_t *cmdtp, int fl
ulong bank, addr_first, addr_last;
int i, p, n, sect_first, sect_last;
int rcode = 0;
-
+#ifdef CONFIG_HAS_DATAFLASH
+ int status;
+#endif
if (argc < 3) {
printf ("Usage:\n%s\n", cmdtp->usage);
return 1;
@@ -322,7 +324,28 @@ int do_protect (cmd_tbl_t *cmdtp, int fl
return 1;
}
+#ifdef CONFIG_HAS_DATAFLASH
+ if ( (strcmp(argv[2], "all") != 0) && (strcmp(argv[2], "bank") != 0) ){
+
+ addr_first = simple_strtoul(argv[2], NULL, 16);
+ addr_last = simple_strtoul(argv[3], NULL, 16);
+
+ if (addr_dataflash(addr_first) && addr_dataflash(addr_last) ){
+
+ status = dataflash_real_protect(p,addr_first,addr_last);
+ if (status < 0){
+ printf("Bad DataFlash sector specification\n");
+ return 1;
+ }
+ printf("%sProtect %d DataFlash Sectors\n",
+ p ? "" : "Un-", status);
+ return 0;
+ }
+ }
+#endif
+
if (strcmp(argv[2], "all") == 0) {
+
for (bank=1; bank<=CFG_MAX_FLASH_BANKS; ++bank) {
info = &flash_info[bank-1];
if (info->flash_id == FLASH_UNKNOWN) {
diff -purN u-boot-1.0.0.orig/common/cmd_mem.c u-boot-1.0.0.test/common/cmd_mem.c
--- u-boot-1.0.0.orig/common/cmd_mem.c Thu Sep 18 11:21:35 2003
+++ u-boot-1.0.0.test/common/cmd_mem.c Fri Nov 7 19:18:14 2003
@@ -136,13 +136,19 @@ int do_mem_md ( cmd_tbl_t *cmdtp, int fl
uint *uip = (uint *)linebuf;
ushort *usp = (ushort *)linebuf;
u_char *ucp = (u_char *)linebuf;
-
+#ifdef CONFIG_HAS_DATAFLASH
+ int rc;
+#endif
printf("%08lx:", addr);
linebytes = (nbytes>DISP_LINE_LEN)?DISP_LINE_LEN:nbytes;
#ifdef CONFIG_HAS_DATAFLASH
- if (read_dataflash(addr, (linebytes/size)*size, linebuf) != -1){
-
+ if ((rc = read_dataflash(addr, (linebytes/size)*size, linebuf)) == DATAFLASH_OK){
+ /* if outside dataflash */
+ /*if (rc != 1) {
+ dataflash_perror (rc);
+ return (1);
+ }*/
for (i=0; i
#endif
-#if !defined(CFG_ENV_IS_IN_NVRAM) && !defined(CFG_ENV_IS_IN_EEPROM) && !defined(CFG_ENV_IS_IN_FLASH) && !defined(CFG_ENV_IS_NOWHERE)
-# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH, CFG_ENV_IS_NOWHERE
+#if !defined(CFG_ENV_IS_IN_NVRAM) && !defined(CFG_ENV_IS_IN_EEPROM) && !defined(CFG_ENV_IS_IN_FLASH) && !defined(CFG_ENV_IS_IN_DATAFLASH) && !defined(CFG_ENV_IS_NOWHERE)
+# error Define one of CFG_ENV_IS_IN_NVRAM, CFG_ENV_IS_IN_EEPROM, CFG_ENV_IS_IN_FLASH, CFG_ENV_IS_IN_DATAFLASH, CFG_ENV_IS_NOWHERE
#endif
#define XMK_STR(x) #x
diff -purN u-boot-1.0.0.orig/common/env_dataflash.c u-boot-1.0.0.test/common/env_dataflash.c
--- u-boot-1.0.0.orig/common/env_dataflash.c Thu Jan 1 01:00:00 1970
+++ u-boot-1.0.0.test/common/env_dataflash.c Fri Nov 7 15:53:35 2003
@@ -0,0 +1,104 @@
+/* LowLevel function for DataFlash environment support
+ * Author : Gilles Gastaldi (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
+
+#if defined(CFG_ENV_IS_IN_DATAFLASH) /* Environment is in DataFlash */
+
+#include
+#include
+#include
+#include
+#include
+
+env_t *env_ptr = NULL;
+
+char * env_name_spec = "dataflash";
+
+extern int read_dataflash (unsigned long addr, unsigned long size, char
+*result);
+extern int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
+ unsigned long size);
+extern int AT91F_DataflashInit (void);
+extern uchar default_environment[];
+/* extern int default_environment_size; */
+
+
+uchar env_get_char_spec (int index)
+{
+ uchar c;
+ read_dataflash (CFG_ENV_ADDR+index+offsetof(env_t,data),1,&c);
+ return (c);
+}
+
+void env_relocate_spec (void)
+{
+ read_dataflash (CFG_ENV_ADDR,CFG_ENV_SIZE,(uchar *)env_ptr);
+}
+
+int saveenv(void)
+{
+/* env must be copied to do not alter env structure in memory*/
+unsigned char temp[CFG_ENV_SIZE];
+int i;
+ memcpy(temp, env_ptr, CFG_ENV_SIZE);
+ return write_dataflash (CFG_ENV_ADDR, (unsigned long)temp, CFG_ENV_SIZE);
+}
+
+/************************************************************************
+ * Initialize Environment use
+ *
+ * We are still running from ROM, so data use is limited
+ * Use a (moderately small) buffer on the stack
+ */
+int env_init(void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ ulong crc, len, new;
+ unsigned off;
+ uchar buf[64];
+ if (gd->env_valid == 0){
+ AT91F_DataflashInit(); /* prepare for DATAFLASH read/write */
+
+ /* read old CRC */
+ read_dataflash (CFG_ENV_ADDR+offsetof(env_t,crc),sizeof(ulong),&crc);
+ new = 0;
+ len = ENV_SIZE;
+ off = offsetof(env_t,data);
+ while (len > 0) {
+ int n = (len > sizeof(buf)) ? sizeof(buf) : len;
+ read_dataflash (CFG_ENV_ADDR+off,n , buf);
+ new = crc32 (new, buf, n);
+ len -= n;
+ off += n;
+ }
+ if (crc == new) {
+ gd->env_addr = offsetof(env_t,data);
+ gd->env_valid = 1;
+ } else {
+ gd->env_addr = (ulong)&default_environment[0];
+ gd->env_valid = 0;
+ }
+ }
+
+ return (0);
+}
+
+#endif /* CFG_ENV_IS_IN_DATAFLASH */
diff -purN u-boot-1.0.0.orig/cpu/at91rm9200/at45.c u-boot-1.0.0.test/cpu/at91rm9200/at45.c
--- u-boot-1.0.0.orig/cpu/at91rm9200/at45.c Fri Jun 27 23:32:32 2003
+++ u-boot-1.0.0.test/cpu/at91rm9200/at45.c Fri Nov 7 15:47:52 2003
@@ -26,6 +26,7 @@
#include
#define SPI_CLK 5000000
+#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 */
@@ -145,10 +146,20 @@ AT91S_DataFlashStatus AT91F_DataFlashSen
/* fill the command buffer */
pDataFlash->pDataFlashDesc->command[0] = OpCode;
- 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;
+ 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;
@@ -230,6 +241,7 @@ AT91S_DataFlashStatus AT91F_DataFlashCon
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;
@@ -239,8 +251,9 @@ AT91S_DataFlashStatus AT91F_DataFlashCon
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(AT91F_DataFlashSendCommand (pDataFlash, DB_CONTINUOUS_ARRAY_READ, 8, src));
+ return(status);
}
@@ -259,13 +272,17 @@ AT91S_DataFlashStatus AT91F_DataFlashPag
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 */
- return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, 4, dest));
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, DB_PAGE_PGM_BUF1, cmdsize, dest));
}
@@ -282,14 +299,17 @@ AT91S_DataFlashStatus AT91F_MainMemoryTo
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;
-
- return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, 4, page*pDataFlash->pDevice->pages_size));
+ cmdsize = 4;
+ if (pDataFlash->pDevice->pages_number >= 16384)
+ cmdsize = 5;
+ return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, page*pDataFlash->pDevice->pages_size));
}
@@ -310,6 +330,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
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;
@@ -324,14 +345,25 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
/* Send first Write Command */
pDataFlash->pDataFlashDesc->command[0] = BufferCommand;
pDataFlash->pDataFlashDesc->command[1] = 0;
- pDataFlash->pDataFlashDesc->command[2] = (unsigned char)(((unsigned int)(bufferAddress & pDataFlash->pDevice->byte_mask)) >> 8) ;
- pDataFlash->pDataFlashDesc->command[3] = (unsigned char)((unsigned int)bufferAddress & 0x00FF) ;
-
+ 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 = 4 ;
+ pDataFlash->pDataFlashDesc->tx_cmd_size = cmdsize ;
pDataFlash->pDataFlashDesc->rx_cmd_pt = pDataFlash->pDataFlashDesc->command ;
- pDataFlash->pDataFlashDesc->rx_cmd_size = 4 ;
+ pDataFlash->pDataFlashDesc->rx_cmd_size = cmdsize ;
pDataFlash->pDataFlashDesc->rx_data_pt = dataBuffer ;
pDataFlash->pDataFlashDesc->tx_data_pt = dataBuffer ;
@@ -341,6 +373,51 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
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 */
@@ -355,6 +432,7 @@ AT91S_DataFlashStatus AT91F_WriteBufferT
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) &&
@@ -365,8 +443,11 @@ AT91S_DataFlashStatus AT91F_WriteBufferT
/* 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, 4, dest));
+ return(AT91F_DataFlashSendCommand (pDataFlash, BufferCommand, cmdsize, dest));
}
@@ -391,10 +472,19 @@ AT91S_DataFlashStatus AT91F_PartialPageW
/* Read the contents of the page in the Sram Buffer */
AT91F_MainMemoryToBufferTransfert(pDataFlash, DB_PAGE_2_BUF1_TRF, page);
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/*Update the SRAM buffer */
AT91F_DataFlashWriteBuffer(pDataFlash, DB_BUF1_WRITE, src, AdrInPage, size);
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+
+ 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)));
@@ -402,7 +492,7 @@ AT91S_DataFlashStatus AT91F_PartialPageW
/*------------------------------------------------------------------------------*/
-/* Function Name : AT91F_DataFlashWrite_Overloaded */
+/* Function Name : AT91F_DataFlashWrite */
/* Object : */
/* Input Parameters : <*src> = Source buffer */
/* : = dataflash adress */
@@ -415,6 +505,8 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
int size )
{
unsigned int length;
+ unsigned int page;
+ unsigned int status;
AT91F_SpiEnable(pDataFlash->pDevice->cs);
@@ -431,7 +523,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
if(!AT91F_PartialPageWrite(pDataFlash,src, dest, length))
return DATAFLASH_ERROR;
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/* Update size, source and destination pointers */
size -= length;
@@ -441,10 +533,21 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
while (( size - pDataFlash->pDevice->pages_size ) >= 0 ) {
/* program dataflash page */
- if(!AT91F_DataFlashPagePgmBuf(pDataFlash, src, dest, pDataFlash->pDevice->pages_size ))
+ 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, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
/* Update size, source and destination pointers */
size -= pDataFlash->pDevice->pages_size ;
@@ -458,7 +561,7 @@ AT91S_DataFlashStatus AT91F_DataFlashWri
if(!AT91F_PartialPageWrite(pDataFlash, src, dest, size) )
return DATAFLASH_ERROR;
- AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000);
+ AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY);
}
return DATAFLASH_OK;
}
@@ -480,13 +583,13 @@ int AT91F_DataFlashRead(
AT91F_SpiEnable(pDataFlash->pDevice->cs);
- if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+ if(AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
return -1;
while (size) {
SizeToRead = (size < 0x8000)? size:0x8000;
- if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, 1000) != DATAFLASH_OK)
+ if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK)
return -1;
if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK)
diff -purN u-boot-1.0.0.orig/drivers/dataflash.c u-boot-1.0.0.test/drivers/dataflash.c
--- u-boot-1.0.0.orig/drivers/dataflash.c Fri Jun 27 23:32:37 2003
+++ u-boot-1.0.0.test/drivers/dataflash.c Fri Nov 7 15:46:59 2003
@@ -31,22 +31,33 @@ int cs[][CFG_MAX_DATAFLASH_BANKS] = {
{CFG_DATAFLASH_LOGIC_ADDR_CS3, 3}
};
+/*define the area offsets*/
+dataflash_protect_t area_list[NB_DATAFLASH_AREA]={
+{0, 0x7fff, FLAG_PROTECT_SET}, /* ROM code */
+{0x8000, 0x1ffff, FLAG_PROTECT_SET}, /* u-boot code*/
+{0x20000, 0x27fff, FLAG_PROTECT_CLEAR}, /* u-boot environment */
+{0x28000, 0x1fffff, FLAG_PROTECT_CLEAR},/* data area size to tune */
+};
+
extern void AT91F_SpiInit (void);
extern int AT91F_DataflashProbe (int i, AT91PS_DataflashDesc pDesc);
extern int AT91F_DataFlashRead (AT91PS_DataFlash pDataFlash,
unsigned long addr,
unsigned long size, char *buffer);
-
+extern int AT91F_DataFlashWrite( AT91PS_DataFlash pDataFlash,
+ unsigned char *src,
+ int dest,
+ int size );
int AT91F_DataflashInit (void)
{
- int i, j;
+ int i,j;
int dfcode;
-
+
AT91F_SpiInit ();
for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
-
+ dataflash_info[i].Desc.state = IDLE;
dataflash_info[i].id = 0;
dataflash_info[i].Device.pages_number = 0;
dfcode = AT91F_DataflashProbe (cs[i][1], &dataflash_info[i].Desc);
@@ -84,22 +95,39 @@ int AT91F_DataflashInit (void)
dataflash_info[i].logical_address = cs[i][0];
dataflash_info[i].id = dfcode;
break;
+ case AT45DB128:
+ dataflash_info[i].Device.pages_number = 16384;
+ dataflash_info[i].Device.pages_size = 1056;
+ dataflash_info[i].Device.page_offset = 11;
+ dataflash_info[i].Device.byte_mask = 0x700;
+ dataflash_info[i].Device.cs = cs[i][1];
+ dataflash_info[i].Desc.DataFlash_state = IDLE;
+ dataflash_info[i].logical_address = cs[i][0];
+ dataflash_info[i].id = dfcode;
+ break;
default:
break;
}
-
- for (j = 0; j < dataflash_info[i].Device.pages_number; j++)
- dataflash_info[i].protect[j] = FLAG_PROTECT_SET;
-
- }
+ /* set the last area end to the dataflash size*/
+ area_list[NB_DATAFLASH_AREA -1].end =
+ (dataflash_info[i].Device.pages_number *
+ dataflash_info[i].Device.pages_size)-1;
+
+ /* set the area addresses */
+ for(j = 0; j (pdataFlash->pDevice->pages_size *
+ pdataFlash->pDevice->pages_number)) return 0;
+ /* is too large for the dataflash */
+ if (size > ((pdataFlash->pDevice->pages_size *
+ pdataFlash->pDevice->pages_number) - ((int)addr & 0x0FFFFFFF))) return 0;
+
+ return 1;
+}
+/*-----------------------------------------------------------------------------*/
+/* Function Name : prot_dataflash */
+/* Object : Test if destination area is protected */
+/*-----------------------------------------------------------------------------*/
+int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr)
+{
+int area;
+ /* find area */
+ for (area=0; area < NB_DATAFLASH_AREA; area++){
+ if ((addr >= pdataFlash->pDevice->area_list[area].start) &&
+ (addr < pdataFlash->pDevice->area_list[area].end))
+ break;
+ }
+ if (area == NB_DATAFLASH_AREA) return -1;
+ /*test protection value*/
+ if (pdataFlash->pDevice->area_list[area].protected == FLAG_PROTECT_SET) return 0;
+
+ return 1;
+}
+/*-----------------------------------------------------------------------------*/
+/* Function Name : dataflash_real_protect */
+/* Object : protect/unprotect area */
+/*-----------------------------------------------------------------------------*/
+int dataflash_real_protect (int flag, unsigned long start_addr, unsigned long end_addr)
+{
+int i,j, area1, area2, addr_valid = 0;
+ /* find dataflash */
+ for (i = 0; i < CFG_MAX_DATAFLASH_BANKS; i++) {
+ if ((((int) start_addr) & 0xF0000000) ==
+ dataflash_info[i].logical_address){
+ addr_valid = 1;
+ break;
+ }
+ }
+ if (!addr_valid) {
+ return -1;
+ }
+ /* find start area */
+ for (area1=0; area1 < NB_DATAFLASH_AREA; area1++){
+ if (start_addr == dataflash_info[i].Device.area_list[area1].start) break;
+ }
+ if (area1 == NB_DATAFLASH_AREA) return -1;
+ /* find end area */
+ for (area2=0; area2 < NB_DATAFLASH_AREA; area2++){
+ if (end_addr == dataflash_info[i].Device.area_list[area2].end) break;
+ }
+ if (area2 == NB_DATAFLASH_AREA) return -1;
+
+ /*set protection value*/
+ for(j = area1; j < area2+1 ; j++)
+ if (flag == 0) dataflash_info[i].Device.area_list[j].protected = FLAG_PROTECT_CLEAR;
+ else dataflash_info[i].Device.area_list[j].protected = FLAG_PROTECT_SET;
+
+ return (area2-area1+1);
+}
/*------------------------------------------------------------------------------*/
/* Function Name : read_dataflash */
@@ -187,10 +295,15 @@ int read_dataflash (unsigned long addr,
AT91PS_DataFlash pFlash = &DataFlashInst;
pFlash = AT91F_DataflashSelect (pFlash, &AddrToRead);
+
if (pFlash == 0)
- return -1;
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if (size_dataflash(pFlash,addr,size) == 0)
+ return ERR_INVAL;
return (AT91F_DataFlashRead (pFlash, AddrToRead, size, result));
+
}
@@ -201,17 +314,25 @@ int read_dataflash (unsigned long addr,
int write_dataflash (unsigned long addr_dest, unsigned long addr_src,
unsigned long size)
{
- extern AT91S_DataFlashStatus AT91F_DataFlashWrite(
- AT91PS_DataFlash, uchar *, int, int);
int AddrToWrite = addr_dest;
AT91PS_DataFlash pFlash = &DataFlashInst;
pFlash = AT91F_DataflashSelect (pFlash, &AddrToWrite);
+
+ if (pFlash == 0)
+ return ERR_UNKNOWN_FLASH_TYPE;
+
+ if (size_dataflash(pFlash,addr_dest,size) == 0)
+ return ERR_INVAL;
+
+ if (prot_dataflash(pFlash,addr_dest) == 0)
+ return ERR_PROTECTED;
+
if (AddrToWrite == -1)
return -1;
- return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite,
- size);
+ return AT91F_DataFlashWrite (pFlash, (char *) addr_src, AddrToWrite, size);
+
}
@@ -242,3 +363,4 @@ void dataflash_perror (int err)
}
#endif
+
diff -purN u-boot-1.0.0.orig/include/configs/at91rm9200dk.h u-boot-1.0.0.test/include/configs/at91rm9200dk.h
--- u-boot-1.0.0.orig/include/configs/at91rm9200dk.h Fri Jun 27 23:32:45 2003
+++ u-boot-1.0.0.test/include/configs/at91rm9200dk.h Fri Nov 7 20:09:16 2003
@@ -105,7 +105,7 @@
#define CONFIG_NET_RETRY_COUNT 20
#define CONFIG_HAS_DATAFLASH 1
-#define CFG_SPI_WRITE_TOUT CFG_HZ
+#define CFG_SPI_WRITE_TOUT (5*CFG_HZ)
#define CFG_MAX_DATAFLASH_BANKS 2
#define CFG_MAX_DATAFLASH_PAGES 16384
#define CFG_DATAFLASH_LOGIC_ADDR_CS0 0xC0000000 /* Logical adress for CS0 */
@@ -118,9 +118,20 @@
#define CFG_MAX_FLASH_SECT 40
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
+
+#undef CFG_ENV_IS_IN_DATAFLASH
+
+#ifdef CFG_ENV_IS_IN_DATAFLASH
+#define CFG_ENV_OFFSET 0x20000
+#define CFG_ENV_ADDR (CFG_DATAFLASH_LOGIC_ADDR_CS0 + CFG_ENV_OFFSET)
+#define CFG_ENV_SIZE 0x2000 /* 0x8000 */
+#else
#define CFG_ENV_IS_IN_FLASH 1
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0xe000) /* 0x10000 */
#define CFG_ENV_SIZE 0x2000 /* 0x8000 */
+#endif
+
+
#define CFG_LOAD_ADDR 0x21000000 /* default load address */
#define CFG_BOOT_SIZE 0x6000 /* 24 KBytes */
diff -purN u-boot-1.0.0.orig/include/dataflash.h u-boot-1.0.0.test/include/dataflash.h
--- u-boot-1.0.0.orig/include/dataflash.h Fri Jun 27 23:32:40 2003
+++ u-boot-1.0.0.test/include/dataflash.h Fri Nov 7 15:46:59 2003
@@ -37,16 +37,15 @@
#include
#include "config.h"
+/*number of protected area*/
+#define NB_DATAFLASH_AREA 4
+/*define the area structure*/
typedef struct {
- unsigned long base; /* logical base address for a bank */
- unsigned long size; /* total bank size */
- unsigned long page_count;
- unsigned long page_size;
- unsigned long id; /* device id */
- unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
-} dataflash_info_t;
-
+ unsigned long start;
+ unsigned long end;
+ unsigned char protected;
+} dataflash_protect_t;
typedef unsigned int AT91S_DataFlashStatus;
@@ -80,6 +79,7 @@ typedef struct _AT91S_Dataflash {
int page_offset; /* page offset in command */
int byte_mask; /* byte mask in command */
int cs;
+ dataflash_protect_t area_list[NB_DATAFLASH_AREA]; /* area protection status */
} AT91S_DataflashFeatures, *AT91PS_DataflashFeatures;
/*---------------------------------------------*/
@@ -91,13 +91,13 @@ typedef struct _AT91S_DataFlash {
} AT91S_DataFlash, *AT91PS_DataFlash;
+
typedef struct _AT91S_DATAFLASH_INFO {
AT91S_DataflashDesc Desc;
AT91S_DataflashFeatures Device; /* Pointer on a dataflash features array */
unsigned long logical_address;
unsigned int id; /* device id */
- unsigned char protect[CFG_MAX_DATAFLASH_PAGES]; /* page protection status */
} AT91S_DATAFLASH_INFO, *AT91PS_DATAFLASH_INFO;
@@ -106,6 +106,7 @@ typedef struct _AT91S_DATAFLASH_INFO {
#define AT45DB161 0x2c
#define AT45DB321 0x34
#define AT45DB642 0x3c
+#define AT45DB128 0x10
#define AT91C_DATAFLASH_TIMEOUT 10000 /* For AT91F_DataFlashWaitReady */
@@ -166,6 +167,9 @@ typedef struct _AT91S_DATAFLASH_INFO {
/*-------------------------------------------------------------------------------------------------*/
+extern int size_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr, unsigned long size);
+extern int prot_dataflash (AT91PS_DataFlash pdataFlash, unsigned long addr);
+extern int dataflash_real_protect (int flag, unsigned long start_addr, unsigned long end_addr);
extern int addr_dataflash (unsigned long addr);
extern int read_dataflash (unsigned long addr, unsigned long size, char *result);
extern int write_dataflash (unsigned long addr, unsigned long dest, unsigned long size);