mirror of
https://github.com/u-boot/u-boot.git
synced 2024-11-30 08:03:32 +08:00
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:
commit
1d147b74f4
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user