public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
From: Yang, Wenyou <Wenyou.Yang@Microchip.com>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 6/8] sf: add new option to support SPI flash above 16MiB
Date: Mon, 22 May 2017 09:20:14 +0800	[thread overview]
Message-ID: <c8ec0dfc-53fc-3d18-8a86-9fe498cd5c66@Microchip.com> (raw)
In-Reply-To: <bc2463b62baa14ab7c38f0a892a92b1acfdbb7b3.1495204848.git.cyrille.pitchen@atmel.com>



On 2017/5/19 22:59, Cyrille Pitchen wrote:
> The patch provides an alternative method to support SPI flash size greater
> than 16MiB (128Mib).
>
> Indeed using the Base Address Register (BAR) is stateful. Hence, once the
> BAR has been modified, if a spurious CPU reset occurs with no reset/power
> off at the SPI flash side, early boot loarders may try to read from offset
> 0 but fails because of the new BAR value.
>
> On the other hand, using the 4-byte address instruction set is stateless.
> When supported by the SPI flash memory, it allows us to access memory data
> area above 16MiB without changing the internal state of this SPI flash
> memory. Then if a spirious reboot occurs, early boot loaders can still
> access data from offset 0.
>
> Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>

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


Best Regards,
Wenyou Yang
> ---
>   drivers/mtd/spi/Kconfig       | 15 ++++++-
>   drivers/mtd/spi/sf_internal.h | 18 +++++++++
>   drivers/mtd/spi/spi_flash.c   | 92 ++++++++++++++++++++++++++++++++++++++++---
>   3 files changed, 118 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
> index 5ca0a712d84a..c11e83263b16 100644
> --- a/drivers/mtd/spi/Kconfig
> +++ b/drivers/mtd/spi/Kconfig
> @@ -34,14 +34,27 @@ config SPI_FLASH
>   
>   	  If unsure, say N
>   
> +choice
> +	prompt "Support SPI flash above 16MiB"
> +	depends on SPI_FLASH
> +	optional
> +
>   config SPI_FLASH_BAR
>   	bool "SPI flash Bank/Extended address register support"
> -	depends on SPI_FLASH
>   	help
>   	  Enable the SPI flash Bank/Extended address register support.
>   	  Bank/Extended address registers are used to access the flash
>   	  which has size > 16MiB in 3-byte addressing.
>   
> +config SPI_FLASH_4BAIS
> +	bool "SPI flash 4-byte address instruction set support"
> +	help
> +	  Convert the selected 3-byte address op codes into their associated
> +	  4-byte address op codes. Using this instruction set does not change
> +	  the internal state of the SPI flash device.
> +
> +endchoice
> +
>   if SPI_FLASH
>   
>   config SPI_FLASH_ATMEL
> diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h
> index 8b8c951bcc55..30994f9f460c 100644
> --- a/drivers/mtd/spi/sf_internal.h
> +++ b/drivers/mtd/spi/sf_internal.h
> @@ -27,6 +27,7 @@ enum spi_nor_option_flags {
>   };
>   
>   #define SPI_FLASH_3B_ADDR_LEN		3
> +#define SPI_FLASH_4B_ADDR_LEN		4
>   #define SPI_FLASH_CMD_LEN		(1 + SPI_FLASH_3B_ADDR_LEN + 16)
>   #define SPI_FLASH_16MB_BOUN		0x1000000
>   
> @@ -64,6 +65,19 @@ enum spi_nor_option_flags {
>   #define CMD_READ_CONFIG			0x35
>   #define CMD_FLAG_STATUS			0x70
>   
> +/* 4-byte address instruction set */
> +#define CMD_READ_ARRAY_SLOW_4B		0x13
> +#define CMD_READ_ARRAY_FAST_4B		0x0c
> +#define CMD_READ_DUAL_OUTPUT_FAST_4B	0x3c
> +#define CMD_READ_DUAL_IO_FAST_4B	0xbc
> +#define CMD_READ_QUAD_OUTPUT_FAST_4B	0x6c
> +#define CMD_READ_QUAD_IO_FAST_4B	0xec
> +#define CMD_PAGE_PROGRAM_4B		0x12
> +#define CMD_PAGE_PROGRAM_1_1_4_4B	0x34
> +#define CMD_PAGE_PROGRAM_1_4_4_4B	0x3e
> +#define CMD_ERASE_4K_4B			0x21
> +#define CMD_ERASE_64K_4B		0xdc
> +
>   /* Bank addr access commands */
>   #ifdef CONFIG_SPI_FLASH_BAR
>   # define CMD_BANKADDR_BRWR		0x17
> @@ -133,6 +147,10 @@ struct spi_flash_info {
>   #define RD_QUADIO		BIT(6)	/* use Quad IO Read */
>   #define RD_DUALIO		BIT(7)	/* use Dual IO Read */
>   #define RD_FULL			(RD_QUAD | RD_DUAL | RD_QUADIO | RD_DUALIO)
> +#define NO_4BAIS		BIT(8)	/*
> +					 * 4-byte address instruction set
> +					 * NOT supported
> +					 */
>   };
>   
>   extern const struct spi_flash_info spi_flash_ids[];
> diff --git a/drivers/mtd/spi/spi_flash.c b/drivers/mtd/spi/spi_flash.c
> index c5e00772f241..695c8555db3f 100644
> --- a/drivers/mtd/spi/spi_flash.c
> +++ b/drivers/mtd/spi/spi_flash.c
> @@ -176,6 +176,67 @@ bar_end:
>   }
>   #endif
>   
> +#ifdef CONFIG_SPI_FLASH_4BAIS
> +static u8 spi_flash_convert_opcode(u8 opcode, const u8 table[][2], size_t size)
> +{
> +	size_t i;
> +
> +	for (i = 0; i < size; i++)
> +		if (table[i][0] == opcode)
> +			return table[i][1];
> +
> +	/* No conversion found, keep input op code. */
> +	return opcode;
> +}
> +
> +static u8 spi_flash_convert_3to4_read(u8 opcode)
> +{
> +	static const u8 spi_flash_3to4_read[][2] = {
> +		{CMD_READ_ARRAY_SLOW,		CMD_READ_ARRAY_SLOW_4B},
> +		{CMD_READ_ARRAY_FAST,		CMD_READ_ARRAY_FAST_4B},
> +		{CMD_READ_DUAL_OUTPUT_FAST,	CMD_READ_DUAL_OUTPUT_FAST_4B},
> +		{CMD_READ_DUAL_IO_FAST,		CMD_READ_DUAL_IO_FAST_4B},
> +		{CMD_READ_QUAD_OUTPUT_FAST,	CMD_READ_QUAD_OUTPUT_FAST_4B},
> +		{CMD_READ_QUAD_IO_FAST,		CMD_READ_QUAD_IO_FAST_4B},
> +	};
> +
> +	return spi_flash_convert_opcode(opcode, spi_flash_3to4_read,
> +					ARRAY_SIZE(spi_flash_3to4_read));
> +}
> +
> +static u8 spi_flash_convert_3to4_write(u8 opcode)
> +{
> +	static const u8 spi_flash_3to4_write[][2] = {
> +		{CMD_PAGE_PROGRAM,		CMD_PAGE_PROGRAM_4B},
> +		{CMD_PAGE_PROGRAM_1_1_4,	CMD_PAGE_PROGRAM_1_1_4_4B},
> +		{CMD_PAGE_PROGRAM_1_4_4,	CMD_PAGE_PROGRAM_1_4_4_4B},
> +	};
> +
> +	return spi_flash_convert_opcode(opcode, spi_flash_3to4_write,
> +					ARRAY_SIZE(spi_flash_3to4_write));
> +}
> +
> +static u8 spi_flash_convert_3to4_erase(u8 opcode)
> +{
> +	static const u8 spi_flash_3to4_erase[][2] = {
> +		{CMD_ERASE_4K,	CMD_ERASE_4K_4B},
> +		{CMD_ERASE_64K,	CMD_ERASE_64K_4B},
> +	};
> +
> +	return spi_flash_convert_opcode(opcode, spi_flash_3to4_erase,
> +					ARRAY_SIZE(spi_flash_3to4_erase));
> +}
> +
> +static void spi_flash_set_4byte_addr_opcodes(struct spi_flash *flash,
> +					     const struct spi_flash_info *info)
> +{
> +	flash->read_cmd = spi_flash_convert_3to4_read(flash->read_cmd);
> +	flash->write_cmd = spi_flash_convert_3to4_write(flash->write_cmd);
> +	flash->erase_cmd = spi_flash_convert_3to4_erase(flash->erase_cmd);
> +	flash->addr_len = SPI_FLASH_4B_ADDR_LEN;
> +}
> +#endif
> +
>   #ifdef CONFIG_SF_DUAL_FLASH
>   static void spi_flash_dual(struct spi_flash *flash, u32 *addr)
>   {
> @@ -966,6 +1027,7 @@ int spi_flash_scan(struct spi_flash *flash)
>   {
>   	struct spi_slave *spi = flash->spi;
>   	const struct spi_flash_info *info = NULL;
> +	bool above_16MB;
>   	int ret;
>   
>   	info = spi_flash_read_id(flash);
> @@ -1106,6 +1168,26 @@ int spi_flash_scan(struct spi_flash *flash)
>   	/* Set the address length */
>   	flash->addr_len = SPI_FLASH_3B_ADDR_LEN;
>   
> +	above_16MB = ((flash->dual_flash == SF_SINGLE_FLASH) &&
> +		      (flash->size > SPI_FLASH_16MB_BOUN)) ||
> +		     ((flash->dual_flash > SF_SINGLE_FLASH) &&
> +		      (flash->size > SPI_FLASH_16MB_BOUN << 1));
> +
> +	/*
> +	 * replace the selected 3-byte address op codes with the associated
> +	 * 4-byte address op codes, if needed (flash->size > 16 MiB)
> +	 */
> +#ifdef CONFIG_SPI_FLASH_4BAIS
> +	if (above_16MB) {
> +		if (info->flags & NO_4BAIS) {
> +			puts("SF: Warning - Only lower 16MiB accessible,");
> +			puts(" 4-byte address instruction set not supported\n");
> +		} else {
> +			spi_flash_set_4byte_addr_opcodes(flash, info);
> +		}
> +	}
> +#endif
> +
>   	/* Configure the BAR - discover bank cmds and read current bank */
>   #ifdef CONFIG_SPI_FLASH_BAR
>   	ret = read_bar(flash, info);
> @@ -1131,13 +1213,11 @@ int spi_flash_scan(struct spi_flash *flash)
>   	puts("\n");
>   #endif
>   
> -#ifndef CONFIG_SPI_FLASH_BAR
> -	if (((flash->dual_flash == SF_SINGLE_FLASH) &&
> -	     (flash->size > SPI_FLASH_16MB_BOUN)) ||
> -	     ((flash->dual_flash > SF_SINGLE_FLASH) &&
> -	     (flash->size > SPI_FLASH_16MB_BOUN << 1))) {
> +#if !defined(CONFIG_SPI_FLASH_BAR) && !defined(CONFIG_SPI_FLASH_4BAIS)
> +	if (above_16MB) {
>   		puts("SF: Warning - Only lower 16MiB accessible,");
> -		puts(" Full access #define CONFIG_SPI_FLASH_BAR\n");
> +		puts(" Full access #define CONFIG_SPI_FLASH_BAR");
> +		puts(" or CONFIG_SPI_FLASH_4BAIS\n");
>   	}
>   #endif
>   

  reply	other threads:[~2017-05-22  1:20 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-05-19 14:59 [U-Boot] [PATCH 0/8] sf: improve support of (Q)SPI flash memories Cyrille Pitchen
2017-05-19 14:59 ` [U-Boot] [PATCH 1/8] spi: add support of SPI flash commands Cyrille Pitchen
2017-05-22  1:17   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 2/8] sf: describe all SPI flash commands with 'struct spi_flash_command' Cyrille Pitchen
2017-05-22  1:18   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 3/8] sf: select the relevant SPI flash protocol for read and write commands Cyrille Pitchen
2017-05-22  1:18   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 4/8] sf: differentiate Page Program 1-1-4 and 1-4-4 Cyrille Pitchen
2017-05-22  1:19   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 5/8] sf: add 'addr_len' member to 'struct spi_flash' Cyrille Pitchen
2017-05-22  1:19   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 6/8] sf: add new option to support SPI flash above 16MiB Cyrille Pitchen
2017-05-22  1:20   ` Yang, Wenyou [this message]
2017-05-19 14:59 ` [U-Boot] [PATCH 7/8] sf: add support to Microchip SST26 QSPI memories Cyrille Pitchen
2017-05-22  1:20   ` Yang, Wenyou
2017-05-19 14:59 ` [U-Boot] [PATCH 8/8] sf: add driver for Atmel QSPI controller Cyrille Pitchen
2017-05-22  1:21   ` Yang, Wenyou

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c8ec0dfc-53fc-3d18-8a86-9fe498cd5c66@Microchip.com \
    --to=wenyou.yang@microchip.com \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox