Re: [U-Boot-Users] AT91 NAND om AT91SAM9260EK

Hej,
Has anyone used the at91_nand driver on the AT91SAM9260EK?
I get bad erase blocks on every block that contaions data (written to nand flash with SAM-BA). Seems like the read_oob (read out of bounds area) function is returning data from the in bounds area.
U-boot configs the nand flash to use hw ecc (syndrome) whereas the at91_nand seems to be setup to use soft ecc.
According to recent conversations on U-Boot mailing list U-boot can do a raw copy of a flash file system, but nothing more. (Correct me if I have misunderstood)
This means that if there are faulty pages in the NAND flash, you are dead. U-Boot needs to be able to map out JFFS2 or YAFFS(2) to be useful here. I.E. NAND flash is not functional as a boot memory yet.
If I understand correctly, you can read a JFFS2 fs in U-Boot
With the SAM9260, you can boot from an external dataflash card, containing Linux and a small file system. When this has booted, I think you can create a JFFS2 file system on the NAND flash. This should contain the Linux image as well.
U-Boot should then after reset, be able to read the linux from the JFFS2 file system and then boot.
I do not know if U-boot can fit into the NAND flash and I have not tested anything of above, but I think it should work. The programming time of the system will of course be significant, since you have to test the NAND flash for bad sectors..
If anyone has been down this path before, I would appreciate any pointers or assistance you can provide.
Michel
List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Best Regards Ulf Samuelsson

On Thursday 08 February 2007 00:17, Ulf Samuelsson wrote:
Has anyone used the at91_nand driver on the AT91SAM9260EK?
I get bad erase blocks on every block that contaions data (written to nand flash with SAM-BA). Seems like the read_oob (read out of bounds area) function is returning data from the in bounds area.
U-boot configs the nand flash to use hw ecc (syndrome) whereas the at91_nand seems to be setup to use soft ecc.
According to recent conversations on U-Boot mailing list U-boot can do a raw copy of a flash file system, but nothing more. (Correct me if I have misunderstood)
Yes. But this copy is bad block aware.
This means that if there are faulty pages in the NAND flash, you are dead.
No. Bad blocks are handled correctly.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk Office: Kirchenstr. 5, D-82194 Groebenzell, Germany =====================================================================

Good morning!
What version of the AT91SAM9260EK u-boot code are you referring to?
I am using u-boot-1.1.5_atmel_1.2 from the Atmel ftp site. Is there a more recent version available? Are there any plans to add the at91sam9260ek support to the main branch of u-boot (latest version 1.2).
In looking through the 1.1.5 Atmel u-boot code I see that nand_bbt.c is used to map out bad blocks marked by the manufacturer. I can write my code to nand from external SAM-BA tool and boot without any problems. Has anyone tried booting from JFFS2 nand within u-boot?
The problem that I was having with the NAND flash on my AT91SAM9260EK board is related to the fact that the hw ECC controller in the 9260 uses the first four bytes of out of bounds space after each page to store an error correction/verification number. The Samsung flash on my board uses the first byte of oob space in the first two pages of a block to mark that it is bad. If the byte is not FF then the mfg has marked the block as bad and it should never be used. When linux mtd starts up it looks for mfg bad blocks and removes them from the available list of nand blocks. Thus any page which contains data is excluded. Looking around at other nand flash devices I found that some use both offsets 0 and 5 in the oob space to mark bad blocks. We plan to use such a nand flash on our custom board. I hope that Atmel will do the same on future revisions of its AT91SAM9260EK board.
My work around for now is to ignore mfg bad blocks and hope that they get caught by the ECC verification code. Mfg bad block info has already been overwritten on my flash chip by the ECC data. Does anyone know if the Atmel SAMBA tool does any bad block verification when programming nand flash? It seems to be writing the 4 byte ECC code in the oob space. Is it also marking mfg bad blocks? If so, at which offset into the oob space?
Michel
On 2/8/07, Stefan Roese sr@denx.de wrote:
On Thursday 08 February 2007 00:17, Ulf Samuelsson wrote:
Has anyone used the at91_nand driver on the AT91SAM9260EK?
I get bad erase blocks on every block that contaions data (written to nand flash with SAM-BA). Seems like the read_oob (read out of bounds area) function is returning data from the in bounds area.
U-boot configs the nand flash to use hw ecc (syndrome) whereas the at91_nand seems to be setup to use soft ecc.
According to recent conversations on U-Boot mailing list U-boot can do a raw copy of a flash file system, but nothing more. (Correct me if I have misunderstood)
Yes. But this copy is bad block aware.
This means that if there are faulty pages in the NAND flash, you are dead.
No. Bad blocks are handled correctly.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk Office: Kirchenstr. 5, D-82194 Groebenzell, Germany =====================================================================

Michel Benoit skrev:
Good morning!
What version of the AT91SAM9260EK u-boot code are you referring to?
I am using u-boot-1.1.5_atmel_1.2 from the Atmel ftp site. Is there a more recent version available? Are there any plans to add the at91sam9260ek support to the main branch of u-boot (latest version 1.2).
The Atmel U-Boot for the AT91SAM9260/1/3 chips uses a common driver for dataflash. This is located in the "drivers/at45.c" If the Atmel U-boot patches are installed, it will break the "board/at91rm9200dk" and "board/cmc_pu2" since it duplicates the functionality. Additional boards coming from Atmel will use the same dataflash driver. The "board/at91rm9200dk/at45.c" functionality is split into a CPU dependent part located in "cpu/arm926ejs/at91sam926x/spi.c" and the "board/at45.c" file.
I tried to start the process of merging with mainstream U-boot by sending in a patch which split the at45.c located in board/at91rm9200dk into * drivers/at45.c * cpu/arm920t/at91rm9200/spi.c but I have no feedback.
Peter Pearse which will be responsible for maintaining the ARM part is not up to speed yet, and noone else seems to be interested.
There has been a discussion about how dataflash should be supported but the things people do not like are not in this file, they are in the "board/dataflash.c" file so I have no clue why nothing is happening.

