mirror of
				git://git.openwrt.org/openwrt/openwrt.git
				synced 2025-10-31 05:54:26 -04:00 
			
		
		
		
	This flag was added to 4.9 with upstream commit 76a4707de5e18dc32d9cb4e990686140c5664a15. Signed-off-by: Victor Shyba <victor1984@riseup.net> [refresh and adjust platform patches, fix commit message] Signed-off-by: Mathias Kresin <dev@kresin.me>
		
			
				
	
	
		
			158 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			158 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 034dd6241b55ab2256eecb845e941fa9b45da38e Mon Sep 17 00:00:00 2001
 | |
| From: Yunhui Cui <yunhui.cui@nxp.com>
 | |
| Date: Thu, 28 Apr 2016 17:03:57 +0800
 | |
| Subject: [PATCH 110/113] mtd: spi-nor: fsl-quad: add flash S25FS extra
 | |
|  support
 | |
| 
 | |
| [context adjustment]
 | |
| not apply changes of arch/arm64/boot/dts/freescale/fsl-ls1012a-qds.dts
 | |
| 
 | |
| There are some boards have the same QSPI controller but have
 | |
| different vendor flash, So, the controller can use the same
 | |
| compatible and share the driver, just for a different flash to do
 | |
| the appropriate adaptation. Based on this, we need add the vendor
 | |
| field in spi-nor, Because we will use the field to distribute
 | |
| corresponding LUT for different flash operations.
 | |
| 
 | |
| Signed-off-by: Yunhui Cui <yunhui.cui@nxp.com>
 | |
| Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
 | |
| Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
 | |
| Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
 | |
| ---
 | |
|  drivers/mtd/spi-nor/fsl-quadspi.c |   47 ++++++++++++++++++++++++++++++-------
 | |
|  drivers/mtd/spi-nor/spi-nor.c     |    5 ++--
 | |
|  include/linux/mtd/spi-nor.h       |    1 +
 | |
|  3 files changed, 42 insertions(+), 11 deletions(-)
 | |
| 
 | |
| --- a/drivers/mtd/spi-nor/fsl-quadspi.c
 | |
| +++ b/drivers/mtd/spi-nor/fsl-quadspi.c
 | |
| @@ -213,6 +213,9 @@
 | |
|  
 | |
|  #define QUADSPI_MIN_IOMAP SZ_4M
 | |
|  
 | |
| +#define FLASH_VENDOR_SPANSION_FS	"s25fs"
 | |
| +#define SPANSION_S25FS_FAMILY	(1 << 1)
 | |
| +
 | |
|  enum fsl_qspi_devtype {
 | |
|  	FSL_QUADSPI_VYBRID,
 | |
|  	FSL_QUADSPI_IMX6SX,
 | |
| @@ -329,6 +332,18 @@ static inline int has_added_amba_base_in
 | |
|  	return q->devtype_data->driver_data & QUADSPI_AMBA_BASE_INTERNAL;
 | |
|  }
 | |
|  
 | |
| +static u32 fsl_get_nor_vendor(struct spi_nor *nor)
 | |
| +{
 | |
| +	u32 vendor_id;
 | |
| +
 | |
| +	if (nor->vendor) {
 | |
| +		if (memcmp(nor->vendor, FLASH_VENDOR_SPANSION_FS,
 | |
| +					sizeof(FLASH_VENDOR_SPANSION_FS) - 1))
 | |
| +			vendor_id = SPANSION_S25FS_FAMILY;
 | |
| +	}
 | |
| +	return vendor_id;
 | |
| +}
 | |
| +
 | |
|  /*
 | |
|   * R/W functions for big- or little-endian registers:
 | |
|   * The qSPI controller's endian is independent of the CPU core's endian.
 | |
| @@ -394,13 +409,15 @@ static void fsl_qspi_init_lut(struct fsl
 | |
|  	int rxfifo = q->devtype_data->rxfifo;
 | |
|  	u32 lut_base;
 | |
|  	int i;
 | |
| -	const struct fsl_qspi_devtype_data *devtype_data = q->devtype_data;
 | |
| +	u32 vendor;
 | |
|  
 | |
|  	struct spi_nor *nor = &q->nor[0];
 | |
|  	u8 addrlen = (nor->addr_width == 3) ? ADDR24BIT : ADDR32BIT;
 | |
|  	u8 read_op = nor->read_opcode;
 | |
|  	u8 read_dm = nor->read_dummy;
 | |
|  
 | |
| +	vendor = fsl_get_nor_vendor(nor);
 | |
| +
 | |
|  	fsl_qspi_unlock_lut(q);
 | |
|  
 | |
|  	/* Clear all the LUT table */
 | |
| @@ -418,12 +435,25 @@ static void fsl_qspi_init_lut(struct fsl
 | |
|  			    LUT1(FSL_READ, PAD1, rxfifo),
 | |
|  				base + QUADSPI_LUT(lut_base + 1));
 | |
