From b8c90c2d903aeccc10a0011e2937cb4eeb3d4655 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Fri, 18 Jun 2021 17:39:04 +0200 Subject: [PATCH] mtd: spi-nor: Fix read SFDP data in dual parallel mode Reading the SFDP data is broken in two ways in dual parallel mode in the current implementation. 1) It reads the data interleaved from both chips, which results in data that can not be parsed. Since both chips have to be identical for dual parallel mode the SFDP data will also be identical. So only read the data from one of the chips. 2) The page, erase and chip size are not update to reflect that they should be twice as large in dual parallel mode. Fix this by moving the update of those parameter after running the SFDP detection rather than doing it before. Signed-off-by: Lars-Peter Clausen Acked-by: Ashok Reddy Soma --- drivers/mtd/spi/spi-nor-core.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 0487a27d343..21e4300ceda 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -1786,10 +1786,11 @@ static int spi_nor_read_sfdp(struct spi_nor *nor, u32 addr, nor->addr_width = 3; nor->read_dummy = 8; - if (nor->isparallel) - nor->spi->flags |= SPI_XFER_STRIPE; - while (len) { + /* Both chips are identical, so should be the SFDP data */ + if (nor->isparallel) + nor->spi->flags |= SPI_XFER_LOWER; + ret = nor->read(nor, addr, len, (u8 *)buf); if (!ret || ret > len) { ret = -EIO; @@ -2380,12 +2381,6 @@ static int spi_nor_init_params(struct spi_nor *nor, params->size = info->sector_size * info->n_sectors; params->page_size = info->page_size; - if (nor->isparallel) - params->page_size <<= nor->shift; - - if (nor->isparallel || nor->isstacked) - params->size <<= nor->shift; - /* (Fast) Read settings. */ params->hwcaps.mask |= SNOR_HWCAPS_READ; spi_nor_set_read_settings(¶ms->reads[SNOR_CMD_READ], @@ -2470,6 +2465,14 @@ static int spi_nor_init_params(struct spi_nor *nor, } } + if (nor->isparallel) { + nor->mtd.erasesize <<= nor->shift; + params->page_size <<= nor->shift; + } + + if (nor->isparallel || nor->isstacked) + params->size <<= nor->shift; + return 0; } -- 2.47.3