On 2/8/07, Ulf Samuelsson ulf@atmel.com wrote:
Additional boards coming from Atmel will use the same dataflash driver.
Hopefully including any AVR32 boards featuring DataFlash.
The "board/at91rm9200dk/at45.c" functionality is split into a CPU dependent part located in "cpu/arm926ejs/at91sam926x/spi.c" and the "board/at45.c" file.
I tried to start the process of merging with mainstream U-boot by sending in a patch which split the at45.c located in board/at91rm9200dk into
- drivers/at45.c
- cpu/arm920t/at91rm9200/spi.c
Any chance the SPI driver could move into drivers/ as well? The at32ap7000 has pretty much the same SPI hardware built in, and IMO there shouldn't really be anything chip-specific about it apart from pin configuration, register base address and interrupt line (if it even uses that.)
I'm willing to review the driver if you send it inline as a single patch, and perhaps help you clean it up as well, if needed. Please Cc hskinnemoen@atmel.com so I receive it in my mail client at work.
There has been a discussion about how dataflash should be supported but the things people do not like are not in this file, they are in the "board/dataflash.c" file so I have no clue why nothing is happening.
It could have something to do with the tarball submission format not being particularly reviewer-friendly...
Haavard

Haavard Skinnemoen skrev:
On 2/8/07, Ulf Samuelsson ulf@atmel.com wrote:
Additional boards coming from Atmel will use the same dataflash driver.
Hopefully including any AVR32 boards featuring DataFlash.
The "board/at91rm9200dk/at45.c" functionality is split into a CPU dependent part located in "cpu/arm926ejs/at91sam926x/spi.c" and the "board/at45.c" file.
I tried to start the process of merging with mainstream U-boot by sending in a patch which split the at45.c located in board/at91rm9200dk into
- drivers/at45.c
- cpu/arm920t/at91rm9200/spi.c
Any chance the SPI driver could move into drivers/ as well? The at32ap7000 has pretty much the same SPI hardware built in, and IMO there shouldn't really be anything chip-specific about it apart from pin configuration, register base address and interrupt line (if it even uses that.)
I'm willing to review the driver if you send it inline as a single patch, and perhaps help you clean it up as well, if needed. Please Cc hskinnemoen@atmel.com so I receive it in my mail client at work.
There has been a discussion about how dataflash should be supported but the things people do not like are not in this file, they are in the "board/dataflash.c" file so I have no clue why nothing is happening.
It could have something to do with the tarball submission format not being particularly reviewer-friendly...
Haavard
Here is it again, was not sent as a tarball, but as an attachement. This was a patchset of three patches, the remaining two patches just removes "board/at91rm9200dk/at45.c" and "board/cmc_pu2/at45.c" They are not used any longer.
I do think that it is better to submit the AT91SAM9 patches first and only then create a common driver.
------------------------------------------------------------- DESCRIPTION
The at45.c dataflash driver is currently duplicated in * board/at91rm9200dk * board/cmc_pu2
This patch splits the at45 dataflash driver into a * cpu-dependent part located in cpu/arm920t/at91rm9200 * cpu-independent part located in drivers/at45.c
making AT45 Dataflash available to all boards with an appropriate SPI driver.
All new AT91 boards use this driver, so if/when patches for these boards are accepted into mainline, having a common driver will reduce the size of the U-boot source and make the board support more maintainable.
The "drivers/at45.c" is compiled for all boards but contain a configuration test: #ifdef CONFIG_HAS_DATAFLASH ... #endif around the code, so if this is not set, the at45 driver will not add code to the system.
------ The current at45.c contains both the cpu specific spi access routines and a higher layer dataflash access routine which calls the lower layer spi routines to read/write dataflash.
To make the at45 independent on the CPU, the spi layer has been removed from the driver and placed in the cpu/arm920t/at91rm9200/spi.c. CPU specific "includes" are moved inside the CONFIG_HAS_DATAFLASH test
Makefile changes
at45.o has been removed from the Makefiles in * "board/at91rm9200dk" * "board/cmc_pu2"
at45.o has been added to the "drivers" Makefile. spi.o has been added to "cpu/arm920t/at91rm9200/Makefile"
------------------------------------------------------------- CHANGELOG: Author: Ulf Samuelsson <ulf <at> atmel.com> Date: Thu Feb 1 21:18:53 CET 2007
Make at45 driver available to all boards. Move SPI low level part to cpu/arm920t/at91rm9200
------------------------------------------------------------- No new configuration options ------------------------------------------------------------- Patch: Attached in plaintext Consists of three parts. 1. Split and move 2. Removal of at45.c from board/at91rm9200dk 3. Removal of at45.c from board/cmc_pu2
------------------------------------------------------------- Patch generated by diff -purN \ u-boot-2007-02-01-0rig \ u-boot-2007-02-01 > \ u-boot-2007-02-01-at45_split.1_3.patch from the parent directory ------------------------------------------------------------- Tested on PPC and ARM
diff -purN u-boot-2007-02-01-0rig/board/at91rm9200dk/Makefile u-boot-2007-02-01/board/at91rm9200dk/Makefile --- u-boot-2007-02-01-0rig/board/at91rm9200dk/Makefile 2007-02-01 20:18:38.000000000 +0100 +++ u-boot-2007-02-01/board/at91rm9200dk/Makefile 2007-02-01 20:43:49.000000000 +0100 @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := at91rm9200dk.o at45.o flash.o +COBJS := at91rm9200dk.o flash.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff -purN u-boot-2007-02-01-0rig/board/cmc_pu2/Makefile u-boot-2007-02-01/board/cmc_pu2/Makefile --- u-boot-2007-02-01-0rig/board/cmc_pu2/Makefile 2007-02-01 20:23:23.000000000 +0100 +++ u-boot-2007-02-01/board/cmc_pu2/Makefile 2007-02-01 20:44:27.000000000 +0100 @@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(BOARD).a
-COBJS := cmc_pu2.o at45.o flash.o load_sernum_ethaddr.o +COBJS := cmc_pu2.o flash.o load_sernum_ethaddr.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff -purN u-boot-2007-02-01-0rig/cpu/arm920t/at91rm9200/Makefile u-boot-2007-02-01/cpu/arm920t/at91rm9200/Makefile --- u-boot-2007-02-01-0rig/cpu/arm920t/at91rm9200/Makefile 2007-02-01 20:18:49.000000000 +0100 +++ u-boot-2007-02-01/cpu/arm920t/at91rm9200/Makefile 2007-02-01 20:42:50.000000000 +0100 @@ -26,7 +26,7 @@ include $(TOPDIR)/config.mk LIB = $(obj)lib$(SOC).a
COBJS = bcm5221.o dm9161.o ether.o i2c.o interrupts.o \ - lxt972.o serial.o usb_ohci.o + lxt972.o serial.o spi.o usb_ohci.o SOBJS = lowlevel_init.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) diff -purN u-boot-2007-02-01-0rig/cpu/arm920t/at91rm9200/spi.c u-boot-2007-02-01/cpu/arm920t/at91rm9200/spi.c --- u-boot-2007-02-01-0rig/cpu/arm920t/at91rm9200/spi.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-2007-02-01/cpu/arm920t/at91rm9200/spi.c 2007-02-01 20:27:37.000000000 +0100 @@ -0,0 +1,136 @@ +/* Driver for ATMEL SPI 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> + +#ifdef CONFIG_HAS_DATAFLASH +#include <common.h> +#include <asm/hardware.h> +#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; +} +#endif diff -purN u-boot-2007-02-01-0rig/drivers/at45.c u-boot-2007-02-01/drivers/at45.c --- u-boot-2007-02-01-0rig/drivers/at45.c 1970-01-01 01:00:00.000000000 +0100 +++ u-boot-2007-02-01/drivers/at45.c 2007-02-01 20:34:34.000000000 +0100 @@ -0,0 +1,515 @@ +/* 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> + +#ifdef CONFIG_HAS_DATAFLASH +#include <asm/hardware.h> +#include <dataflash.h> + + +#define AT91C_TIMEOUT_WRDY 200000 + + +/*----------------------------------------------------------------------*/ +/* \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))
- ;
+ 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))
- ;
+ 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, (uchar *)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 -purN u-boot-2007-02-01-0rig/drivers/Makefile u-boot-2007-02-01/drivers/Makefile --- u-boot-2007-02-01-0rig/drivers/Makefile 2007-02-01 20:18:50.000000000 +0100 +++ u-boot-2007-02-01/drivers/Makefile 2007-02-01 20:28:50.000000000 +0100 @@ -27,7 +27,7 @@ include $(TOPDIR)/config.mk
LIB = $(obj)libdrivers.a
-COBJS = 3c589.o 5701rls.o ali512x.o atmel_usart.o \ +COBJS = 3c589.o 5701rls.o ali512x.o at45.o atmel_usart.o \ bcm570x.o bcm570x_autoneg.o cfb_console.o cfi_flash.o \ cs8900.o ct69000.o dataflash.o dc2114x.o dm9000x.o \ e1000.o eepro100.o \

On Thu, 08 Feb 2007 23:20:55 +0100 Ulf Samuelsson ulf@atmel.com wrote:
Here is it again, was not sent as a tarball, but as an attachement. This was a patchset of three patches, the remaining two patches just removes "board/at91rm9200dk/at45.c" and "board/cmc_pu2/at45.c" They are not used any longer.
Thanks. When I replied last time, I thought for some reason that this was a new driver even though I knew perfectly well it isn't. Anyway, I guess it makes the review process slightly different...
I think the best way forward is probably to first get rid of the duplication by moving everything as-is into drivers. That way, there's only a single driver to clean up, not two.
I suggest we try to create a patch series doing the following: 1. Eliminate any differences between the two at45.c drivers 2. Consolidate the two drivers into drivers/at45.c 3. Do a codingstyle cleanup of drivers/at45.c 4. Split out the SPI part into a separate driver 5. Make everything portable. This includes getting rid of all the AT91FOO prefixing. <insert additional cleanup steps here>
Wolfgang, does this sound like a good plan to you?
Step #1 is easy:
$ diff -up board/cmc_pu2/at45.c board/at91rm9200dk/at45.c --- board/cmc_pu2/at45.c 2006-08-30 21:53:30.000000000 +0200 +++ board/at91rm9200dk/at45.c 2006-08-30 21:53:30.000000000 +0200 @@ -593,7 +593,7 @@ int AT91F_DataFlashRead( if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK) return -1;
- if (AT91F_DataFlashContinuousRead (pDataFlash, addr, buffer, SizeToRead) != DATAFLASH_OK) + if (AT91F_DataFlashContinuousRead (pDataFlash, addr, (uchar *)buffer, SizeToRead) != DATAFLASH_OK) return -1;
size -= SizeToRead;
We'll just have to decide whether or not to keep the cast. buffer is a char * anyway, so I don't think it makes any difference at all.
Step #2 will probably generate an oversize patch unless we do it as a git patch, which will basically just boil down to a rename and a deletion (where the deletion will be the biggest part, but still under 40KB I hope.)
Step #3 is where the fun begins...
I have a prototype board with DataFlash for ATSTK1000, so I can start testing on AVR32 around step #5. Before that, I'd appreciate some help testing the individual patches (I can do build testing on ARM though.)
I do think that it is better to submit the AT91SAM9 patches first and only then create a common driver.
If the AT91SAM9 patches include another at45.c driver, I disagree. Better consolidate first and add new stuff on top of that. But the driver should be usable for new boards after step #2, so you probably don't have to wait very long before you can start submitting the SAM stuff.
Btw, Wolfgang: I'd really appreciate if you could pull the avr32 update from last november (which I rebased and resent last week):
git://www.atmel.no/~hskinnemoen/u-boot/avr32.git for-wolfgang
It will be a lot easier to support avr32 with a single, unified at45 driver if those changes are in mainline. They simplify much of the portmux- clock- and I/O management code, thus making it easier to see what it takes to make the at45 and spi drivers portable across ARM and AVR32.
Besides, you were the one who specifically asked me to add relocation support, which is what the update is really all about...
Haavard

Here is it again, was not sent as a tarball, but as an attachement. This was a patchset of three patches, the remaining two patches just removes "board/at91rm9200dk/at45.c" and "board/cmc_pu2/at45.c" They are not used any longer.
Thanks. When I replied last time, I thought for some reason that this was a new driver even though I knew perfectly well it isn't. Anyway, I guess it makes the review process slightly different...
I think the best way forward is probably to first get rid of the duplication by moving everything as-is into drivers. That way, there's only a single driver to clean up, not two.
I suggest we try to create a patch series doing the following:
- Eliminate any differences between the two at45.c drivers
- Consolidate the two drivers into drivers/at45.c
- Do a codingstyle cleanup of drivers/at45.c
- Split out the SPI part into a separate driver
- Make everything portable. This includes getting rid of all the AT91FOO prefixing.
<insert additional cleanup steps here>
My priority is to have AT91SAM9x support inside U-Boot ASAP. This approach creates all kinds of unneccessary critical paths which will delay this
I would like to see the following atpproach.
1) at45_split is applied splitting into cpu independent part and cpu dependent part. the drivers/at45.c is siglty modified to handle at91rm9200dk and cmc_pu2 boards as well as the at91sam926xek boards 2) cpu/arm926ejs/at91sam926x AT91SAM9 support This has an spi.c which is different from 3) board patches applied board/at91sam9260ek board/at91sam9261ek board/at91sam9263ek board/at91rm9200ek board/at91rm9200df drivers/dataflash.c update to support linux-2.6 instead of linux-2.4
After that is in place, then it is time for your proposal.
1) Do a codingstyle cleanup of drivers/at45.c 2) Make everything portable. This includes getting rid of all the AT91FOO prefixing.
If we follow your approach, then the at91sam926x SPI support has first to be inserted into at45.c and retested only to be split up at a later stage.
Wolfgang, does this sound like a good plan to you?
Step #1 is easy:
$ diff -up board/cmc_pu2/at45.c board/at91rm9200dk/at45.c --- board/cmc_pu2/at45.c 2006-08-30 21:53:30.000000000 +0200 +++ board/at91rm9200dk/at45.c 2006-08-30 21:53:30.000000000 +0200 @@ -593,7 +593,7 @@ int AT91F_DataFlashRead( if (AT91F_DataFlashWaitReady(pDataFlash->pDataFlashDesc, AT91C_TIMEOUT_WRDY) != DATAFLASH_OK) return -1;
if (AT91F_DataFlashContinuousRead (pDataFlash, addr,
buffer, SizeToRead) != DATAFLASH_OK)
if (AT91F_DataFlashContinuousRead (pDataFlash, addr,
(uchar *)buffer, SizeToRead) != DATAFLASH_OK) return -1;
size -= SizeToRead;
We'll just have to decide whether or not to keep the cast. buffer is a char * anyway, so I don't think it makes any difference at all.
Step #2 will probably generate an oversize patch unless we do it as a git patch, which will basically just boil down to a rename and a deletion (where the deletion will be the biggest part, but still under 40KB I hope.)
Step #3 is where the fun begins...
I have a prototype board with DataFlash for ATSTK1000, so I can start testing on AVR32 around step #5. Before that, I'd appreciate some help testing the individual patches (I can do build testing on ARM though.)
I do not see anyone from the AT91 team participating in this effort right now, and that is why I think we should apply *tested* code to establish a base which is useful to at91sam9 users.
I do think that it is better to submit the AT91SAM9 patches first and only then create a common driver.
If the AT91SAM9 patches include another at45.c driver, I disagree.
The at91sam9 patchset has a board/at45.c and it is this that is available in in the "at45_split" patch. If at91_split is applied there will be no modification of this file when the at91sam9 patchset is submitted.
Better consolidate first and add new stuff on top of that. But the driver should be usable for new boards after step #2, so you probably don't have to wait very long before you can start submitting the SAM stuff.
the spi.c is very small and msot of the code relies on the pin multiplexing of the part. This is why I think it may make little sense to have a common driver.
Btw, Wolfgang: I'd really appreciate if you could pull the avr32 update from last november (which I rebased and resent last week):
git://www.atmel.no/~hskinnemoen/u-boot/avr32.git for-wolfgang
It will be a lot easier to support avr32 with a single, unified at45 driver if those changes are in mainline. They simplify much of the portmux- clock- and I/O management code, thus making it easier to see what it takes to make the at45 and spi drivers portable across ARM and AVR32.
Besides, you were the one who specifically asked me to add relocation support, which is what the update is really all about...
Haavard
Best Regards Ulf Samuelsson ulf@atmel.com Atmel Nordic AB Mail: Box 2033, 174 02 Sundbyberg, Sweden Visit: Kavallerivägen 24, 174 58 Sundbyberg, Sweden Phone +46 (8) 441 54 22 Fax +46 (8) 441 54 29 GSM +46 (706) 22 44 57
Technical support when I am not available: AT89 C51 Applications Group: mailto:micro.hotline@nto.atmel.com AT90 AVR Applications Group: mailto:avr@atmel.com AT91 ARM Applications Group: mailto:at91support@atmel.com FPSLIC Application Group: mailto:fpslic@atmel.com Best AVR

On 2/9/07, Ulf Samuelsson ulf@atmel.com wrote:
I suggest we try to create a patch series doing the following:
- Eliminate any differences between the two at45.c drivers
- Consolidate the two drivers into drivers/at45.c
- Do a codingstyle cleanup of drivers/at45.c
- Split out the SPI part into a separate driver
- Make everything portable. This includes getting rid of all the AT91FOO prefixing.
<insert additional cleanup steps here>
My priority is to have AT91SAM9x support inside U-Boot ASAP. This approach creates all kinds of unneccessary critical paths which will delay this
Hmm...at first I thought you disagreed with the whole approach, but I think what you _really_ disagree with is the ordering of step 3 and 4. I have no problem with doing these steps the other way around.
I would like to see the following atpproach.
- at45_split is applied splitting into cpu independent part and cpu dependent part. the drivers/at45.c is siglty modified to handle at91rm9200dk and cmc_pu2 boards as well as the at91sam926xek boards
The problem with your patchset is that it first creates a _third_ identical driver before removing the other two. I think it would be cleaner to consolidate the existing two first, and it's not even a big deal -- if it still builds after the move, it works because the code will be the same.
After we then split out the spi part, you can apply your at91sam926 stuff on top of that. This will hopefully be a very small patch.
Btw, why is at45.c going to be modified? It already supports both at91rm9200dk and cmc_pu2. The differences are minimal and purely cosmetic.
- cpu/arm926ejs/at91sam926x AT91SAM9 support This has an spi.c which is different from
Different from what? AFAIK the hardware is the same as on AT91RM9200 and AT32AP7000 modulo a couple of extra features which probably aren't useful to u-boot.
If you're talking about the port muxing, I think it's _really_ overkill to add a new driver for each mux configuration. Maybe it would be better not to split it spi vs. dataflash, but rather "chip-dependent stuff like port muxing" vs. "chip-independent driver code"?
- board patches applied board/at91sam9260ek board/at91sam9261ek board/at91sam9263ek board/at91rm9200ek board/at91rm9200df drivers/dataflash.c update to support linux-2.6 instead of linux-2.4
After that is in place, then it is time for your proposal.
Fine. If it will give us more at91 testers, I'm all for it.
- Do a codingstyle cleanup of drivers/at45.c
- Make everything portable. This includes getting rid of all the AT91FOO prefixing.
If we follow your approach, then the at91sam926x SPI support has first to be inserted into at45.c and retested only to be split up at a later stage.
We can do the spi split before the code cleanup if that helps. But I can't help but think that a per-chip spi driver is mighty strange...
I do not see anyone from the AT91 team participating in this effort right now, and that is why I think we should apply *tested* code to establish a base which is useful to at91sam9 users.
Good point. But code that can't be changed because it's been tested once and for all is going to suck in the long term.
I do think that it is better to submit the AT91SAM9 patches first and only then create a common driver.
If the AT91SAM9 patches include another at45.c driver, I disagree.
The at91sam9 patchset has a board/at45.c and it is this that is available in in the "at45_split" patch.
What's the difference between this driver and the existing two?
If at91_split is applied there will be no modification of this file when the at91sam9 patchset is submitted.
That's good.
Better consolidate first and add new stuff on top of that. But the driver should be usable for new boards after step #2, so you probably don't have to wait very long before you can start submitting the SAM stuff.
the spi.c is very small and msot of the code relies on the pin multiplexing of the part. This is why I think it may make little sense to have a common driver.
This is why I think it isn't the spi stuff that ought to get split out -- it's the pin multiplexing stuff. Maybe it makes sense to split out the spi stuff as well, if it could have other uses beyond dataflash. In fact, the STK1000 has an LCD panel which is powered on using SPI, so a generic spi driver would be nice if we're going to support boot logo on this board later.
Haavard

In message 20070209164520.68b3980c@dhcp-252-105.norway.atmel.com you wrote:
I suggest we try to create a patch series doing the following:
- Eliminate any differences between the two at45.c drivers
- Consolidate the two drivers into drivers/at45.c
- Do a codingstyle cleanup of drivers/at45.c
- Split out the SPI part into a separate driver
- Make everything portable. This includes getting rid of all the AT91FOO prefixing.
<insert additional cleanup steps here>
Wolfgang, does this sound like a good plan to you?
Yes, it does.
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
Best regards,
Wolfgang Denk

link: www.avrfreaks.net ----- Original Message ----- From: "Wolfgang Denk" wd@denx.de To: "Haavard Skinnemoen" hskinnemoen@atmel.com Cc: "Ulf Samuelsson" ulf@atmel.com; u-boot-users@lists.sourceforge.net Sent: Friday, February 09, 2007 8:39 PM Subject: Re: [U-Boot-Users] AT91 NAND om AT91SAM9260EK
In message 20070209164520.68b3980c@dhcp-252-105.norway.atmel.com you wrote:
I suggest we try to create a patch series doing the following:
- Eliminate any differences between the two at45.c drivers
- Consolidate the two drivers into drivers/at45.c
- Do a codingstyle cleanup of drivers/at45.c
- Split out the SPI part into a separate driver
- Make everything portable. This includes getting rid of all the AT91FOO prefixing.
<insert additional cleanup steps here>
Wolfgang, does this sound like a good plan to you?
Yes, it does.
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
Best regards,
I think at45.c is CPU independent, but spi.c is closely tied to Atmel processors. spi.c consist of:
SpiInit - Clearly CPU dependent due to pin mux. Only reason that sam926x chips can use a common file is the #ifdefs...
SpiEnable - Configure the chip select. - Not generic only useable w Atmel SPI SpiDisable,SpiEnable: both these start PDC (DMA) transfers. SpiWrite: - Initializes the PDC (DMA) for the SPI macro. It sometimes reads the dataflash as a side effect.
--------------- at45.c contains commands which are specific to the at45 series of dataflash. In order to access the functionality of the at45 chips you have to send commands over the SPI.
Typically you prepare a descriptor which then calls the SPI driver. Low level commands are * send command * get status * wait until ready
High level commands are: * Continous read * Program flash from internal at45 SRAM buffer * Transfer from SDRAM to internal SRAM buffer * Write data to internal at45 SRAM buffer * Page Erase * Block Erase * Read internal at45 SRAM buffer to SDRAM * Partial Page Write * Page Write * Read Dataflash * Probe Dataflash You could conceivably use a different SPI flash, I.E. AT26xxx, and this family of chips would require another driver
--------------- drivers/dataflash.c
This file initializes the SPI and probes the SPI bus for precense of dataflash chips. It determines which type of dataflash chip, and stores this info in a table allowing printing out this later.
The dataflash is divided into several partitions which can be independently protected. A table defines the partition sizes
The AT91F_DataflashSelect function will map a physical address to a chip select using a mapping table. When fed an address, the function will scan this table until a match is found.
You can check if an address is inside the dataflash memory map. You can check if a memory block is completely inisde the dataflash.
You can check if a memory area is protected, and you can protect and unprotect the memory area.
The read routine will do error checks, assert the chip select and then read the dataflash using access routines in at45.c
The write routine will do similar things for writing dataflash
At the end there is an error routine.
Everything Wolfgang dislikes about dataflash (memory mapping) is either in the memory commands in the common directory or in the dataflash.c file.
The sam926x patches will need to update the dataflash.c because most boards will either support one chip select or two chipselects and this information needs to be there for new boards.
It will not change any of the access routines used to implement memory mapping. That is why I think the sam926x patches can be applied even though people now question the implementation.
=====================================================
While the functions in at45.c are called AT91xxx they really do not depend on any specific SPI H/W and it can thus be used with any chip which implements the SPI API defined by cpu/arm920t/at91rm9200/spi.c
If you let it remain in the board directories as is, then you duplicate this for each board.
I think a good place for any driver stuff which is useable both by at91 and ap7xxx chips could be an board/atmel/drivers directory. An alternative would be a cpu/atmel/drivers directory.
I do not think it belongs inside the drivers directory. By putting spi.c in drivers you have to be really careful not to compile this for chips which does not have this SPI macro.
The cpu/arm920t/at91rm9200/spi.c should at least contain the spi init.
I still would like to have the complete sam926x patch set implemented before we start to "play" with it
Best Regards Ulf Samuelsson

On 2/9/07, Ulf Samuelsson ulf@atmel.com wrote:
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
It's somewhat cpu- and board-independent. at32 and at91 are based on two different architectures, so they don't have any directories in common apart from the ones common to everyone.
We could perhaps create a drivers/atmel subdirectory or, as Ulf suggests, boards/atmel/drivers or cpu/atmel/drivers.
I think at45.c is CPU independent, but spi.c is closely tied to Atmel processors. spi.c consist of:
SpiInit - Clearly CPU dependent due to pin mux. Only reason that sam926x chips can use a common file is the #ifdefs...
Hmm...how about moving the cpu-dependent bits into inline functions somewhere under asm/arch? For example
static inline void portmux_enable_spi(unsigned int id) { /* do chip-dependent PIO stuff here */ }
asm/arch is chip-specific so there shouldn't be any need for #ifdefs there.
While the functions in at45.c are called AT91xxx they really do not depend on any specific SPI H/W and it can thus be used with any chip which implements the SPI API defined by cpu/arm920t/at91rm9200/spi.c
Yeah, that's why the AT91 prefixing should be dropped. But that's for much later.
Btw, looks like there's another SPI API in u-boot as well. Probably a good idea to convert the at91/atmel spi stuff over to implementing that one. No point in having several APIs doing the same thing, and the other API uses the much more sensible function name spi_xfer for doing SPI transfers, as opposed to AT91F_SpiWrite which is totally misleading since it's being used for reading as well.
If you let it remain in the board directories as is, then you duplicate this for each board.
I don't think anyone wants that. Although you're the one suggesting we add a _third_ identical driver ;-)
I think a good place for any driver stuff which is useable both by at91 and ap7xxx chips could be an board/atmel/drivers directory. An alternative would be a cpu/atmel/drivers directory.
Are any other drivers organized this way?
I do not think it belongs inside the drivers directory.
I'm sorry but I fail to see why not. There are several other platform-specific drivers in there. And I don't really see the big advantage of spreading drivers around all over the place...
By putting spi.c in drivers you have to be really careful not to compile this for chips which does not have this SPI macro.
Yeah, but if it's protected by an easy-to-understand #ifdef that shouldn't be a problem. Although I don't think we should call it spi.c then. It should be atmel_spi.c or something.
The cpu/arm920t/at91rm9200/spi.c should at least contain the spi init.
Or do it in a chip-specific header file.
I still would like to have the complete sam926x patch set implemented before we start to "play" with it
Yeah, but I still think some preparatory patches are a good thing in order to make things easier later on.
Haavard

