From c0aa05123f116c709c816130ef4e55a6748e5e1a Mon Sep 17 00:00:00 2001 From: Takahiro Kuwano Date: Wed, 26 Jul 2023 10:52:49 +0300 Subject: mtd: spi-nor: spansion: prepare octal dtr methods for multi chip support Infineon's multi-chip package (MCP) devices require the octal DTR configuration to be set for each die. Split common code in dedicated methods to ease the octal DDR MCP support addition. Signed-off-by: Takahiro Kuwano Link: https://lore.kernel.org/r/20230726075257.12985-4-tudor.ambarus@linaro.org Signed-off-by: Tudor Ambarus --- drivers/mtd/spi-nor/spansion.c | 50 +++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'drivers/mtd') diff --git a/drivers/mtd/spi-nor/spansion.c b/drivers/mtd/spi-nor/spansion.c index 6460d2247bdf..51eabddf2b16 100644 --- a/drivers/mtd/spi-nor/spansion.c +++ b/drivers/mtd/spi-nor/spansion.c @@ -156,7 +156,7 @@ static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor) return 1; } -static int cypress_nor_octal_dtr_en(struct spi_nor *nor) +static int cypress_nor_set_memlat(struct spi_nor *nor, u64 addr) { struct spi_mem_op op; u8 *buf = nor->bouncebuf; @@ -164,8 +164,7 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) u8 addr_mode_nbytes = nor->params->addr_mode_nbytes; op = (struct spi_mem_op) - CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, - SPINOR_REG_CYPRESS_CFR2V, 0, buf); + CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0, buf); ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto); if (ret) @@ -176,8 +175,7 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) *buf |= FIELD_PREP(SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK, SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24); op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, - SPINOR_REG_CYPRESS_CFR2V, 1, buf); + CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1, buf); ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); if (ret) @@ -185,13 +183,33 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) nor->read_dummy = 24; + return 0; +} + +static int cypress_nor_set_octal_dtr_bits(struct spi_nor *nor, u64 addr) +{ + struct spi_mem_op op; + u8 *buf = nor->bouncebuf; + /* Set the octal and DTR enable bits. */ buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN; op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, - SPINOR_REG_CYPRESS_CFR5V, 1, buf); + CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes, + addr, 1, buf); - ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); + return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto); +} + +static int cypress_nor_octal_dtr_en(struct spi_nor *nor) +{ + u8 *buf = nor->bouncebuf; + int ret; + + ret = cypress_nor_set_memlat(nor, SPINOR_REG_CYPRESS_CFR2V); + if (ret) + return ret; + + ret = cypress_nor_set_octal_dtr_bits(nor, SPINOR_REG_CYPRESS_CFR5V); if (ret) return ret; @@ -209,11 +227,10 @@ static int cypress_nor_octal_dtr_en(struct spi_nor *nor) return 0; } -static int cypress_nor_octal_dtr_dis(struct spi_nor *nor) +static int cypress_nor_set_single_spi_bits(struct spi_nor *nor, u64 addr) { struct spi_mem_op op; u8 *buf = nor->bouncebuf; - int ret; /* * The register is 1-byte wide, but 1-byte transactions are not allowed @@ -223,9 +240,16 @@ static int cypress_nor_octal_dtr_dis(struct spi_nor *nor) buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS; buf[1] = 0; op = (struct spi_mem_op) - CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, - SPINOR_REG_CYPRESS_CFR5V, 2, buf); - ret = spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); + CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, addr, 2, buf); + return spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR); +} + +static int cypress_nor_octal_dtr_dis(struct spi_nor *nor) +{ + u8 *buf = nor->bouncebuf; + int ret; + + ret = cypress_nor_set_single_spi_bits(nor, SPINOR_REG_CYPRESS_CFR5V); if (ret) return ret; -- cgit v1.2.3