Merge "ipq807x: Add 4byte mode support for Winbond nor flash"

This commit is contained in:
Linux Build Service Account 2017-10-25 10:55:29 -07:00 committed by Gerrit - the friendly Code Review server
commit 636aa76e04
6 changed files with 66 additions and 15 deletions

View file

@ -253,6 +253,25 @@ unsigned int get_rootfs_active_partition(void)
return 0; /* alt partition not available */
}
/*
* To determine the spi flash addr is in 3 byte
* or 4 byte.
*/
unsigned int get_smem_spi_addr_len(void)
{
int ret;
uint32_t spi_flash_addr_len;
ret = smem_read_alloc_entry(SMEM_SPI_FLASH_ADDR_LEN,
&spi_flash_addr_len, sizeof(uint32_t));
if (ret != 0) {
printf("smem: read spi flash address len failed\n");
spi_flash_addr_len = 0;
}
return spi_flash_addr_len;
}
unsigned int get_partition_table_offset(void)
{
int ret;

View file

@ -144,6 +144,7 @@ typedef struct
extern qca_smem_bootconfig_info_t qca_smem_bootconfig_info;
int smem_bootconfig_info(void);
unsigned int get_smem_spi_addr_len(void);
unsigned int get_rootfs_active_partition(void);
unsigned int get_mibib_active_partition(void);
void qca_smem_part_to_mtdparts(char *mtdid);

View file

@ -223,9 +223,10 @@ typedef enum {
SMEM_BOOT_FLASH_DENSITY = 502,
SMEM_BOOT_DUALPARTINFO = 503,
SMEM_PARTITION_TABLE_OFFSET = 504,
SMEM_SPI_FLASH_ADDR_LEN = 505,
SMEM_FIRST_VALID_TYPE = SMEM_SPINLOCK_ARRAY,
SMEM_LAST_VALID_TYPE = SMEM_PARTITION_TABLE_OFFSET,
SMEM_MAX_SIZE = SMEM_PARTITION_TABLE_OFFSET + 1,
SMEM_LAST_VALID_TYPE = SMEM_SPI_FLASH_ADDR_LEN,
SMEM_MAX_SIZE = SMEM_SPI_FLASH_ADDR_LEN + 1,
} smem_mem_type_t;
/* Reserved-memory node names*/

View file

@ -54,7 +54,7 @@ enum spi_nor_option_flags {
};
#define SPI_FLASH_3B_ADDR_LEN 3
#define SPI_FLASH_CMD_LEN (1 + SPI_FLASH_3B_ADDR_LEN)
#define SPI_FLASH_4B_ADDR_LEN 4
#define SPI_FLASH_16MB_BOUN 0x1000000
/* CFI Manufacture ID's */

View file

@ -21,12 +21,19 @@
DECLARE_GLOBAL_DATA_PTR;
static void spi_flash_addr(u32 addr, u8 *cmd)
static void spi_flash_addr(struct spi_flash *flash, u32 addr, u8 *cmd)
{
/* cmd[0] is actual command */
cmd[1] = addr >> 16;
cmd[2] = addr >> 8;
cmd[3] = addr >> 0;
cmd[1] = addr >> (flash->addr_width * 8 - 8);
cmd[2] = addr >> (flash->addr_width * 8 - 16);
cmd[3] = addr >> (flash->addr_width * 8 - 24);
if (flash->addr_width == SPI_FLASH_4B_ADDR_LEN)
cmd[4] = addr >> (flash->addr_width * 8 - 32);
}
static int spi_flash_cmdsz(struct spi_flash *flash)
{
return 1 + flash->addr_width;
}
/* Read commands array */
@ -122,6 +129,7 @@ static int write_cr(struct spi_flash *flash, u8 wc)
#endif
#ifdef CONFIG_SPI_FLASH_BAR
static int spi_flash_write_bar(struct spi_flash *flash, u32 offset)
{
u8 cmd, bank_sel;
@ -302,7 +310,7 @@ int spi_flash_write_common(struct spi_flash *flash, const u8 *cmd,
int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
{
u32 erase_size, erase_addr;
u8 cmd[SPI_FLASH_CMD_LEN];
u8 *cmd, cmdsz;
int ret = -1;
erase_size = flash->erase_size;
@ -319,6 +327,13 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
}
}
cmdsz = spi_flash_cmdsz(flash);
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
return -ENOMEM;
}
cmd[0] = flash->erase_cmd;
while (len) {
erase_addr = offset;
@ -332,12 +347,12 @@ int spi_flash_cmd_erase_ops(struct spi_flash *flash, u32 offset, size_t len)
if (ret < 0)
return ret;
#endif
spi_flash_addr(erase_addr, cmd);
spi_flash_addr(flash, erase_addr, cmd);
debug("SF: erase %2x %2x %2x %2x (%x)\n", cmd[0], cmd[1],
cmd[2], cmd[3], erase_addr);
ret = spi_flash_write_common(flash, cmd, sizeof(cmd), NULL, 0);
ret = spi_flash_write_common(flash, cmd, cmdsz, NULL, 0);
if (ret < 0) {
debug("SF: erase failed\n");
break;
@ -356,7 +371,7 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
unsigned long byte_addr, page_size;
u32 write_addr;
size_t chunk_len, actual;
u8 cmd[SPI_FLASH_CMD_LEN];
u8 *cmd, cmdsz;
int ret = -1;
page_size = flash->page_size;
@ -369,6 +384,13 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
}
}
cmdsz = spi_flash_cmdsz(flash);
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
return -ENOMEM;
}
cmd[0] = flash->write_cmd;
for (actual = 0; actual < len; actual += chunk_len) {
write_addr = offset;
@ -389,12 +411,12 @@ int spi_flash_cmd_write_ops(struct spi_flash *flash, u32 offset,
chunk_len = min(chunk_len,
(size_t)flash->spi->max_write_size);
spi_flash_addr(write_addr, cmd);
spi_flash_addr(flash, write_addr, cmd);
debug("SF: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len);
ret = spi_flash_write_common(flash, cmd, sizeof(cmd),
ret = spi_flash_write_common(flash, cmd, cmdsz,
buf + actual, chunk_len);
if (ret < 0) {
debug("SF: write failed\n");
@ -457,7 +479,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
return 0;
}
cmdsz = SPI_FLASH_CMD_LEN + flash->dummy_byte;
cmdsz = spi_flash_cmdsz(flash) + flash->dummy_byte;
cmd = calloc(1, cmdsz);
if (!cmd) {
debug("SF: Failed to allocate cmd\n");
@ -485,7 +507,7 @@ int spi_flash_cmd_read_ops(struct spi_flash *flash, u32 offset,
else
read_len = remain_len;
spi_flash_addr(read_addr, cmd);
spi_flash_addr(flash, read_addr, cmd);
ret = spi_flash_read_common(flash, cmd, cmdsz, data, read_len);
if (ret < 0) {
@ -1071,6 +1093,13 @@ int spi_flash_scan(struct spi_flash *flash)
flash->dummy_byte = 1;
}
flash->addr_width = SPI_FLASH_3B_ADDR_LEN;
printf("SPI_ADDR_LEN=%x\n",get_smem_spi_addr_len());
if ((flash->size > SPI_FLASH_16MB_BOUN) &&
(get_smem_spi_addr_len() == SPI_FLASH_4B_ADDR_LEN)) {
if (idcode[0] == SPI_FLASH_CFI_MFR_WINBOND)
flash->addr_width = SPI_FLASH_4B_ADDR_LEN;
}
#ifdef CONFIG_SPI_FLASH_STMICRO
if (params->flags & E_FSR)
flash->flags |= SNOR_F_USE_FSR;

View file

@ -73,6 +73,7 @@ struct spi_flash {
const char *name;
u8 dual_flash;
u8 shift;
u8 addr_width;
u16 flags;
u32 size;