I still would like to have the complete sam926x patch set implemented before we start to "play" with it
Yeah, but I still think some preparatory patches are a good thing in order to make things easier later on.
I only see two things as a result of those prepatory patches.
1) Bugs 2) Delays in availability
I am not questioning anything you want to do, just the timing. If we follow your recommendation you will have a bunch of untested board patches in the mainstream u-boot, for the sam926x.
I do not have the time to thoroughly test any changes you do (I dont even have an at91sam9263 board).
If we go my way, then we should be able to have *tested* sam926x support inside U-boot very soon, and while this results in duplication of a small part of the spi code on the source level (no addition to the binary) I believe that the benefit to the community of at91sam926x users of having native support in U-Boot outweighs this duplication a lot.
The number of users far outweisghs the number of implementers and I think that we need to look at it from their point of view.
We are not introducing any new interfaces here, just using the existing interfaces. This means that it will not be harder to do any modifications *after* the sam926x patches are applied. It will be easier since you have better overview.
The only alternative I can see is that you take over the responsibility for both AVR32 and AT91 U-boot and test all modifications on all boards before submission - Still with availability of working solution as the highest priority.
Haavard
Best Regards Ulf Samuelsson

On 2/10/07, Ulf Samuelsson ulf@atmel.com wrote:
The number of users far outweisghs the number of implementers and I think that we need to look at it from their point of view.
Would help a lot to have some of those users help with testing though.
We are not introducing any new interfaces here, just using the existing interfaces. This means that it will not be harder to do any modifications *after* the sam926x patches are applied. It will be easier since you have better overview.
Whatever. Please let me know when you're ready to continue.
The only alternative I can see is that you take over the responsibility for both AVR32 and AT91 U-boot and test all modifications on all boards before submission
- Still with availability of working solution as the highest priority.
I don't think that's going to happen. Besides, having the same person implement and test the code usually doesn't work very well anyway, so if we're going to do this we need people willing to test probably-working-but-still-experimental stuff.
I'm of course not saying that I can't be bothered to test my modifications before submitting, but relying on me to implement _and_ test everything on all configurations is just insane.
Haavard

