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
This commit is contained in:
Tom Rini 2024-10-31 10:50:25 -06:00
commit 1d147b74f4
3 changed files with 91 additions and 127 deletions

View File

@ -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;
}
}
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;
}
}
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;
}
#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;

View File

@ -20,12 +20,6 @@ menuconfig SPI
if SPI
config SPI_ADVANCE
bool "Enable the advance feature"
help
Enable the SPI advance feature support. By default this is disabled.
If you intend to use the advance feature support you should enable.
config DM_SPI
bool "Enable Driver Model for SPI drivers"
depends on DM
@ -615,6 +609,12 @@ config ZYNQMP_GQSPI
This option is used to enable ZynqMP QSPI controller driver which
is used to communicate with qspi flash devices.
config SPI_STACKED_PARALLEL
bool "Enable support for stacked or parallel memories"
help
Enable support for stacked/or parallel memories. This functionality
may appear on Xilinx hardware. By default this is disabled.
endif # if DM_SPI
config FSL_ESPI

View File

@ -308,7 +308,7 @@ enum spi_nor_option_flags {
SNOR_F_BROKEN_RESET = BIT(6),
SNOR_F_SOFT_RESET = BIT(7),
SNOR_F_IO_MODE_EN_VOLATILE = BIT(8),
#if defined(CONFIG_SPI_ADVANCE)
#if defined(CONFIG_SPI_STACKED_PARALLEL)
SNOR_F_HAS_STACKED = BIT(9),
SNOR_F_HAS_PARALLEL = BIT(10),
#else