mtd: spi-nor: core: Move spi_nor_set_addr_width() in spi_nor_setup()
spi_nor_setup() configures the SPI NOR memory. Setting the addr width is too a configuration, hence we can move the spi_nor_set_addr_width() in spi_nor_setup(). Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> Reviewed-by: Pratyush Yadav <p.yadav@ti.com> Reviewed-by: Michael Walle <michael@walle.cc> Link: https://lore.kernel.org/r/20211207140254.87681-11-tudor.ambarus@microchip.com
This commit is contained in:
parent
5dabf5770f
commit
b7ed1a3731
@ -2484,13 +2484,61 @@ static int spi_nor_default_setup(struct spi_nor *nor,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_nor_set_addr_width(struct spi_nor *nor)
|
||||
{
|
||||
if (nor->addr_width) {
|
||||
/* already configured from SFDP */
|
||||
} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
|
||||
/*
|
||||
* In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
|
||||
* in this protocol an odd address width cannot be used because
|
||||
* then the address phase would only span a cycle and a half.
|
||||
* Half a cycle would be left over. We would then have to start
|
||||
* the dummy phase in the middle of a cycle and so too the data
|
||||
* phase, and we will end the transaction with half a cycle left
|
||||
* over.
|
||||
*
|
||||
* Force all 8D-8D-8D flashes to use an address width of 4 to
|
||||
* avoid this situation.
|
||||
*/
|
||||
nor->addr_width = 4;
|
||||
} else if (nor->info->addr_width) {
|
||||
nor->addr_width = nor->info->addr_width;
|
||||
} else {
|
||||
nor->addr_width = 3;
|
||||
}
|
||||
|
||||
if (nor->addr_width == 3 && nor->params->size > 0x1000000) {
|
||||
/* enable 4-byte addressing if the device exceeds 16MiB */
|
||||
nor->addr_width = 4;
|
||||
}
|
||||
|
||||
if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
|
||||
dev_dbg(nor->dev, "address width is too large: %u\n",
|
||||
nor->addr_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set 4byte opcodes when possible. */
|
||||
if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES &&
|
||||
!(nor->flags & SNOR_F_HAS_4BAIT))
|
||||
spi_nor_set_4byte_opcodes(nor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spi_nor_setup(struct spi_nor *nor,
|
||||
const struct spi_nor_hwcaps *hwcaps)
|
||||
{
|
||||
if (!nor->params->setup)
|
||||
return 0;
|
||||
int ret;
|
||||
|
||||
return nor->params->setup(nor, hwcaps);
|
||||
if (nor->params->setup) {
|
||||
ret = nor->params->setup(nor, hwcaps);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return spi_nor_set_addr_width(nor);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -3078,49 +3126,6 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int spi_nor_set_addr_width(struct spi_nor *nor)
|
||||
{
|
||||
if (nor->addr_width) {
|
||||
/* already configured from SFDP */
|
||||
} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
|
||||
/*
|
||||
* In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
|
||||
* in this protocol an odd address width cannot be used because
|
||||
* then the address phase would only span a cycle and a half.
|
||||
* Half a cycle would be left over. We would then have to start
|
||||
* the dummy phase in the middle of a cycle and so too the data
|
||||
* phase, and we will end the transaction with half a cycle left
|
||||
* over.
|
||||
*
|
||||
* Force all 8D-8D-8D flashes to use an address width of 4 to
|
||||
* avoid this situation.
|
||||
*/
|
||||
nor->addr_width = 4;
|
||||
} else if (nor->info->addr_width) {
|
||||
nor->addr_width = nor->info->addr_width;
|
||||
} else {
|
||||
nor->addr_width = 3;
|
||||
}
|
||||
|
||||
if (nor->addr_width == 3 && nor->params->size > 0x1000000) {
|
||||
/* enable 4-byte addressing if the device exceeds 16MiB */
|
||||
nor->addr_width = 4;
|
||||
}
|
||||
|
||||
if (nor->addr_width > SPI_NOR_MAX_ADDR_WIDTH) {
|
||||
dev_dbg(nor->dev, "address width is too large: %u\n",
|
||||
nor->addr_width);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Set 4byte opcodes when possible. */
|
||||
if (nor->addr_width == 4 && nor->flags & SNOR_F_4B_OPCODES &&
|
||||
!(nor->flags & SNOR_F_HAS_4BAIT))
|
||||
spi_nor_set_4byte_opcodes(nor);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spi_nor_debugfs_init(struct spi_nor *nor,
|
||||
const struct flash_info *info)
|
||||
{
|
||||
@ -3252,15 +3257,12 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
|
||||
* - select op codes for (Fast) Read, Page Program and Sector Erase.
|
||||
* - set the number of dummy cycles (mode cycles + wait states).
|
||||
* - set the SPI protocols for register and memory accesses.
|
||||
* - set the address width.
|
||||
*/
|
||||
ret = spi_nor_setup(nor, hwcaps);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = spi_nor_set_addr_width(nor);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Send all the required SPI flash commands to initialize device */
|
||||
ret = spi_nor_init(nor);
|
||||
if (ret)
|
||||
|
Loading…
Reference in New Issue
Block a user