On 2/10/07, Ulf Samuelsson ulf@atmel.com wrote:
The number of users far outweisghs the number of implementers and I think that we need to look at it from their point of view.
Would help a lot to have some of those users help with testing though.
We are not introducing any new interfaces here, just using the existing interfaces. This means that it will not be harder to do any modifications *after* the sam926x patches are applied. It will be easier since you have better overview.
Whatever. Please let me know when you're ready to continue.
I am ready to continue as soon as at45_split is applied. It is a real simple patch, it divides one more or less duplicated file into two files.
If I try to apply any sam926x patches without that, then It will crash the at91rm9200dk and cmc_pu2 board support.
Once this patch is applied, I can submit the at91sam926x patches and if/when they are accepted, then we have accomplished the most important goal to Atmel customers, which is that *tested* sam926x support is available from the primary U-Boot location and that you can build both at91 and avr32 from the same source code.
I consider all other activities secondary.
Best Regards Ulf Samuelsson ulf@atmel.com Atmel Nordic AB Mail: Box 2033, 174 02 Sundbyberg, Sweden Visit: Kavallerivägen 24, 174 58 Sundbyberg, Sweden Phone +46 (8) 441 54 22 Fax +46 (8) 441 54 29 GSM +46 (706) 22 44 57
Technical support when I am not available: AT89 C51 Applications Group: mailto:micro.hotline@nto.atmel.com AT90 AVR Applications Group: mailto:avr@atmel.com AT91 ARM Applications Group: mailto:at91support@atmel.com FPSLIC Application Group: mailto:fpslic@atmel.com Best AVR

