summaryrefslogtreecommitdiff
path: root/drivers/mtd/spi/spi-nor-core.c
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2024-10-31 10:50:25 -0600
committerTom Rini <trini@konsulko.com>2024-10-31 10:50:25 -0600
commit1d147b74f437fb0e85821e8271fe52bc5fd30194 (patch)
tree4d414c85d51bf8899be050e77a774a9d830dcc06 /drivers/mtd/spi/spi-nor-core.c
parentd4c8b8750b564ee83303160414607e17b6873fe2 (diff)
parent43423cdc5dc174468546c7c48f771fe26fe6d101 (diff)
Merge patch series "mtd: spi-nor: Remove recently added nor->addr_width == 3 test"
Tom Rini <trini@konsulko.com> says: In the patch series "spi-nor: Add parallel and stacked memories support" a number of issues have since been raised about problems that now exist on a large number of previously working platforms. Marek Vasut has gone and identified a number of issues and this series is the starting point of attempting to address them and fix the problems with previously existing platforms. Link: https://patchwork.ozlabs.org/project/uboot/list/?series=429932&state=* Link: https://lore.kernel.org/r/20241026201741.171073-1-marek.vasut+renesas@mailbox.org
Diffstat (limited to 'drivers/mtd/spi/spi-nor-core.c')
-rw-r--r--drivers/mtd/spi/spi-nor-core.c200
1 files changed, 82 insertions, 118 deletions
diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c
index f5c9868bbca..a3a62fff213 100644
--- a/drivers/mtd/spi/spi-nor-core.c
+++ b/drivers/mtd/spi/spi-nor-core.c
@@ -1134,12 +1134,10 @@ static int spi_nor_erase(struct mtd_info *mtd, struct erase_info *instr)
offset /= 2;
if (nor->flags & SNOR_F_HAS_STACKED) {
- if (offset >= (mtd->size / 2)) {
- offset = offset - (mtd->size / 2);
+ if (offset >= (mtd->size / 2))
nor->spi->flags |= SPI_XFER_U_PAGE;
- } else {
+ else
nor->spi->flags &= ~SPI_XFER_U_PAGE;
- }
}
#ifdef CONFIG_SPI_FLASH_BAR
ret = write_bar(nor, addr);
@@ -1588,23 +1586,22 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
dev_dbg(nor->dev, "from 0x%08x, len %zd\n", (u32)from, len);
if ((nor->flags & SNOR_F_HAS_PARALLEL) && (offset & 1)) {
- /* We can hit this case when we use file system like ubifs */
+ /* We can hit this case when we use file system like ubifs */
from--;
len++;
is_ofst_odd = true;
}
while (len) {
- if (nor->addr_width == 3) {
- if (nor->flags & SNOR_F_HAS_PARALLEL) {
- bank = (u32)from / (SZ_16M << 0x01);
- rem_bank_len = ((SZ_16M << 0x01) *
- (bank + 1)) - from;
- } else {
- bank = (u32)from / SZ_16M;
- rem_bank_len = (SZ_16M * (bank + 1)) - from;
- }
- }
+ bank = (u32)from / SZ_16M;
+ if (nor->flags & SNOR_F_HAS_PARALLEL)
+ bank /= 2;
+
+ rem_bank_len = SZ_16M * (bank + 1);
+ if (nor->flags & SNOR_F_HAS_PARALLEL)
+ rem_bank_len *= 2;
+ rem_bank_len -= from;
+
offset = from;
if (nor->flags & SNOR_F_HAS_STACKED) {
@@ -1619,13 +1616,11 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
if (nor->flags & SNOR_F_HAS_PARALLEL)
offset /= 2;
- if (nor->addr_width == 3) {
#ifdef CONFIG_SPI_FLASH_BAR
- ret = write_bar(nor, offset);
- if (ret < 0)
- return log_ret(ret);
+ ret = write_bar(nor, offset);
+ if (ret < 0)
+ return log_ret(ret);
#endif
- }
if (len < rem_bank_len)
read_len = len;
@@ -1635,10 +1630,6 @@ static int spi_nor_read(struct mtd_info *mtd, loff_t from, size_t len,
if (read_len == 0)
return -EIO;
- ret = spi_nor_wait_till_ready(nor);
- if (ret)
- goto read_err;
-
ret = nor->read(nor, offset, read_len, buf);
if (ret == 0) {
/* We shouldn't see 0-length reads */
@@ -1977,9 +1968,9 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
return ret;
*retlen += 1; /* We've written only one actual byte */
- ++buf;
- --len;
- ++to;
+ buf++;
+ len--;
+ to++;
}
for (i = 0; i < len; ) {
@@ -1999,7 +1990,7 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
page_offset = do_div(aux, nor->page_size);
}
- offset = (to + i);
+ offset = to + i;
if (nor->flags & SNOR_F_HAS_PARALLEL)
offset /= 2;
@@ -2012,21 +2003,16 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
}
}
- if (nor->addr_width == 3) {
#ifdef CONFIG_SPI_FLASH_BAR
- ret = write_bar(nor, offset);
- if (ret < 0)
- return ret;
+ ret = write_bar(nor, offset);
+ if (ret < 0)
+ return ret;
#endif
- }
+
/* the size of data remaining on the first page */
page_remain = min_t(size_t,
nor->page_size - page_offset, len - i);
- ret = spi_nor_wait_till_ready(nor);
- if (ret)
- goto write_err;
-
write_enable(nor);
/*
* On DTR capable flashes like Micron Xcella the writes cannot
@@ -2086,10 +2072,6 @@ static int spi_nor_write(struct mtd_info *mtd, loff_t to, size_t len,
if (ret)
goto write_err;
- ret = write_disable(nor);
- if (ret)
- goto write_err;
-
*retlen += written;
i += written;
}
@@ -2130,10 +2112,6 @@ static int macronix_quad_enable(struct spi_nor *nor)
if (ret)
return ret;
- ret = write_disable(nor);
- if (ret)
- return ret;
-
ret = read_sr(nor);
if (!(ret > 0 && (ret & SR_QUAD_EN_MX))) {
dev_err(nor->dev, "Macronix Quad bit not set\n");
@@ -2195,7 +2173,7 @@ static int spansion_quad_enable_volatile(struct spi_nor *nor, u32 addr_base,
return -EINVAL;
}
- return write_disable(nor);
+ return 0;
}
#endif
@@ -3069,13 +3047,6 @@ static int spi_nor_init_params(struct spi_nor *nor,
const struct flash_info *info,
struct spi_nor_flash_parameter *params)
{
-#if CONFIG_IS_ENABLED(DM_SPI) && CONFIG_IS_ENABLED(SPI_ADVANCE)
- struct udevice *dev = nor->spi->dev;
- u64 flash_size[SNOR_FLASH_CNT_MAX] = {0};
- u32 idx = 0, i = 0;
- int rc;
-#endif
-
/* Set legacy flash parameters as default. */
memset(params, 0, sizeof(*params));
@@ -3194,62 +3165,69 @@ static int spi_nor_init_params(struct spi_nor *nor,
spi_nor_post_sfdp_fixups(nor, params);
}
-#if CONFIG_IS_ENABLED(DM_SPI) && CONFIG_IS_ENABLED(SPI_ADVANCE)
- /*
- * The flashes that are connected in stacked mode should be of same make.
- * Except the flash size all other properties are identical for all the
- * flashes connected in stacked mode.
- * The flashes that are connected in parallel mode should be identical.
- */
- while (i < SNOR_FLASH_CNT_MAX) {
- rc = ofnode_read_u64_index(dev_ofnode(dev), "stacked-memories",
- idx, &flash_size[i]);
- if (rc == -EINVAL) {
- break;
- } else if (rc == -EOVERFLOW) {
- idx++;
- } else {
- idx++;
- i++;
- if (!(nor->flags & SNOR_F_HAS_STACKED))
- nor->flags |= SNOR_F_HAS_STACKED;
- if (!(nor->spi->flags & SPI_XFER_STACKED))
- nor->spi->flags |= SPI_XFER_STACKED;
+
+ if (CONFIG_IS_ENABLED(SPI_STACKED_PARALLEL)) {
+ u64 flash_size[SNOR_FLASH_CNT_MAX] = { 0 };
+ struct udevice *dev = nor->spi->dev;
+ u32 idx = 0, i = 0;
+ int rc;
+
+ /*
+ * The flashes that are connected in stacked mode should be of same make.
+ * Except the flash size all other properties are identical for all the
+ * flashes connected in stacked mode.
+ * The flashes that are connected in parallel mode should be identical.
+ */
+ while (i < SNOR_FLASH_CNT_MAX) {
+ rc = ofnode_read_u64_index(dev_ofnode(dev), "stacked-memories",
+ idx, &flash_size[i]);
+ if (rc == -EINVAL) {
+ break;
+ } else if (rc == -EOVERFLOW) {
+ idx++;
+ } else {
+ idx++;
+ i++;
+ if (!(nor->flags & SNOR_F_HAS_STACKED))
+ nor->flags |= SNOR_F_HAS_STACKED;
+ if (!(nor->spi->flags & SPI_XFER_STACKED))
+ nor->spi->flags |= SPI_XFER_STACKED;
+ }
}
- }
- i = 0;
- idx = 0;
- while (i < SNOR_FLASH_CNT_MAX) {
- rc = ofnode_read_u64_index(dev_ofnode(dev), "parallel-memories",
- idx, &flash_size[i]);
- if (rc == -EINVAL) {
- break;
- } else if (rc == -EOVERFLOW) {
- idx++;
- } else {
- idx++;
- i++;
- if (!(nor->flags & SNOR_F_HAS_PARALLEL))
- nor->flags |= SNOR_F_HAS_PARALLEL;
+ i = 0;
+ idx = 0;
+ while (i < SNOR_FLASH_CNT_MAX) {
+ rc = ofnode_read_u64_index(dev_ofnode(dev), "parallel-memories",
+ idx, &flash_size[i]);
+ if (rc == -EINVAL) {
+ break;
+ } else if (rc == -EOVERFLOW) {
+ idx++;
+ } else {
+ idx++;
+ i++;
+ if (!(nor->flags & SNOR_F_HAS_PARALLEL))
+ nor->flags |= SNOR_F_HAS_PARALLEL;
+ }
}
- }
- if (nor->flags & (SNOR_F_HAS_STACKED | SNOR_F_HAS_PARALLEL)) {
- params->size = 0;
- for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++)
- params->size += flash_size[idx];
- }
- /*
- * In parallel-memories the erase operation is
- * performed on both the flashes simultaneously
- * so, double the erasesize.
- */
- if (nor->flags & SNOR_F_HAS_PARALLEL) {
- nor->mtd.erasesize <<= 1;
- params->page_size <<= 1;
+ if (nor->flags & (SNOR_F_HAS_STACKED | SNOR_F_HAS_PARALLEL)) {
+ params->size = 0;
+ for (idx = 0; idx < SNOR_FLASH_CNT_MAX; idx++)
+ params->size += flash_size[idx];
+ }
+ /*
+ * In parallel-memories the erase operation is
+ * performed on both the flashes simultaneously
+ * so, double the erasesize.
+ */
+ if (nor->flags & SNOR_F_HAS_PARALLEL) {
+ nor->mtd.erasesize <<= 1;
+ params->page_size <<= 1;
+ }
}
-#endif
+
spi_nor_late_init_fixups(nor, params);
return 0;
@@ -3599,19 +3577,6 @@ static int spi_nor_select_erase(struct spi_nor *nor,
mtd->erasesize = info->sector_size;
}
- if ((JEDEC_MFR(info) == SNOR_MFR_SST) && info->flags & SECT_4K) {
- nor->erase_opcode = SPINOR_OP_BE_4K;
- /*
- * In parallel-memories the erase operation is
- * performed on both the flashes simultaneously
- * so, double the erasesize.
- */
- if (nor->flags & SNOR_F_HAS_PARALLEL)
- mtd->erasesize = 4096 * 2;
- else
- mtd->erasesize = 4096;
- }
-
return 0;
}
@@ -4606,7 +4571,6 @@ int spi_nor_scan(struct spi_nor *nor)
#else
/* Configure the BAR - discover bank cmds and read current bank */
nor->addr_width = 3;
- set_4byte(nor, info, 0);
ret = read_bar(nor, info);
if (ret < 0)
return ret;