diff options
Diffstat (limited to 'drivers/mtd')
| -rw-r--r-- | drivers/mtd/spi/sf_internal.h | 10 | ||||
| -rw-r--r-- | drivers/mtd/spi/sf_ops.c | 26 | ||||
| -rw-r--r-- | drivers/mtd/spi/sf_probe.c | 28 | 
3 files changed, 62 insertions, 2 deletions
| diff --git a/drivers/mtd/spi/sf_internal.h b/drivers/mtd/spi/sf_internal.h index dcc9014e5..dca34f7a7 100644 --- a/drivers/mtd/spi/sf_internal.h +++ b/drivers/mtd/spi/sf_internal.h @@ -12,6 +12,11 @@  #define SPI_FLASH_16MB_BOUN		0x1000000 +/* CFI Manufacture ID's */ +#define SPI_FLASH_CFI_MFR_SPANSION	0x01 +#define SPI_FLASH_CFI_MFR_STMICRO	0x20 +#define SPI_FLASH_CFI_MFR_WINBOND	0xef +  /* SECT flags */  #define SECT_4K				(1 << 1)  #define SECT_32K			(1 << 2) @@ -52,6 +57,7 @@  /* Common status */  #define STATUS_WIP			0x01 +#define STATUS_QEB_WINSPAN		(1 << 1)  #define STATUS_PEC			0x80  /* Flash timeout values */ @@ -93,8 +99,8 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len);  /* Program the status register */  int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr); -/* Set quad enbale bit */ -int spi_flash_set_qeb(struct spi_flash *flash); +/* Set quad enbale bit for winbond and spansion flashes */ +int spi_flash_set_qeb_winspan(struct spi_flash *flash);  /* Enable writing on the SPI flash */  static inline int spi_flash_cmd_write_enable(struct spi_flash *flash) diff --git a/drivers/mtd/spi/sf_ops.c b/drivers/mtd/spi/sf_ops.c index 39e06ecae..827f71912 100644 --- a/drivers/mtd/spi/sf_ops.c +++ b/drivers/mtd/spi/sf_ops.c @@ -38,6 +38,7 @@ int spi_flash_cmd_write_status(struct spi_flash *flash, u8 sr)  	return 0;  } +#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND)  static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 cr)  {  	u8 data[2]; @@ -62,6 +63,31 @@ static int spi_flash_cmd_write_config(struct spi_flash *flash, u8 cr)  	return 0;  } +int spi_flash_set_qeb_winspan(struct spi_flash *flash) +{ +	u8 qeb_status; +	u8 cmd; +	int ret; + +	cmd = CMD_READ_CONFIG; +	ret = spi_flash_read_common(flash, &cmd, 1, &qeb_status, 1); +	if (ret < 0) { +		debug("SF: fail to read config register\n"); +		return ret; +	} + +	if (qeb_status & STATUS_QEB_WINSPAN) { +		debug("SF: Quad enable bit is already set\n"); +	} else { +		ret = spi_flash_cmd_write_config(flash, STATUS_QEB_WINSPAN); +		if (ret < 0) +			return ret; +	} + +	return ret; +} +#endif +  #ifdef CONFIG_SPI_FLASH_BAR  static int spi_flash_cmd_bankaddr_write(struct spi_flash *flash, u8 bank_sel)  { diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c index 3fa7363da..8b2972c7a 100644 --- a/drivers/mtd/spi/sf_probe.c +++ b/drivers/mtd/spi/sf_probe.c @@ -165,6 +165,25 @@ static u8 spi_read_cmds_array[] = {  	CMD_READ_QUAD_OUTPUT_FAST,  }; +static int spi_flash_set_qeb(struct spi_flash *flash, u8 idcode0) +{ +	switch (idcode0) { +#if defined(CONFIG_SPI_FLASH_SPANSION) || defined(CONFIG_SPI_FLASH_WINBOND) +	case SPI_FLASH_CFI_MFR_SPANSION: +	case SPI_FLASH_CFI_MFR_WINBOND: +		return spi_flash_set_qeb_winspan(flash); +#endif +#ifdef CONFIG_SPI_FLASH_STMICRO +	case SPI_FLASH_CFI_MFR_STMICRO: +		debug("SF: QEB is volatile for %02x flash\n", idcode0); +		return 0; +#endif +	default: +		printf("SF: Need set QEB func for %02x flash\n", idcode0); +		return -1; +	} +} +  static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,  		u8 *idcode)  { @@ -250,6 +269,15 @@ static struct spi_flash *spi_flash_validate_params(struct spi_slave *spi,  		/* Go for default supported write cmd */  		flash->write_cmd = CMD_PAGE_PROGRAM; +	/* Set the quad enable bit - only for quad commands */ +	if ((flash->read_cmd == CMD_READ_QUAD_OUTPUT_FAST) || +	    (flash->write_cmd == CMD_QUAD_PAGE_PROGRAM)) { +		if (spi_flash_set_qeb(flash, idcode[0])) { +			debug("SF: Fail to set QEB for %02x\n", idcode[0]); +			return NULL; +		} +	} +  	/* Poll cmd seclection */  	flash->poll_cmd = CMD_READ_STATUS;  #ifdef CONFIG_SPI_FLASH_STMICRO |