In message 012b01c74ca1$8ee35fe0$01c4af0a@Glamdring you wrote:
If we go my way, then we should be able to have *tested* sam926x support inside U-boot very soon, and while this results in duplication of a small part of the spi code on the source level (no addition to the binary) I believe that the benefit to the community of at91sam926x users of having native support in U-Boot outweighs this duplication a lot.
And once it's in, who guarantees to clean it up later? And when?
We are not introducing any new interfaces here,
But we're adding to the mess of duplicated code.
Best regards,
Wolfgang Denk

In message 012b01c74ca1$8ee35fe0$01c4af0a@Glamdring you wrote:
If we go my way, then we should be able to have *tested* sam926x support inside U-boot very soon, and while this results in duplication of a small part of the spi code on the source level (no addition to the binary) I believe that the benefit to the community of at91sam926x users of having native support in U-Boot outweighs this duplication a lot.
And once it's in, who guarantees to clean it up later? And when?
We are not introducing any new interfaces here,
But we're adding to the mess of duplicated code.
No, that is wrong.
today at45.c is in itself a duplication.
board/at91rm9200dk/at45.c and board/cmc_pu2/at45.c are duplicates (except for a bug which is not fixed in cmc_pu2)
Customers which build their own board add additional at45.c's in their board directory.
After the patch you have a single at45.c which is common for all at91rm9200 boards and a single spi.c which is common for all at91rm9200 boards and an spi.c which is common for all at91sam926x boards.
spi.c is CPU specific and the only reason you can have a single file for the sam926x (three chips supported by that the file) contains ifdefs to select which chip.
Duplication is therefore reduced by the patch. I am sure that you realize this if you get into the details.
Best regards,
Wolfgang Denk
Best Regards Ulf Samuelsson ulf@atmel.com Atmel Nordic AB Mail: Box 2033, 174 02 Sundbyberg, Sweden Visit: Kavallerivägen 24, 174 58 Sundbyberg, Sweden Phone +46 (8) 441 54 22 Fax +46 (8) 441 54 29 GSM +46 (706) 22 44 57
Technical support when I am not available: AT89 C51 Applications Group: mailto:micro.hotline@nto.atmel.com AT90 AVR Applications Group: mailto:avr@atmel.com AT91 ARM Applications Group: mailto:at91support@atmel.com FPSLIC Application Group: mailto:fpslic@atmel.com Best AVR link: www.avrfreaks.net

On Friday 09 February 2007 23:58, Haavard Skinnemoen wrote:
On 2/9/07, Ulf Samuelsson ulf@atmel.com wrote:
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
It's somewhat cpu- and board-independent. at32 and at91 are based on two different architectures, so they don't have any directories in common apart from the ones common to everyone.
We could perhaps create a drivers/atmel subdirectory or, as Ulf suggests, boards/atmel/drivers or cpu/atmel/drivers.
My preferred location would be "drivers/atmel" too.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk Office: Kirchenstr. 5, D-82194 Groebenzell, Germany =====================================================================

In message 010801c74c98$716c2040$01c4af0a@Glamdring you wrote:
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
...
I think at45.c is CPU independent, but spi.c is closely tied to Atmel
...
at45.c contains commands which are specific to the at45 series of dataflash.
Sounds contradictory ;-)
But I agree with the latter statement: at45.c is specific to the at45 series of dataflash, which in turn is specific to a certain class of processors. You probably cannot find this on PowerPC, MIPS, NIOS, ... systems.
That's why I wonder if this should not be located somewhere under cpu/...
While the functions in at45.c are called AT91xxx they really do not
Then that naming should be fixed...
depend on any specific SPI H/W and it can thus be used with any chip which implements the SPI API defined by cpu/arm920t/at91rm9200/spi.c
But we agree that this *is* specific to a certain class of processors of the ARM family, right?
If you let it remain in the board directories as is, then you duplicate this for each board.
This is not what I want, nor what I suggested.
I think a good place for any driver stuff which is useable both by at91 and ap7xxx chips could be an board/atmel/drivers directory.
No. Not board/... if you are talking about chip specific features.
An alternative would be a cpu/atmel/drivers directory.
or cpu/atmel/ (without the /drivers part), like we do for other processors.
Best regards,
Wolfgang Denk

