[PATCH v2] cfi_flash: Fix detection of 8-bit bus flash devices via address shift

Stefan Roese sr at denx.de
Tue Apr 6 10:45:41 CEST 2021


On 26.02.21 08:51, Stefan Roese wrote:
> From: Jagannadha Sutradharudu Teki <jagannadha.sutradharudu-teki at xilinx.com>
> 
> We had a problem detecting 8/16bit flash devices connected only via
> 8bits to the SoC for quite a while. Commit 239cb9d9
> [mtd: cfi_flash: Fix CFI flash driver for 8-bit bus support] finally
> fixed this 8-bit bus support. But also broke some other boards using
> this cfi driver. So this patch had to be reverted.
> 
> I spotted a different, simpler approach for this 8-bit bus support
> on the barebox mailing list posted by
> Oleksij Rempel <bug-track at fisher-privat.net>:
> 
> http://www.spinics.net/lists/u-boot-v2/msg14687.html
> 
> Here the commit text:
> 
> "
> Many cfi chips support 16 and 8 bit modes. Most important
> difference is use of so called "Q15/A-1" pin. In 16bit mode this
> pin is used for data IO. In 8bit mode, it is an address input
> which add one more least significant bit (LSB). In this case
> we should shift all adresses by one:
> For example 0xaa << 1 = 0x154
> "
> 
> This patch now is a port of this barebox patch to U-Boot.
> 
> Along with the change w.r.t from barebox,
> Some flash chips can support multiple bus widths, override the
> interface width and limit it to the port width.
> 
> Tested on 16-bit Spansion flash on sequoia.
> Tested 8-bit flashes like 256M29EW, 512M29EW.
> 
> Signed-off-by: Stefan Roese <sr at denx.de>
> Tested-by: Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
> Cc: Jagannadha Sutradharudu Teki <jaganna at xilinx.com>
> Cc: Aaron Williams <awilliams at marvell.com>
> Cc: Chandrakala Chavva <cchavva at marvell.com>
> Cc: Andre Przywara <andre.przywara at arm.com>
> Cc: Vignesh Raghavendra <vigneshr at ti.com>
> Cc: Simon Glass <sjg at chromium.org>
> Cc: Mario Six <mario.six at gdsys.cc>
> Cc: York Sun <york.sun at nxp.com>
> Cc: Marek Vasut <marek.vasut+renesas at gmail.com>
> ---
> v2:
> - Rebase on current mainline
> 
> I've run into problems with CFI flash on the MIPS Octeon EBB7304, where
> the CFI detection did not work. While testing and digging through the
> very old CFI related patches, I stumbled over this patch which fixes
> the problems on the EBB7304.
> 
> I would really like to see some further testing of this patch on other
> boards using CFI parallel flash though. That's why I added some
> developers who did send CFI related patches in the last few years. So
> please test with this patch applied if possible.
> 
> Thanks,
> Stefan

Unfortunately it did not receive any tests on other platforms yet.
That's why I'm pulling this patch early in the merge window, so that
it has a longer time for testing in master.

Applied to u-boot-cfi-flash/master

Thanks,
Stefan

>   drivers/mtd/cfi_flash.c | 37 +++++++++++++++++++++++++++++++++----
>   include/flash.h         |  2 ++
>   2 files changed, 35 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/mtd/cfi_flash.c b/drivers/mtd/cfi_flash.c
> index b4512e3a5f..9642d7c7dc 100644
> --- a/drivers/mtd/cfi_flash.c
> +++ b/drivers/mtd/cfi_flash.c
> @@ -218,7 +218,7 @@ flash_map(flash_info_t *info, flash_sect_t sect, uint offset)
>   {
>   	unsigned int byte_offset = offset * info->portwidth;
>   
> -	return (void *)(info->start[sect] + byte_offset);
> +	return (void *)(info->start[sect] + (byte_offset << info->chip_lsb));
>   }
>   
>   static inline void flash_unmap(flash_info_t *info, flash_sect_t sect,
> @@ -1918,12 +1918,27 @@ static int __flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry)
>   			flash_read_cfi(info, qry, FLASH_OFFSET_CFI_RESP,
>   				       sizeof(struct cfi_qry));
>   			info->interface	= le16_to_cpu(qry->interface_desc);
> +			/* Some flash chips can support multiple bus widths.
> +			 * In this case, override the interface width and
> +			 * limit it to the port width.
> +			 */
> +			if ((info->interface == FLASH_CFI_X8X16) &&
> +					(info->portwidth == FLASH_CFI_8BIT)) {
> +				debug("Overriding 16-bit interface width to"
> +						" 8-bit port width\n");
> +				info->interface = FLASH_CFI_X8;
> +			} else if ((info->interface == FLASH_CFI_X16X32) &&
> +					(info->portwidth == FLASH_CFI_16BIT)) {
> +				debug("Overriding 16-bit interface width to"
> +						" 16-bit port width\n");
> +				info->interface = FLASH_CFI_X16;
> +			}
>   
>   			info->cfi_offset = flash_offset_cfi[cfi_offset];
>   			debug("device interface is %d\n",
>   			      info->interface);
> -			debug("found port %d chip %d ",
> -			      info->portwidth, info->chipwidth);
> +			debug("found port %d chip %d chip_lsb %d ",
> +			      info->portwidth, info->chipwidth, info->chip_lsb);
>   			debug("port %d bits chip %d bits\n",
>   			      info->portwidth << CFI_FLASH_SHIFT_WIDTH,
>   			      info->chipwidth << CFI_FLASH_SHIFT_WIDTH);
> @@ -1962,9 +1977,23 @@ static int flash_detect_cfi(flash_info_t *info, struct cfi_qry *qry)
>   	     info->portwidth <= FLASH_CFI_64BIT; info->portwidth <<= 1) {
>   		for (info->chipwidth = FLASH_CFI_BY8;
>   		     info->chipwidth <= info->portwidth;
> -		     info->chipwidth <<= 1)
> +		     info->chipwidth <<= 1) {
> +			/*
> +			 * First, try detection without shifting the addresses
> +			 * for 8bit devices (16bit wide connection)
> +			 */
> +			info->chip_lsb = 0;
> +			if (__flash_detect_cfi(info, qry))
> +				return 1;
> +
> +			/*
> +			 * Not detected, so let's try with shifting
> +			 * for 8bit devices
> +			 */
> +			info->chip_lsb = 1;
>   			if (__flash_detect_cfi(info, qry))
>   				return 1;
> +		}
>   	}
>   	debug("not found\n");
>   	return 0;
> diff --git a/include/flash.h b/include/flash.h
> index 3bf6b22399..42b18a6047 100644
> --- a/include/flash.h
> +++ b/include/flash.h
> @@ -24,6 +24,8 @@ typedef struct {
>   #ifdef CONFIG_SYS_FLASH_CFI
>   	uchar	portwidth;		/* the width of the port		*/
>   	uchar	chipwidth;		/* the width of the chip		*/
> +	uchar	chip_lsb;		/* extra Least Significant Bit in the */
> +					/* address of chip	*/
>   	ushort	buffer_size;		/* # of bytes in write buffer		*/
>   	ulong	erase_blk_tout;		/* maximum block erase timeout		*/
>   	ulong	write_tout;		/* maximum write timeout		*/
> 


Viele Grüße,
Stefan

-- 
DENX Software Engineering GmbH,      Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-51 Fax: (+49)-8142-66989-80 Email: sr at denx.de


More information about the U-Boot mailing list