From e70ac288708c006251a80b7b69fc49423f19e454 Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Fri, 22 Dec 2023 14:46:05 +0900 Subject: [PATCH] mtd: spi-nor-core: Rework spi_nor_cypress_octal_dtr_enable() Enabling Octal DTR mode in multi-die package parts requires reister setup for each die. That can be done by simple for-loop. write_enable() takes effect to all die at once so we can call it before the loop. Besides we can replace spi_mem_exec_op() calls with spansion_read/write_any_reg(). And finally, we must mask CFR2V[7:4] when changing dummy cycles, as CFR2V[7] indicates current addressing mode and that should be 1 (4-byte address mode) for multi-die package parts. Signed-off-by: Takahiro Kuwano Reviewed-by: Jagan Teki --- drivers/mtd/spi/spi-nor-core.c | 54 +++++++++++++++++----------------- include/linux/mtd/spi-nor.h | 1 + 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/drivers/mtd/spi/spi-nor-core.c b/drivers/mtd/spi/spi-nor-core.c index 87d3ab29cd..f86003ca8c 100644 --- a/drivers/mtd/spi/spi-nor-core.c +++ b/drivers/mtd/spi/spi-nor-core.c @@ -3565,48 +3565,48 @@ static struct spi_nor_fixups s25fl256l_fixups = { */ static int spi_nor_cypress_octal_dtr_enable(struct spi_nor *nor) { - struct spi_mem_op op; + u32 addr; u8 buf; - u8 addr_width = 3; int ret; - /* Use 24 dummy cycles for memory array reads. */ ret = write_enable(nor); if (ret) return ret; - buf = SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24; - op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR2V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(1, &buf, 1)); - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) { - dev_warn(nor->dev, - "failed to set default memory latency value: %d\n", - ret); - return ret; - } - ret = spi_nor_wait_till_ready(nor); - if (ret) - return ret; + /* Use 24 dummy cycles for memory array reads. */ + for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) { + ret = spansion_read_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR2V, 0, + &buf); + if (ret) + return ret; + buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK; + buf |= SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24; + ret = spansion_write_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR2V, + buf); + if (ret) { + dev_warn(nor->dev, "failed to set default memory latency value: %d\n", ret); + return ret; + } + } nor->read_dummy = 24; - /* Set the octal and DTR enable bits. */ ret = write_enable(nor); if (ret) return ret; + /* Set the octal and DTR enable bits. */ buf = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN; - op = (struct spi_mem_op)SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 1), - SPI_MEM_OP_ADDR(addr_width, SPINOR_REG_CYPRESS_CFR5V, 1), - SPI_MEM_OP_NO_DUMMY, - SPI_MEM_OP_DATA_OUT(1, &buf, 1)); - ret = spi_mem_exec_op(nor->spi, &op); - if (ret) { - dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); - return ret; + for (addr = 0; addr < nor->mtd.size; addr += SZ_128M) { + ret = spansion_write_any_reg(nor, + addr + SPINOR_REG_CYPRESS_CFR5V, + buf); + if (ret) { + dev_warn(nor->dev, "Failed to enable octal DTR mode\n"); + return ret; + } } return 0; diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h index 8a94e12037..d1dbf3eadb 100644 --- a/include/linux/mtd/spi-nor.h +++ b/include/linux/mtd/spi-nor.h @@ -185,6 +185,7 @@ #define SPINOR_REG_CYPRESS_STR1V 0x00800000 #define SPINOR_REG_CYPRESS_CFR1V 0x00800002 #define SPINOR_REG_CYPRESS_CFR2V 0x00800003 +#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0) #define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb #define SPINOR_REG_CYPRESS_CFR3V 0x00800004 #define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */ -- 2.39.5