On Saturday 10 February 2007 02:15, Wolfgang Denk wrote:
I think a good place for any driver stuff which is useable both by at91 and ap7xxx chips could be an board/atmel/drivers directory.
No. Not board/... if you are talking about chip specific features.
An alternative would be a cpu/atmel/drivers directory.
or cpu/atmel/ (without the /drivers part), like we do for other processors.
I really prefer to "collect" the drivers in the "drivers" directory (or a subdirectory). We already do this (Freescale Quicc Engine "drivers/qe"), and we have something like "drivers/netarm_eth.c".
So especially for driver that can be used by more than one cpu platform, I suggest to put them into the drivers directory (or subdirectory) and _not_ create another directory instead.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk Office: Kirchenstr. 5, D-82194 Groebenzell, Germany =====================================================================

In message 010801c74c98$716c2040$01c4af0a@Glamdring you wrote:
The only thimg I'm not really happy with (whithout having any better suggestion) is to move this into drivers - drivers is intended for general, CPU and board independent code, where this is obviously specific to a certain class of processors.
...
I think at45.c is CPU independent, but spi.c is closely tied to Atmel
...
at45.c contains commands which are specific to the at45 series of dataflash.
Sounds contradictory ;-)
But I agree with the latter statement: at45.c is specific to the at45 series of dataflash, which in turn is specific to a certain class of processors. You probably cannot find this on PowerPC, MIPS, NIOS, ... systems.
No it is not specific to any class processors. You can add at45 dataflash to any processor.
That's why I wonder if this should not be located somewhere under cpu/...
While the functions in at45.c are called AT91xxx they really do not
Then that naming should be fixed...
depend on any specific SPI H/W and it can thus be used with any chip which implements the SPI API defined by cpu/arm920t/at91rm9200/spi.c
But we agree that this *is* specific to a certain class of processors of the ARM family, right?
No. You can add dataflash to any processor with an SPI interface or even if you do not have an SPI interface you can access the device using standard I/O pins.
At the moment, inside U-Boot it is only used by AT91 processors but that is really not the same thing.
I do believe that it is the guy who wants to use if for more than AT91 processors that shoudl clean it up. Please realize that I am not adding code, I am just rearranging code in a way which will be an improvement of U-Boot.
Are you really against improvements of U-Boot because you want more improvement and rather have a worse U-boot because the improvement is not large enough???
If you let it remain in the board directories as is, then you duplicate this for each board.
This is not what I want, nor what I suggested.
I think a good place for any driver stuff which is useable both by at91 and ap7xxx chips could be an board/atmel/drivers directory.
No. Not board/... if you are talking about chip specific features.
An alternative would be a cpu/atmel/drivers directory.
or cpu/atmel/ (without the /drivers part), like we do for other processors.
I do not see any such directories. I only see cpu/<cpu type> directories.
I believe the proper way to proceed is to merge the tested patches from the Atmel AT91 group which applies cleanly to the the current tree (with the exception of at45_split and a small issue on the NAND flash) We need to split the current at45.c in the board directory into spi.c and the remainder of at45.c in order not to break current code.
I would like to suggest we proceed in the following way:
I modify the patch to generate:
cpu/arm920t/at91rm9200dk/spi.c cpu/atmel/at45.c and the neccessary hooks in Makefiles/configurations?
Once that is included, I will submit the at91sam926x patch(es) One of the sam926x patches will then generate cpu/arm926ejs/at91sam926x/spi.c
Haavard can then, after the sam926x patch set has applied merge (if it is really desired) the spi.c with the AVR32 version and put it in cpu/atmel/spi.c . He can the "clean up" cpu/atmel/at45.c" making naming conventions more generic and move it to drivers/at45.c when that is completed.
Agreed?
Best Regards Ulf Samuelsson

