[U-Boot] [PATCH 3/8] sf: select the relevant SPI flash protocol for read and write commands

Yang, Wenyou Wenyou.Yang at Microchip.com
Mon May 22 01:18:55 UTC 2017



On 2017/5/19 22:59, Cyrille Pitchen wrote:
> SPI controller drivers should not check the instruction op code byte to
> guess which SPI x-y-z protocol is to be used for Fast Read or Page Program
> operations.
>
> Indeed, the op code values are not so reliable. For instance, the 32h op
> code is generally used for Page Program 1-1-4 operations. However
> Microchip SST26 memories use this 32h op code for their Page Program 1-4-4
> operations. There are many other examples of those SPI flash manufacturer
> quirks.
>
> Instead, the SPI FLASH sub-system now fills the 'proto' member
> of 'struct spi_flash_command' with flash->read_proto for Fast Read
> operations and flash->write_proto for Page Program operations.
>
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen at atmel.com>

Acked-by Wenyou Yang <wenyou.yang at atmel.com>


Best Regards,
Wenyou Yang

> ---
>   drivers/mtd/spi/spi_flash.c | 24 ++++++++++++++++--------
>   include/spi_flash.h         |  4 ++++
>   2 files changed, 20 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
> index d0634e5b28c7..7e35fb9f4802 100644
> --- a/drivers/mtd/spi/spi_flash.c
> +++ b/drivers/mtd/spi/spi_flash.c
> @@ -379,6 +379,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
>   
>   	spi_flash_command_init(&cmd, flash->write_cmd, SPI_FLASH_3B_ADDR_LEN,
>   			       SPI_FCMD_WRITE);
> +	cmd.proto = flash->write_proto;
>   	for (actual = 0; actual < len; actual += chunk_len) {
>   		write_addr = offset;
>   
> @@ -482,6 +483,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
>   
>   	spi_flash_command_init(&cmd, flash->read_cmd, SPI_FLASH_3B_ADDR_LEN,
>   			       SPI_FCMD_READ);
> +	cmd.proto = flash->read_proto;
>   	cmd.num_wait_states = flash->dummy_byte * 8;
>   	while (len) {
>   		read_addr = offset;
> @@ -1045,24 +1047,30 @@ int spi_flash_scan(struct spi_flash *flash)
>   
>   	/* Look for read commands */
>   	flash->read_cmd = CMD_READ_ARRAY_FAST;
> -	if (spi->mode & SPI_RX_SLOW)
> +	flash->read_proto = SPI_FPROTO_1_1_1;
> +	if (spi->mode & SPI_RX_SLOW) {
>   		flash->read_cmd = CMD_READ_ARRAY_SLOW;
> -	else if (spi->mode & SPI_RX_QUAD && info->flags & RD_QUAD)
> +	} else if (spi->mode & SPI_RX_QUAD && info->flags & RD_QUAD) {
>   		flash->read_cmd = CMD_READ_QUAD_OUTPUT_FAST;
> -	else if (spi->mode & SPI_RX_DUAL && info->flags & RD_DUAL)
> +		flash->read_proto = SPI_FPROTO_1_1_4;
> +	} else if (spi->mode & SPI_RX_DUAL && info->flags & RD_DUAL) {
>   		flash->read_cmd = CMD_READ_DUAL_OUTPUT_FAST;
> +		flash->read_proto = SPI_FPROTO_1_1_2;
> +	}
>   
>   	/* Look for write commands */
> -	if (info->flags & WR_QPP && spi->mode & SPI_TX_QUAD)
> +	if (info->flags & WR_QPP && spi->mode & SPI_TX_QUAD) {
>   		flash->write_cmd = CMD_QUAD_PAGE_PROGRAM;
> -	else
> +		flash->write_proto = SPI_FPROTO_1_1_4;
> +	} else {
>   		/* Go for default supported write cmd */
>   		flash->write_cmd = CMD_PAGE_PROGRAM;
> +		flash->write_proto = SPI_FPROTO_1_1_1;
> +	}
>   
>   	/* Set the quad enable bit - only for quad commands */
> -	if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) ||
> -	    (flash->read_cmd == CMD_READ_QUAD_IO_FAST) ||
> -	    (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) {
> +	if (spi_flash_protocol_get_data_nbits(flash->read_proto) == 4 ||
> +	    spi_flash_protocol_get_data_nbits(flash->write_proto) == 4) {
>   		ret = set_quad_mode(flash, info);
>   		if (ret) {
>   			debug("SF: Fail to set QEB for %02x\n",
> diff --git a/include/spi_flash.h b/include/spi_flash.h
> index be2fe3f84cb9..ac2b37f0202f 100644
> --- a/include/spi_flash.h
> +++ b/include/spi_flash.h
> @@ -48,6 +48,8 @@ struct spi_slave;
>    * @read_cmd:		Read cmd - Array Fast, Extn read and quad read.
>    * @write_cmd:		Write cmd - page and quad program.
>    * @dummy_byte:		Dummy cycles for read operation.
> + * @read_proto:		SPI x-y-z protocol for flash read ops
> + * @write_proto:	SPI x-y-z protocol for flash write ops
>    * @memory_map:		Address of read-only SPI flash access
>    * @flash_lock:		lock a region of the SPI Flash
>    * @flash_unlock:	unlock a region of the SPI Flash
> @@ -83,6 +85,8 @@ struct spi_flash {
>   	u8 read_cmd;
>   	u8 write_cmd;
>   	u8 dummy_byte;
> +	enum spi_flash_protocol read_proto;
> +	enum spi_flash_protocol write_proto;
>   
>   	void *memory_map;
>   



More information about the U-Boot mailing list