[U-Boot] [PATCH 1/2 v1] sf: probe: Add support Atmel AT45DB series devices special commands

Peng Fan Peng.Fan at freescale.com
Thu Mar 26 04:04:53 CET 2015


Hi Haikun,

On 3/26/2015 10:39 AM, Wang Haikun-B53464 wrote:
> On 3/25/2015 10:10 PM, Fan Peng-B51431 wrote:
>> Hi Haikun,
>>
>> On 3/25/2015 8:35 PM, Haikun Wang wrote:
>>> From: Haikun Wang <Haikun.Wang at freescale.com>
>>>
>>> Atmel AT45DB series devices commands is different from common spi flash
>>> commands. This patch add support for AT45DB special commands.
>>> Add a flag AT45DB_CMD to control whether use those commands.
>>>
>>> Signed-off-by: Haikun Wang <Haikun.Wang at freescale.com>
>>> ---
>>>
>>> Changes in v1: None
>>>
>>>     drivers/mtd/spi/sf_internal.h |  7 +++++++
>>>     drivers/mtd/spi/sf_ops.c      |  2 +-
>>>     drivers/mtd/spi/sf_probe.c    | 10 ++++++++++
>>>     3 files changed, 18 insertions(+), 1 deletion(-)
>>>
>>> diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
>>> index 785f7a9..234af21 100644
>>> --- a/drivers/mtd/spi/sf_internal.h
>>> +++ b/drivers/mtd/spi/sf_internal.h
>>> @@ -43,6 +43,7 @@ enum {
>>>     	SST_BP		= 1 << 3,
>>>     	SST_WP		= 1 << 4,
>>>     	WR_QPP		= 1 << 5,
>>> +	AT45DB_CMD	= 1 << 6,
>>>     };
>>>
>>>     #define SST_WR		(SST_BP | SST_WP)
>>> @@ -106,6 +107,12 @@ enum {
>>>     #define SPI_FLASH_PAGE_ERASE_TIMEOUT		(5 * CONFIG_SYS_HZ)
>>>     #define SPI_FLASH_SECTOR_ERASE_TIMEOUT	(10 * CONFIG_SYS_HZ)
>>>
>>> +/* Atmel AT45DB specific */
>>> +#define CMD_ATMEL_PAGE_PROGRAM		0x82
>> Why not use 0x2 to align with current mtd/spi framework?
> I didn't find the program command '0x2' in AT45DB021D datasheet.
My fault. 0x2h is supported by AT45DB021E, but not AT45DB021D. You can 
use 0x82.
> Do you ever use it in AT45DBxxxx flash chip?
I used a similar chip AT45DB021E, not AT45DB021D. And I have a local 
patch for this chip.

>>> +#define CMD_ATMEL_READ_STATUS		0xd7
>>> +#define CMD_ATMEL_FLAG_STATUS		0xd7
>>> +#define CMD_ATMEL_BLK_ERASE	        0x50
>>> +
>>>     /* SST specific */
>>>     #ifdef CONFIG_SPI_FLASH_SST
>>>     # define CMD_SST_BP		0x02    /* Byte Program */
>>> diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c
>>> index 34bc54e..27ce5f9 100644
>>> --- a/drivers/mtd/spi/sf_ops.c
>>> +++ b/drivers/mtd/spi/sf_ops.c
>>> @@ -165,7 +165,7 @@ int spi_flash_cmd_wait_ready(struct spi_flash *flash, unsigned long timeout)
>>>     	u8 poll_bit = STATUS_WIP;
>>>     	u8 cmd = flash->poll_cmd;
>>>
>>> -	if (cmd == CMD_FLAG_STATUS) {
>>> +	if (cmd == CMD_FLAG_STATUS || cmd == CMD_ATMEL_FLAG_STATUS) {
>>>     		poll_bit = STATUS_PEC;
>>>     		check_status = poll_bit;
>>>     	}
>>> diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
>>> index 4103723..2ccddf2 100644
>>> --- a/drivers/mtd/spi/sf_probe.c
>>> +++ b/drivers/mtd/spi/sf_probe.c
>>> @@ -226,6 +226,16 @@ static int spi_flash_validate_params(struct spi_slave *spi, u8 *idcode,
>>>     		flash->poll_cmd = CMD_FLAG_STATUS;
>>>     #endif
>>>
>>> +#ifdef CONFIG_SPI_FLASH_ATMEL
>>> +	if (params->flags & AT45DB_CMD) {
>>> +		flash->poll_cmd = CMD_ATMEL_READ_STATUS;
>>> +		flash->write_cmd = CMD_ATMEL_PAGE_PROGRAM;
>>> +		/* use block-erase command, eight pages */
>>> +		flash->erase_cmd = CMD_ATMEL_BLK_ERASE;
>>> +		flash->erase_size = flash->page_size * 8;
>>> +	}
>>> +#endif
>>> +
>> The SPI Flash's default page size is 264 bytes, but mtd/spi framework
>> supports 256 and 512 bytes for one page. In your patch, you does not
>> handle such case, can your driver works as expected?
> Fine, I know mtd/spi framework doesn't support page-size of 264bytes.
> In fact we change the chip's page-size to 256bytes before using it.
If others use a same chip, he/she has no idea about this.
> It is a big work to adjust the framework support 264bytes.
No big work, just send a configuration command to the chip.
> So how about add a check here, if the chip has a page-size of 264bytes,
> we just return an error.
This AT45XXD chip's page size can only be configured once. you can check 
the status register, BIT 0's meaning is PAGE SIZE is 256 or 264.
If the page size is 264, you can configure the chip to 256 seeing "11.1 
Programming the Configuration Register". If the page size is already 
256, no need to configure it again.
You can added related function in sf_ops.c and invoke this function in 
sf_probe.c when probe.
you can take the following piece of code as a reference as you like, it 
works for AT45DB021E. About read status, I suppose you  can use the 
FLAG_STATUS to get the correct value.

#if defined(CONFIG_SPI_FLASH_ATMEL)
/*
  * For the AT45DB021E, there are an extra eight bytes
  * of memory in each page for a total of an extra 8KB
  * (64-Kbits) of user-accessible memory.
  * In order to be compatible with spi framework, we use 256bytes.
  */

int spi_flash_cmd_write_config(struct spi_flash *flash, u8 wc)
{
     u8 data[3];
     u8 cmd;
     int ret;

     ret = spi_flash_cmd_read_status(flash, &data[0]);
     if (ret < 0)
         return ret;

     /*
      * PAGE SIZE Page Size, bit 0.
      * 0 Device is configured for standard DataFlash page size (264 bytes).
      * 1 Device is configured for “power of 2” binary page size (256 
bytes).
      */
     if (wc == SPI_FLASH_PAGE_256) {
         /* Already 256? */
         if (data[0] & 1)
             return 0;
     } else if (wc == SPI_FLASH_PAGE_264) {
         /* Already 264? */
         if ((data[0] & 1) == 0)
             return 0;
     } else {
         debug("Unsupport page configuration!\n");
         return -1;
     }

     /*
      * 3D, 2A, 80, A6 command seq will configure flash page size 256.
      * 3D, 2A, 80, A7 command seq will configure flash page size 264.
      */
     cmd = 0x3D;
     if (wc == SPI_FLASH_PAGE_256)
         data[2] = 0xA6;
     else if (wc == SPI_FLASH_PAGE_264)
         data[2] = 0xA7;
     data[1] = 0x80;
     data[0] = 0x2A;
     ret = spi_flash_write_common(flash, &cmd, 1, data, 3);
     if (ret) {
         debug("SF: fail to write config register\n");
         return ret;
     }

     /* Check again  the page size*/
    xxxxxxxxxxxxxxxxxx

     return 0;
}
#endif

> Or I will add a AT45DB special flash driver under Driver Model.
Regards,
Peng.


More information about the U-Boot mailing list