Hello,
I'm currently working with the at91sam9260ek board. I've rebased the atmel code for this board up to the 1.2 release of u-boot. In addition, I've made modifications to the NAND flash driver to support hardware ECC with Syndrome. To support this feature, I had to enable the use of "bad block tables". When u-boot first starts ( I had to start u-boot using the dataflash), it checks for the existence of the bad block table, and if not found, scans through all of the erase blocks to create the table. Once this is done, you can use SAM-BA or the u-boot from dataflash to install U-Boot to the NAND flash. At this point it is safe to overwrite the bad block markers in the OOB area, as they are maintained by the bad block table.
This "bad block table" has the added benefit of a faster boot time, as it doesn't have to scan the entire NAND flash when booting.
Ken Watson kenw@sixnetio.com
-----Original Message----- From: u-boot-users-bounces@lists.sourceforge.net [mailto:u-boot-users- bounces@lists.sourceforge.net] On Behalf Of Michel Benoit Sent: Thursday, February 08, 2007 3:34 AM To: Stefan Roese Cc: Ulf Samuelsson; u-boot-users@lists.sourceforge.net; ARM Linux Mailing List Subject: Re: [U-Boot-Users] AT91 NAND om AT91SAM9260EK
Good morning!
What version of the AT91SAM9260EK u-boot code are you referring to?
I am using u-boot-1.1.5_atmel_1.2 from the Atmel ftp site. Is there a more recent version available? Are there any plans to add the at91sam9260ek support to the main branch of u-boot (latest version 1.2).
In looking through the 1.1.5 Atmel u-boot code I see that nand_bbt.c is used to map out bad blocks marked by the manufacturer. I can write my code to nand from external SAM-BA tool and boot without any problems. Has anyone tried booting from JFFS2 nand within u-boot?
The problem that I was having with the NAND flash on my AT91SAM9260EK board is related to the fact that the hw ECC controller in the 9260 uses the first four bytes of out of bounds space after each page to store an error correction/verification number. The Samsung flash on my board uses the first byte of oob space in the first two pages of a block to mark that it is bad. If the byte is not FF then the mfg has marked the block as bad and it should never be used. When linux mtd starts up it looks for mfg bad blocks and removes them from the available list of nand blocks. Thus any page which contains data is excluded. Looking around at other nand flash devices I found that some use both offsets 0 and 5 in the oob space to mark bad blocks. We plan to use such a nand flash on our custom board. I hope that Atmel will do the same on future revisions of its AT91SAM9260EK board.
My work around for now is to ignore mfg bad blocks and hope that they get caught by the ECC verification code. Mfg bad block info has already been overwritten on my flash chip by the ECC data. Does anyone know if the Atmel SAMBA tool does any bad block verification when programming nand flash? It seems to be writing the 4 byte ECC code in the oob space. Is it also marking mfg bad blocks? If so, at which offset into the oob space?
Michel
On 2/8/07, Stefan Roese sr@denx.de wrote:
On Thursday 08 February 2007 00:17, Ulf Samuelsson wrote:
Has anyone used the at91_nand driver on the AT91SAM9260EK?
I get bad erase blocks on every block that contaions data (written
to
nand flash with SAM-BA). Seems like the read_oob (read out of
bounds
area) function is returning data from the in bounds area.
U-boot configs the nand flash to use hw ecc (syndrome) whereas the at91_nand seems to be setup to use soft ecc.
According to recent conversations on U-Boot mailing list U-boot can do a raw copy of a flash file system, but nothing more. (Correct me if I have misunderstood)
Yes. But this copy is bad block aware.
This means that if there are faulty pages in the NAND flash, you are
dead.
No. Bad blocks are handled correctly.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, HRB 165235 Munich, CEO: Wolfgang Denk Office: Kirchenstr. 5, D-82194 Groebenzell, Germany =====================================================================
Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier. Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&da... _______________________________________________ U-Boot-Users mailing list U-Boot-Users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/u-boot-users
participants (7)
-
Haavard Skinnemoen
-
Haavard Skinnemoen
-
Ken Watson
-
Michel Benoit
-
Stefan Roese
-
Ulf Samuelsson
-
Wolfgang Denk