|  	} else if (nor->flash_read == SPI_NOR_QUAD) {
 | |
| -		qspi_writel(q, LUT0(CMD, PAD1, read_op) |
 | |
| -			    LUT1(ADDR, PAD1, addrlen),
 | |
| -				base + QUADSPI_LUT(lut_base));
 | |
| -		qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
 | |
| -			    LUT1(FSL_READ, PAD4, rxfifo),
 | |
| -				base + QUADSPI_LUT(lut_base + 1));
 | |
| +		if (q->nor_size == 0x4000000) {
 | |
| +			read_op = 0xEC;
 | |
| +		qspi_writel(q,
 | |
| +			LUT0(CMD, PAD1, read_op) | LUT1(ADDR, PAD4, addrlen),
 | |
| +			base + QUADSPI_LUT(lut_base));
 | |
| +		qspi_writel(q,
 | |
| +			LUT0(MODE, PAD4, 0xff) | LUT1(DUMMY, PAD4, read_dm),
 | |
| +			base + QUADSPI_LUT(lut_base + 1));
 | |
| +		qspi_writel(q,
 | |
| +			LUT0(FSL_READ, PAD4, rxfifo),
 | |
| +			base + QUADSPI_LUT(lut_base + 2));
 | |
| +		} else {
 | |
| +			qspi_writel(q, LUT0(CMD, PAD1, read_op) |
 | |
| +				    LUT1(ADDR, PAD1, addrlen),
 | |
| +					base + QUADSPI_LUT(lut_base));
 | |
| +			qspi_writel(q, LUT0(DUMMY, PAD1, read_dm) |
 | |
| +				    LUT1(FSL_READ, PAD4, rxfifo),
 | |
| +					base + QUADSPI_LUT(lut_base + 1));
 | |
| +		}
 | |
|  	} else if (nor->flash_read == SPI_NOR_DDR_QUAD) {
 | |
|  		/* read mode : 1-4-4, such as Spansion s25fl128s. */
 | |
|  		qspi_writel(q, LUT0(CMD, PAD1, read_op)
 | |
| @@ -510,7 +540,8 @@ static void fsl_qspi_init_lut(struct fsl
 | |
|  	 * use the same value 0x65. But it indicates different meaning.
 | |
|  	 */
 | |
|  	lut_base = SEQID_RDAR_OR_RD_EVCR * 4;
 | |
| -	if (devtype_data->devtype == FSL_QUADSPI_LS2080A) {
 | |
| +
 | |
| +	if (vendor == SPANSION_S25FS_FAMILY) {
 | |
|  		/*
 | |
|  		* Read any device register.
 | |
|  		* Used for Spansion S25FS-S family flash only.
 | |
| --- a/drivers/mtd/spi-nor/spi-nor.c
 | |
| +++ b/drivers/mtd/spi-nor/spi-nor.c
 | |
| @@ -798,7 +798,6 @@ static const struct flash_info spi_nor_i
 | |
|  	{ "s25sl032p",  INFO(0x010215, 0x4d00,  64 * 1024,  64, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 | |
|  	{ "s25sl064p",  INFO(0x010216, 0x4d00,  64 * 1024, 128, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 | |
|  	{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512, 0)},
 | |
| -	{ "s25fs512s",  INFO6(0x010220, 0x4d0081, 128 * 1024, 512, 0)},
 | |
|  	{ "s25fl256s0", INFO(0x010219, 0x4d00, 256 * 1024, 128, 0) },
 | |
|  	{ "s25fl256s1", INFO(0x010219, 0x4d01,  64 * 1024, 512, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 | |
|  	{ "s25fl512s",  INFO(0x010220, 0x4d00, 256 * 1024, 256, SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
 | |
| @@ -965,11 +964,9 @@ static int spansion_s25fs_disable_4kb_er
 | |
|  	ret = nor->read_reg(nor, SPINOR_OP_SPANSION_RDAR, &cr3v, 1);
 | |
|  	if (ret)
 | |
|  		return ret;
 | |
| -/*
 | |
|  	if (!(cr3v & CR3V_4KB_ERASE_UNABLE))
 | |
|  		return -EPERM;
 | |
|  
 | |
| -*/
 | |
|  	return 0;
 | |
|  }
 | |
|  
 | |
| @@ -1336,6 +1333,8 @@ int spi_nor_scan(struct spi_nor *nor, co
 | |
|  
 | |
|  	if (!mtd->name)
 | |
|  		mtd->name = dev_name(dev);
 | |
| +	if (info->name)
 | |
| +		nor->vendor = info->name;
 | |
|  	mtd->priv = nor;
 | |
|  	mtd->type = MTD_NORFLASH;
 | |
|  	mtd->writesize = 1;
 | |
| --- a/include/linux/mtd/spi-nor.h
 | |
| +++ b/include/linux/mtd/spi-nor.h
 | |
| @@ -172,6 +172,7 @@ struct spi_nor {
 | |
|  	bool			sst_write_second;
 | |
|  	u32			flags;
 | |
|  	u8			cmd_buf[SPI_NOR_MAX_CMD_SIZE];
 | |
| +	char			*vendor;
 | |
|  
 | |
|  	int (*prepare)(struct spi_nor *nor, enum spi_nor_ops ops);
 | |
|  	void (*unprepare)(struct spi_nor *nor, enum spi_nor_ops ops);
 |