The Linux Kernel Mailing List
 help / color / mirror / Atom feed
diff for duplicates of <20200916124418.833-5-p.yadav@ti.com>

diff --git a/a/1.txt b/N1/1.txt
index aa70e2c..8b13789 100644
--- a/a/1.txt
+++ b/N1/1.txt
@@ -1,681 +1 @@
-Double Transfer Rate (DTR) is SPI protocol in which data is transferred
-on each clock edge as opposed to on each clock cycle. Make
-framework-level changes to allow supporting flashes in DTR mode.
 
-Right now, mixed DTR modes are not supported. So, for example a mode
-like 4S-4D-4D will not work. All phases need to be either DTR or STR.
-
-Signed-off-by: Pratyush Yadav <p.yadav@ti.com>
----
- drivers/mtd/spi-nor/core.c  | 222 +++++++++++++++++++++++++++++-------
- drivers/mtd/spi-nor/core.h  |   7 ++
- drivers/mtd/spi-nor/sfdp.c  |   9 +-
- include/linux/mtd/spi-nor.h |  51 ++++++---
- 4 files changed, 236 insertions(+), 53 deletions(-)
-
-diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c
-index 7009cb702e22..7445d7122304 100644
---- a/drivers/mtd/spi-nor/core.c
-+++ b/drivers/mtd/spi-nor/core.c
-@@ -40,6 +40,78 @@
- 
- #define SPI_NOR_MAX_ADDR_WIDTH	4
- 
-+/**
-+ * spi_nor_get_cmd_ext() - Get the command opcode extension based on the
-+ *			   extension type.
-+ * @nor:		pointer to a 'struct spi_nor'
-+ * @op:			pointer to the 'struct spi_mem_op' whose properties
-+ *			need to be initialized.
-+ *
-+ * Right now, only "repeat" and "invert" are supported.
-+ *
-+ * Return: The opcode extension.
-+ */
-+static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,
-+			      const struct spi_mem_op *op)
-+{
-+	switch (nor->cmd_ext_type) {
-+	case SPI_NOR_EXT_INVERT:
-+		return ~op->cmd.opcode;
-+
-+	case SPI_NOR_EXT_REPEAT:
-+		return op->cmd.opcode;
-+
-+	default:
-+		dev_err(nor->dev, "Unknown command extension type\n");
-+		return 0;
-+	}
-+}
-+
-+/**
-+ * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op.
-+ * @nor:		pointer to a 'struct spi_nor'
-+ * @op:			pointer to the 'struct spi_mem_op' whose properties
-+ *			need to be initialized.
-+ * @proto:		the protocol from which the properties need to be set.
-+ */
-+void spi_nor_spimem_setup_op(const struct spi_nor *nor,
-+			     struct spi_mem_op *op,
-+			     const enum spi_nor_protocol proto)
-+{
-+	u8 ext;
-+
-+	op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(proto);
-+
-+	if (op->addr.nbytes)
-+		op->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto);
-+
-+	if (op->dummy.nbytes)
-+		op->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto);
-+
-+	if (op->data.nbytes)
-+		op->data.buswidth = spi_nor_get_protocol_data_nbits(proto);
-+
-+	if (spi_nor_protocol_is_dtr(proto)) {
-+		/*
-+		 * SPIMEM supports mixed DTR modes, but right now we can only
-+		 * have all phases either DTR or STR. IOW, SPIMEM can have
-+		 * something like 4S-4D-4D, but SPI NOR can't. So, set all 4
-+		 * phases to either DTR or STR.
-+		 */
-+		op->cmd.dtr = true;
-+		op->addr.dtr = true;
-+		op->dummy.dtr = true;
-+		op->data.dtr = true;
-+
-+		/* 2 bytes per clock cycle in DTR mode. */
-+		op->dummy.nbytes *= 2;
-+
-+		ext = spi_nor_get_cmd_ext(nor, op);
-+		op->cmd.opcode = (op->cmd.opcode << 8) | ext;
-+		op->cmd.nbytes = 2;
-+	}
-+}
-+
- /**
-  * spi_nor_spimem_bounce() - check if a bounce buffer is needed for the data
-  *                           transfer
-@@ -85,17 +157,26 @@ static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op *op)
- static int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,
- 			    size_t len)
- {
-+	if (spi_nor_protocol_is_dtr(nor->reg_proto))
-+		return -EOPNOTSUPP;
-+
- 	return nor->controller_ops->read_reg(nor, opcode, buf, len);
- }
- 
- static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,
- 			     size_t len)
- {
-+	if (spi_nor_protocol_is_dtr(nor->reg_proto))
-+		return -EOPNOTSUPP;
-+
- 	return nor->controller_ops->write_reg(nor, opcode, buf, len);
- }
- 
- static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs)
- {
-+	if (spi_nor_protocol_is_dtr(nor->write_proto))
-+		return -EOPNOTSUPP;
-+
- 	return nor->controller_ops->erase(nor, offs);
- }
- 
-@@ -121,14 +202,12 @@ static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from,
- 	ssize_t nbytes;
- 	int error;
- 
--	/* get transfer protocols. */
--	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);
--	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);
--	op.dummy.buswidth = op.addr.buswidth;
--	op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
-+	spi_nor_spimem_setup_op(nor, &op, nor->read_proto);
- 
- 	/* convert the dummy cycles to the number of bytes */
- 	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
-+	if (spi_nor_protocol_is_dtr(nor->read_proto))
-+		op.dummy.nbytes *= 2;
- 
- 	usebouncebuf = spi_nor_spimem_bounce(nor, &op);
- 
-@@ -186,13 +265,11 @@ static ssize_t spi_nor_spimem_write_data(struct spi_nor *nor, loff_t to,
- 	ssize_t nbytes;
- 	int error;
- 
--	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
--	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
--	op.data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
--
- 	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
- 		op.addr.nbytes = 0;
- 
-+	spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
-+
- 	if (spi_nor_spimem_bounce(nor, &op))
- 		memcpy(nor->bouncebuf, buf, op.data.nbytes);
- 
-@@ -244,6 +321,8 @@ int spi_nor_write_enable(struct spi_nor *nor)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_WREN, NULL, 0);
-@@ -272,6 +351,8 @@ int spi_nor_write_disable(struct spi_nor *nor)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_WRDI, NULL, 0);
-@@ -302,6 +383,8 @@ static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_IN(1, sr, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_read_reg(nor, SPINOR_OP_RDSR, sr, 1);
-@@ -332,6 +415,8 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_IN(1, fsr, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_read_reg(nor, SPINOR_OP_RDFSR, fsr, 1);
-@@ -363,6 +448,8 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_IN(1, cr, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_read_reg(nor, SPINOR_OP_RDCR, cr, 1);
-@@ -396,6 +483,8 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
- 				  SPI_MEM_OP_NO_DUMMY,
- 				  SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor,
-@@ -432,6 +521,8 @@ static int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_BRWR, nor->bouncebuf, 1);
-@@ -463,6 +554,8 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_WREAR, nor->bouncebuf, 1);
-@@ -493,6 +586,8 @@ int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_IN(1, sr, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_read_reg(nor, SPINOR_OP_XRDSR, sr, 1);
-@@ -537,6 +632,8 @@ static void spi_nor_clear_sr(struct spi_nor *nor)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_CLSR, NULL, 0);
-@@ -600,6 +697,8 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);
-@@ -743,6 +842,8 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_OUT(len, sr, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_WRSR, sr, len);
-@@ -944,6 +1045,8 @@ static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_OUT(1, sr2, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);
-@@ -977,6 +1080,8 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_DATA_IN(1, sr2, 1));
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);
-@@ -1007,6 +1112,8 @@ static int spi_nor_erase_chip(struct spi_nor *nor)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
-+
- 		ret = spi_mem_exec_op(nor->spimem, &op);
- 	} else {
- 		ret = spi_nor_write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0);
-@@ -1148,6 +1255,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)
- 				   SPI_MEM_OP_NO_DUMMY,
- 				   SPI_MEM_OP_NO_DATA);
- 
-+		spi_nor_spimem_setup_op(nor, &op, nor->write_proto);
-+
- 		return spi_mem_exec_op(nor->spimem, &op);
- 	} else if (nor->controller_ops->erase) {
- 		return spi_nor_controller_ops_erase(nor, addr);
-@@ -2273,6 +2382,7 @@ int spi_nor_hwcaps_read2cmd(u32 hwcaps)
- 		{ SNOR_HWCAPS_READ_1_8_8,	SNOR_CMD_READ_1_8_8 },
- 		{ SNOR_HWCAPS_READ_8_8_8,	SNOR_CMD_READ_8_8_8 },
- 		{ SNOR_HWCAPS_READ_1_8_8_DTR,	SNOR_CMD_READ_1_8_8_DTR },
-+		{ SNOR_HWCAPS_READ_8_8_8_DTR,	SNOR_CMD_READ_8_8_8_DTR },
- 	};
- 
- 	return spi_nor_hwcaps2cmd(hwcaps, hwcaps_read2cmd,
-@@ -2289,6 +2399,7 @@ static int spi_nor_hwcaps_pp2cmd(u32 hwcaps)
- 		{ SNOR_HWCAPS_PP_1_1_8,		SNOR_CMD_PP_1_1_8 },
- 		{ SNOR_HWCAPS_PP_1_8_8,		SNOR_CMD_PP_1_8_8 },
- 		{ SNOR_HWCAPS_PP_8_8_8,		SNOR_CMD_PP_8_8_8 },
-+		{ SNOR_HWCAPS_PP_8_8_8_DTR,	SNOR_CMD_PP_8_8_8_DTR },
- 	};
- 
- 	return spi_nor_hwcaps2cmd(hwcaps, hwcaps_pp2cmd,
-@@ -2339,15 +2450,15 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor,
- {
- 	struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(read->opcode, 1),
- 					  SPI_MEM_OP_ADDR(3, 0, 1),
--					  SPI_MEM_OP_DUMMY(0, 1),
--					  SPI_MEM_OP_DATA_IN(0, NULL, 1));
-+					  SPI_MEM_OP_DUMMY(1, 1),
-+					  SPI_MEM_OP_DATA_IN(1, NULL, 1));
- 
--	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(read->proto);
--	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(read->proto);
--	op.data.buswidth = spi_nor_get_protocol_data_nbits(read->proto);
--	op.dummy.buswidth = op.addr.buswidth;
--	op.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) *
--			  op.dummy.buswidth / 8;
-+	spi_nor_spimem_setup_op(nor, &op, read->proto);
-+
-+	/* convert the dummy cycles to the number of bytes */
-+	op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
-+	if (spi_nor_protocol_is_dtr(nor->read_proto))
-+		op.dummy.nbytes *= 2;
- 
- 	return spi_nor_spimem_check_op(nor, &op);
- }
-@@ -2366,11 +2477,9 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor,
- 	struct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(pp->opcode, 1),
- 					  SPI_MEM_OP_ADDR(3, 0, 1),
- 					  SPI_MEM_OP_NO_DUMMY,
--					  SPI_MEM_OP_DATA_OUT(0, NULL, 1));
-+					  SPI_MEM_OP_DATA_OUT(1, NULL, 1));
- 
--	op.cmd.buswidth = spi_nor_get_protocol_inst_nbits(pp->proto);
--	op.addr.buswidth = spi_nor_get_protocol_addr_nbits(pp->proto);
--	op.data.buswidth = spi_nor_get_protocol_data_nbits(pp->proto);
-+	spi_nor_spimem_setup_op(nor, &op, pp->proto);
- 
- 	return spi_nor_spimem_check_op(nor, &op);
- }
-@@ -2388,12 +2497,16 @@ spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps)
- 	struct spi_nor_flash_parameter *params = nor->params;
- 	unsigned int cap;
- 
--	/* DTR modes are not supported yet, mask them all. */
--	*hwcaps &= ~SNOR_HWCAPS_DTR;
--
- 	/* X-X-X modes are not supported yet, mask them all. */
- 	*hwcaps &= ~SNOR_HWCAPS_X_X_X;
- 
-+	/*
-+	 * If the reset line is broken, we do not want to enter a stateful
-+	 * mode.
-+	 */
-+	if (nor->flags & SNOR_F_BROKEN_RESET)
-+		*hwcaps &= ~(SNOR_HWCAPS_X_X_X | SNOR_HWCAPS_X_X_X_DTR);
-+
- 	for (cap = 0; cap < sizeof(*hwcaps) * BITS_PER_BYTE; cap++) {
- 		int rdidx, ppidx;
- 
-@@ -2648,7 +2761,7 @@ static int spi_nor_default_setup(struct spi_nor *nor,
- 		 * controller directly implements the spi_nor interface.
- 		 * Yet another reason to switch to spi-mem.
- 		 */
--		ignored_mask = SNOR_HWCAPS_X_X_X;
-+		ignored_mask = SNOR_HWCAPS_X_X_X | SNOR_HWCAPS_X_X_X_DTR;
- 		if (shared_mask & ignored_mask) {
- 			dev_dbg(nor->dev,
- 				"SPI n-n-n protocols are not supported.\n");
-@@ -2794,11 +2907,28 @@ static void spi_nor_info_init_params(struct spi_nor *nor)
- 					  SNOR_PROTO_1_1_8);
- 	}
- 
-+	if (info->flags & SPI_NOR_OCTAL_DTR_READ) {
-+		params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;
-+		spi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8_8_8_DTR],
-+					  0, 20, SPINOR_OP_READ_FAST,
-+					  SNOR_PROTO_8_8_8_DTR);
-+	}
-+
- 	/* Page Program settings. */
- 	params->hwcaps.mask |= SNOR_HWCAPS_PP;
- 	spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],
- 				SPINOR_OP_PP, SNOR_PROTO_1_1_1);
- 
-+	if (info->flags & SPI_NOR_OCTAL_DTR_PP) {
-+		params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
-+		/*
-+		 * Since xSPI Page Program opcode is backward compatible with
-+		 * Legacy SPI, use Legacy SPI opcode there as well.
-+		 */
-+		spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
-+					SPINOR_OP_PP, SNOR_PROTO_8_8_8_DTR);
-+	}
-+
- 	/*
- 	 * Sector Erase settings. Sort Erase Types in ascending order, with the
- 	 * smallest erase size starting at BIT(0).
-@@ -2906,7 +3036,8 @@ static int spi_nor_init_params(struct spi_nor *nor)
- 
- 	spi_nor_manufacturer_init_params(nor);
- 
--	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&
-+	if ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |
-+				 SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&
- 	    !(nor->info->flags & SPI_NOR_SKIP_SFDP))
- 		spi_nor_sfdp_init_params(nor);
- 
-@@ -2969,7 +3100,9 @@ static int spi_nor_init(struct spi_nor *nor)
- 		return err;
- 	}
- 
--	if (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {
-+	if (nor->addr_width == 4 &&
-+	    !spi_nor_protocol_is_dtr(nor->read_proto) &&
-+	    !(nor->flags & SNOR_F_4B_OPCODES)) {
- 		/*
- 		 * If the RESET# pin isn't hooked up properly, or the system
- 		 * otherwise doesn't perform a reset command in the boot
-@@ -3028,7 +3161,10 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,
- 
- static int spi_nor_set_addr_width(struct spi_nor *nor)
- {
--	if (nor->addr_width) {
-+	if (spi_nor_protocol_is_dtr(nor->read_proto)) {
-+		 /* Always use 4-byte addresses in DTR mode. */
-+		nor->addr_width = 4;
-+	} else if (nor->addr_width) {
- 		/* already configured from SFDP */
- 	} else if (nor->info->addr_width) {
- 		nor->addr_width = nor->info->addr_width;
-@@ -3267,14 +3403,19 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor)
- 	};
- 	struct spi_mem_op *op = &info.op_tmpl;
- 
--	/* get transfer protocols. */
--	op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);
--	op->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);
--	op->dummy.buswidth = op->addr.buswidth;
--	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
-+	spi_nor_spimem_setup_op(nor, op, nor->read_proto);
- 
- 	/* convert the dummy cycles to the number of bytes */
- 	op->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;
-+	if (spi_nor_protocol_is_dtr(nor->read_proto))
-+		op->dummy.nbytes *= 2;
-+
-+	/*
-+	 * Since spi_nor_spimem_setup_op() only sets buswidth when the number
-+	 * of data bytes is non-zero, the data buswidth won't be set here. So,
-+	 * do it explicitly.
-+	 */
-+	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);
- 
- 	nor->dirmap.rdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
- 						       &info);
-@@ -3293,15 +3434,18 @@ static int spi_nor_create_write_dirmap(struct spi_nor *nor)
- 	};
- 	struct spi_mem_op *op = &info.op_tmpl;
- 
--	/* get transfer protocols. */
--	op->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);
--	op->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);
--	op->dummy.buswidth = op->addr.buswidth;
--	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
--
- 	if (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)
- 		op->addr.nbytes = 0;
- 
-+	spi_nor_spimem_setup_op(nor, op, nor->write_proto);
-+
-+	/*
-+	 * Since spi_nor_spimem_setup_op() only sets buswidth when the number
-+	 * of data bytes is non-zero, the data buswidth won't be set here. So,
-+	 * do it explicitly.
-+	 */
-+	op->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);
-+
- 	nor->dirmap.wdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,
- 						       &info);
- 	return PTR_ERR_OR_ZERO(nor->dirmap.wdesc);
-diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h
-index 95aa32f3ceb1..125d27b0a72f 100644
---- a/drivers/mtd/spi-nor/core.h
-+++ b/drivers/mtd/spi-nor/core.h
-@@ -62,6 +62,7 @@ enum spi_nor_read_command_index {
- 	SNOR_CMD_READ_1_8_8,
- 	SNOR_CMD_READ_8_8_8,
- 	SNOR_CMD_READ_1_8_8_DTR,
-+	SNOR_CMD_READ_8_8_8_DTR,
- 
- 	SNOR_CMD_READ_MAX
- };
-@@ -78,6 +79,7 @@ enum spi_nor_pp_command_index {
- 	SNOR_CMD_PP_1_1_8,
- 	SNOR_CMD_PP_1_8_8,
- 	SNOR_CMD_PP_8_8_8,
-+	SNOR_CMD_PP_8_8_8_DTR,
- 
- 	SNOR_CMD_PP_MAX
- };
-@@ -311,6 +313,8 @@ struct flash_info {
- 					 * BP3 is bit 6 of status register.
- 					 * Must be used with SPI_NOR_4BIT_BP.
- 					 */
-+#define SPI_NOR_OCTAL_DTR_READ	BIT(19) /* Flash supports octal DTR Read. */
-+#define SPI_NOR_OCTAL_DTR_PP	BIT(20) /* Flash supports Octal DTR Page Program */
- 
- 	/* Part specific fixup hooks. */
- 	const struct spi_nor_fixups *fixups;
-@@ -399,6 +403,9 @@ extern const struct spi_nor_manufacturer spi_nor_winbond;
- extern const struct spi_nor_manufacturer spi_nor_xilinx;
- extern const struct spi_nor_manufacturer spi_nor_xmc;
- 
-+void spi_nor_spimem_setup_op(const struct spi_nor *nor,
-+			     struct spi_mem_op *op,
-+			     const enum spi_nor_protocol proto);
- int spi_nor_write_enable(struct spi_nor *nor);
- int spi_nor_write_disable(struct spi_nor *nor);
- int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable);
-diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c
-index e2a43d39eb5f..21fa9ab78eae 100644
---- a/drivers/mtd/spi-nor/sfdp.c
-+++ b/drivers/mtd/spi-nor/sfdp.c
-@@ -1047,9 +1047,16 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,
- 	}
- 
- 	/* 4BAIT is the only SFDP table that indicates page program support. */
--	if (pp_hwcaps & SNOR_HWCAPS_PP)
-+	if (pp_hwcaps & SNOR_HWCAPS_PP) {
- 		spi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP],
- 					SPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);
-+		/*
-+		 * Since xSPI Page Program opcode is backward compatible with
-+		 * Legacy SPI, use Legacy SPI opcode there as well.
-+		 */
-+		spi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP_8_8_8_DTR],
-+					SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
-+	}
- 	if (pp_hwcaps & SNOR_HWCAPS_PP_1_1_4)
- 		spi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP_1_1_4],
- 					SPINOR_OP_PP_1_1_4_4B,
-diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
-index 60bac2c0ec45..cd549042c53d 100644
---- a/include/linux/mtd/spi-nor.h
-+++ b/include/linux/mtd/spi-nor.h
-@@ -182,6 +182,7 @@ enum spi_nor_protocol {
- 	SNOR_PROTO_1_2_2_DTR = SNOR_PROTO_DTR(1, 2, 2),
- 	SNOR_PROTO_1_4_4_DTR = SNOR_PROTO_DTR(1, 4, 4),
- 	SNOR_PROTO_1_8_8_DTR = SNOR_PROTO_DTR(1, 8, 8),
-+	SNOR_PROTO_8_8_8_DTR = SNOR_PROTO_DTR(8, 8, 8),
- };
- 
- static inline bool spi_nor_protocol_is_dtr(enum spi_nor_protocol proto)
-@@ -228,7 +229,7 @@ struct spi_nor_hwcaps {
-  * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly
-  * (Slow) Read.
-  */
--#define SNOR_HWCAPS_READ_MASK		GENMASK(14, 0)
-+#define SNOR_HWCAPS_READ_MASK		GENMASK(15, 0)
- #define SNOR_HWCAPS_READ		BIT(0)
- #define SNOR_HWCAPS_READ_FAST		BIT(1)
- #define SNOR_HWCAPS_READ_1_1_1_DTR	BIT(2)
-@@ -245,11 +246,12 @@ struct spi_nor_hwcaps {
- #define SNOR_HWCAPS_READ_4_4_4		BIT(9)
- #define SNOR_HWCAPS_READ_1_4_4_DTR	BIT(10)
- 
--#define SNOR_HWCAPS_READ_OCTAL		GENMASK(14, 11)
-+#define SNOR_HWCAPS_READ_OCTAL		GENMASK(15, 11)
- #define SNOR_HWCAPS_READ_1_1_8		BIT(11)
- #define SNOR_HWCAPS_READ_1_8_8		BIT(12)
- #define SNOR_HWCAPS_READ_8_8_8		BIT(13)
- #define SNOR_HWCAPS_READ_1_8_8_DTR	BIT(14)
-+#define SNOR_HWCAPS_READ_8_8_8_DTR	BIT(15)
- 
- /*
-  * Page Program capabilities.
-@@ -260,18 +262,19 @@ struct spi_nor_hwcaps {
-  * JEDEC/SFDP standard to define them. Also at this moment no SPI flash memory
-  * implements such commands.
-  */
--#define SNOR_HWCAPS_PP_MASK	GENMASK(22, 16)
--#define SNOR_HWCAPS_PP		BIT(16)
-+#define SNOR_HWCAPS_PP_MASK		GENMASK(23, 16)
-+#define SNOR_HWCAPS_PP			BIT(16)
- 
--#define SNOR_HWCAPS_PP_QUAD	GENMASK(19, 17)
--#define SNOR_HWCAPS_PP_1_1_4	BIT(17)
--#define SNOR_HWCAPS_PP_1_4_4	BIT(18)
--#define SNOR_HWCAPS_PP_4_4_4	BIT(19)
-+#define SNOR_HWCAPS_PP_QUAD		GENMASK(19, 17)
-+#define SNOR_HWCAPS_PP_1_1_4		BIT(17)
-+#define SNOR_HWCAPS_PP_1_4_4		BIT(18)
-+#define SNOR_HWCAPS_PP_4_4_4		BIT(19)
- 
--#define SNOR_HWCAPS_PP_OCTAL	GENMASK(22, 20)
--#define SNOR_HWCAPS_PP_1_1_8	BIT(20)
--#define SNOR_HWCAPS_PP_1_8_8	BIT(21)
--#define SNOR_HWCAPS_PP_8_8_8	BIT(22)
-+#define SNOR_HWCAPS_PP_OCTAL		GENMASK(23, 20)
-+#define SNOR_HWCAPS_PP_1_1_8		BIT(20)
-+#define SNOR_HWCAPS_PP_1_8_8		BIT(21)
-+#define SNOR_HWCAPS_PP_8_8_8		BIT(22)
-+#define SNOR_HWCAPS_PP_8_8_8_DTR	BIT(23)
- 
- #define SNOR_HWCAPS_X_X_X	(SNOR_HWCAPS_READ_2_2_2 |	\
- 				 SNOR_HWCAPS_READ_4_4_4 |	\
-@@ -279,10 +282,14 @@ struct spi_nor_hwcaps {
- 				 SNOR_HWCAPS_PP_4_4_4 |		\
- 				 SNOR_HWCAPS_PP_8_8_8)
- 
-+#define SNOR_HWCAPS_X_X_X_DTR	(SNOR_HWCAPS_READ_8_8_8_DTR |	\
-+				 SNOR_HWCAPS_PP_8_8_8_DTR)
-+
- #define SNOR_HWCAPS_DTR		(SNOR_HWCAPS_READ_1_1_1_DTR |	\
- 				 SNOR_HWCAPS_READ_1_2_2_DTR |	\
- 				 SNOR_HWCAPS_READ_1_4_4_DTR |	\
--				 SNOR_HWCAPS_READ_1_8_8_DTR)
-+				 SNOR_HWCAPS_READ_1_8_8_DTR |	\
-+				 SNOR_HWCAPS_READ_8_8_8_DTR)
- 
- #define SNOR_HWCAPS_ALL		(SNOR_HWCAPS_READ_MASK |	\
- 				 SNOR_HWCAPS_PP_MASK)
-@@ -318,6 +325,22 @@ struct spi_nor_controller_ops {
- 	int (*erase)(struct spi_nor *nor, loff_t offs);
- };
- 
-+/**
-+ * enum spi_nor_cmd_ext - describes the command opcode extension in DTR mode
-+ * @SPI_NOR_EXT_NONE: no extension. This is the default, and is used in Legacy
-+ *		      SPI mode
-+ * @SPI_NOR_EXT_REPEAT: the extension is same as the opcode
-+ * @SPI_NOR_EXT_INVERT: the extension is the bitwise inverse of the opcode
-+ * @SPI_NOR_EXT_HEX: the extension is any hex value. The command and opcode
-+ *		     combine to form a 16-bit opcode.
-+ */
-+enum spi_nor_cmd_ext {
-+	SPI_NOR_EXT_NONE = 0,
-+	SPI_NOR_EXT_REPEAT,
-+	SPI_NOR_EXT_INVERT,
-+	SPI_NOR_EXT_HEX,
-+};
-+
- /*
-  * Forward declarations that are used internally by the core and manufacturer
-  * drivers.
-@@ -345,6 +368,7 @@ struct spi_nor_flash_parameter;
-  * @program_opcode:	the program opcode
-  * @sst_write_second:	used by the SST write operation
-  * @flags:		flag options for the current SPI NOR (SNOR_F_*)
-+ * @cmd_ext_type:	the command opcode extension type for DTR mode.
-  * @read_proto:		the SPI protocol for read operations
-  * @write_proto:	the SPI protocol for write operations
-  * @reg_proto:		the SPI protocol for read_reg/write_reg/erase operations
-@@ -376,6 +400,7 @@ struct spi_nor {
- 	enum spi_nor_protocol	reg_proto;
- 	bool			sst_write_second;
- 	u32			flags;
-+	enum spi_nor_cmd_ext	cmd_ext_type;
- 
- 	const struct spi_nor_controller_ops *controller_ops;
- 
--- 
-2.28.0
diff --git a/a/content_digest b/N1/content_digest
index 727a5a0..e7c2a6a 100644
--- a/a/content_digest
+++ b/N1/content_digest
@@ -13,686 +13,5 @@
  " Boris Brezillon <boris.brezillon@collabora.com>\0"
  "\00:1\0"
  "b\0"
- "Double Transfer Rate (DTR) is SPI protocol in which data is transferred\n"
- "on each clock edge as opposed to on each clock cycle. Make\n"
- "framework-level changes to allow supporting flashes in DTR mode.\n"
- "\n"
- "Right now, mixed DTR modes are not supported. So, for example a mode\n"
- "like 4S-4D-4D will not work. All phases need to be either DTR or STR.\n"
- "\n"
- "Signed-off-by: Pratyush Yadav <p.yadav@ti.com>\n"
- "---\n"
- " drivers/mtd/spi-nor/core.c  | 222 +++++++++++++++++++++++++++++-------\n"
- " drivers/mtd/spi-nor/core.h  |   7 ++\n"
- " drivers/mtd/spi-nor/sfdp.c  |   9 +-\n"
- " include/linux/mtd/spi-nor.h |  51 ++++++---\n"
- " 4 files changed, 236 insertions(+), 53 deletions(-)\n"
- "\n"
- "diff --git a/drivers/mtd/spi-nor/core.c b/drivers/mtd/spi-nor/core.c\n"
- "index 7009cb702e22..7445d7122304 100644\n"
- "--- a/drivers/mtd/spi-nor/core.c\n"
- "+++ b/drivers/mtd/spi-nor/core.c\n"
- "@@ -40,6 +40,78 @@\n"
- " \n"
- " #define SPI_NOR_MAX_ADDR_WIDTH\t4\n"
- " \n"
- "+/**\n"
- "+ * spi_nor_get_cmd_ext() - Get the command opcode extension based on the\n"
- "+ *\t\t\t   extension type.\n"
- "+ * @nor:\t\tpointer to a 'struct spi_nor'\n"
- "+ * @op:\t\t\tpointer to the 'struct spi_mem_op' whose properties\n"
- "+ *\t\t\tneed to be initialized.\n"
- "+ *\n"
- "+ * Right now, only \"repeat\" and \"invert\" are supported.\n"
- "+ *\n"
- "+ * Return: The opcode extension.\n"
- "+ */\n"
- "+static u8 spi_nor_get_cmd_ext(const struct spi_nor *nor,\n"
- "+\t\t\t      const struct spi_mem_op *op)\n"
- "+{\n"
- "+\tswitch (nor->cmd_ext_type) {\n"
- "+\tcase SPI_NOR_EXT_INVERT:\n"
- "+\t\treturn ~op->cmd.opcode;\n"
- "+\n"
- "+\tcase SPI_NOR_EXT_REPEAT:\n"
- "+\t\treturn op->cmd.opcode;\n"
- "+\n"
- "+\tdefault:\n"
- "+\t\tdev_err(nor->dev, \"Unknown command extension type\\n\");\n"
- "+\t\treturn 0;\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- "+/**\n"
- "+ * spi_nor_spimem_setup_op() - Set up common properties of a spi-mem op.\n"
- "+ * @nor:\t\tpointer to a 'struct spi_nor'\n"
- "+ * @op:\t\t\tpointer to the 'struct spi_mem_op' whose properties\n"
- "+ *\t\t\tneed to be initialized.\n"
- "+ * @proto:\t\tthe protocol from which the properties need to be set.\n"
- "+ */\n"
- "+void spi_nor_spimem_setup_op(const struct spi_nor *nor,\n"
- "+\t\t\t     struct spi_mem_op *op,\n"
- "+\t\t\t     const enum spi_nor_protocol proto)\n"
- "+{\n"
- "+\tu8 ext;\n"
- "+\n"
- "+\top->cmd.buswidth = spi_nor_get_protocol_inst_nbits(proto);\n"
- "+\n"
- "+\tif (op->addr.nbytes)\n"
- "+\t\top->addr.buswidth = spi_nor_get_protocol_addr_nbits(proto);\n"
- "+\n"
- "+\tif (op->dummy.nbytes)\n"
- "+\t\top->dummy.buswidth = spi_nor_get_protocol_addr_nbits(proto);\n"
- "+\n"
- "+\tif (op->data.nbytes)\n"
- "+\t\top->data.buswidth = spi_nor_get_protocol_data_nbits(proto);\n"
- "+\n"
- "+\tif (spi_nor_protocol_is_dtr(proto)) {\n"
- "+\t\t/*\n"
- "+\t\t * SPIMEM supports mixed DTR modes, but right now we can only\n"
- "+\t\t * have all phases either DTR or STR. IOW, SPIMEM can have\n"
- "+\t\t * something like 4S-4D-4D, but SPI NOR can't. So, set all 4\n"
- "+\t\t * phases to either DTR or STR.\n"
- "+\t\t */\n"
- "+\t\top->cmd.dtr = true;\n"
- "+\t\top->addr.dtr = true;\n"
- "+\t\top->dummy.dtr = true;\n"
- "+\t\top->data.dtr = true;\n"
- "+\n"
- "+\t\t/* 2 bytes per clock cycle in DTR mode. */\n"
- "+\t\top->dummy.nbytes *= 2;\n"
- "+\n"
- "+\t\text = spi_nor_get_cmd_ext(nor, op);\n"
- "+\t\top->cmd.opcode = (op->cmd.opcode << 8) | ext;\n"
- "+\t\top->cmd.nbytes = 2;\n"
- "+\t}\n"
- "+}\n"
- "+\n"
- " /**\n"
- "  * spi_nor_spimem_bounce() - check if a bounce buffer is needed for the data\n"
- "  *                           transfer\n"
- "@@ -85,17 +157,26 @@ static int spi_nor_spimem_exec_op(struct spi_nor *nor, struct spi_mem_op *op)\n"
- " static int spi_nor_read_reg(struct spi_nor *nor, u8 opcode, u8 *buf,\n"
- " \t\t\t    size_t len)\n"
- " {\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->reg_proto))\n"
- "+\t\treturn -EOPNOTSUPP;\n"
- "+\n"
- " \treturn nor->controller_ops->read_reg(nor, opcode, buf, len);\n"
- " }\n"
- " \n"
- " static int spi_nor_write_reg(struct spi_nor *nor, u8 opcode, const u8 *buf,\n"
- " \t\t\t     size_t len)\n"
- " {\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->reg_proto))\n"
- "+\t\treturn -EOPNOTSUPP;\n"
- "+\n"
- " \treturn nor->controller_ops->write_reg(nor, opcode, buf, len);\n"
- " }\n"
- " \n"
- " static int spi_nor_controller_ops_erase(struct spi_nor *nor, loff_t offs)\n"
- " {\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->write_proto))\n"
- "+\t\treturn -EOPNOTSUPP;\n"
- "+\n"
- " \treturn nor->controller_ops->erase(nor, offs);\n"
- " }\n"
- " \n"
- "@@ -121,14 +202,12 @@ static ssize_t spi_nor_spimem_read_data(struct spi_nor *nor, loff_t from,\n"
- " \tssize_t nbytes;\n"
- " \tint error;\n"
- " \n"
- "-\t/* get transfer protocols. */\n"
- "-\top.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);\n"
- "-\top.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);\n"
- "-\top.dummy.buswidth = op.addr.buswidth;\n"
- "-\top.data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);\n"
- "+\tspi_nor_spimem_setup_op(nor, &op, nor->read_proto);\n"
- " \n"
- " \t/* convert the dummy cycles to the number of bytes */\n"
- " \top.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->read_proto))\n"
- "+\t\top.dummy.nbytes *= 2;\n"
- " \n"
- " \tusebouncebuf = spi_nor_spimem_bounce(nor, &op);\n"
- " \n"
- "@@ -186,13 +265,11 @@ static ssize_t spi_nor_spimem_write_data(struct spi_nor *nor, loff_t to,\n"
- " \tssize_t nbytes;\n"
- " \tint error;\n"
- " \n"
- "-\top.cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);\n"
- "-\top.addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);\n"
- "-\top.data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);\n"
- "-\n"
- " \tif (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)\n"
- " \t\top.addr.nbytes = 0;\n"
- " \n"
- "+\tspi_nor_spimem_setup_op(nor, &op, nor->write_proto);\n"
- "+\n"
- " \tif (spi_nor_spimem_bounce(nor, &op))\n"
- " \t\tmemcpy(nor->bouncebuf, buf, op.data.nbytes);\n"
- " \n"
- "@@ -244,6 +321,8 @@ int spi_nor_write_enable(struct spi_nor *nor)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_WREN, NULL, 0);\n"
- "@@ -272,6 +351,8 @@ int spi_nor_write_disable(struct spi_nor *nor)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_WRDI, NULL, 0);\n"
- "@@ -302,6 +383,8 @@ static int spi_nor_read_sr(struct spi_nor *nor, u8 *sr)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_IN(1, sr, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_read_reg(nor, SPINOR_OP_RDSR, sr, 1);\n"
- "@@ -332,6 +415,8 @@ static int spi_nor_read_fsr(struct spi_nor *nor, u8 *fsr)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_IN(1, fsr, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_read_reg(nor, SPINOR_OP_RDFSR, fsr, 1);\n"
- "@@ -363,6 +448,8 @@ static int spi_nor_read_cr(struct spi_nor *nor, u8 *cr)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_IN(1, cr, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_read_reg(nor, SPINOR_OP_RDCR, cr, 1);\n"
- "@@ -396,6 +483,8 @@ int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable)\n"
- " \t\t\t\t  SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t  SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor,\n"
- "@@ -432,6 +521,8 @@ static int spansion_set_4byte_addr_mode(struct spi_nor *nor, bool enable)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_BRWR, nor->bouncebuf, 1);\n"
- "@@ -463,6 +554,8 @@ int spi_nor_write_ear(struct spi_nor *nor, u8 ear)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_OUT(1, nor->bouncebuf, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_WREAR, nor->bouncebuf, 1);\n"
- "@@ -493,6 +586,8 @@ int spi_nor_xread_sr(struct spi_nor *nor, u8 *sr)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_IN(1, sr, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_read_reg(nor, SPINOR_OP_XRDSR, sr, 1);\n"
- "@@ -537,6 +632,8 @@ static void spi_nor_clear_sr(struct spi_nor *nor)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_CLSR, NULL, 0);\n"
- "@@ -600,6 +697,8 @@ static void spi_nor_clear_fsr(struct spi_nor *nor)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_CLFSR, NULL, 0);\n"
- "@@ -743,6 +842,8 @@ static int spi_nor_write_sr(struct spi_nor *nor, const u8 *sr, size_t len)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_OUT(len, sr, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_WRSR, sr, len);\n"
- "@@ -944,6 +1045,8 @@ static int spi_nor_write_sr2(struct spi_nor *nor, const u8 *sr2)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_OUT(1, sr2, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_WRSR2, sr2, 1);\n"
- "@@ -977,6 +1080,8 @@ static int spi_nor_read_sr2(struct spi_nor *nor, u8 *sr2)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_DATA_IN(1, sr2, 1));\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->reg_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_read_reg(nor, SPINOR_OP_RDSR2, sr2, 1);\n"
- "@@ -1007,6 +1112,8 @@ static int spi_nor_erase_chip(struct spi_nor *nor)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->write_proto);\n"
- "+\n"
- " \t\tret = spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else {\n"
- " \t\tret = spi_nor_write_reg(nor, SPINOR_OP_CHIP_ERASE, NULL, 0);\n"
- "@@ -1148,6 +1255,8 @@ static int spi_nor_erase_sector(struct spi_nor *nor, u32 addr)\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DUMMY,\n"
- " \t\t\t\t   SPI_MEM_OP_NO_DATA);\n"
- " \n"
- "+\t\tspi_nor_spimem_setup_op(nor, &op, nor->write_proto);\n"
- "+\n"
- " \t\treturn spi_mem_exec_op(nor->spimem, &op);\n"
- " \t} else if (nor->controller_ops->erase) {\n"
- " \t\treturn spi_nor_controller_ops_erase(nor, addr);\n"
- "@@ -2273,6 +2382,7 @@ int spi_nor_hwcaps_read2cmd(u32 hwcaps)\n"
- " \t\t{ SNOR_HWCAPS_READ_1_8_8,\tSNOR_CMD_READ_1_8_8 },\n"
- " \t\t{ SNOR_HWCAPS_READ_8_8_8,\tSNOR_CMD_READ_8_8_8 },\n"
- " \t\t{ SNOR_HWCAPS_READ_1_8_8_DTR,\tSNOR_CMD_READ_1_8_8_DTR },\n"
- "+\t\t{ SNOR_HWCAPS_READ_8_8_8_DTR,\tSNOR_CMD_READ_8_8_8_DTR },\n"
- " \t};\n"
- " \n"
- " \treturn spi_nor_hwcaps2cmd(hwcaps, hwcaps_read2cmd,\n"
- "@@ -2289,6 +2399,7 @@ static int spi_nor_hwcaps_pp2cmd(u32 hwcaps)\n"
- " \t\t{ SNOR_HWCAPS_PP_1_1_8,\t\tSNOR_CMD_PP_1_1_8 },\n"
- " \t\t{ SNOR_HWCAPS_PP_1_8_8,\t\tSNOR_CMD_PP_1_8_8 },\n"
- " \t\t{ SNOR_HWCAPS_PP_8_8_8,\t\tSNOR_CMD_PP_8_8_8 },\n"
- "+\t\t{ SNOR_HWCAPS_PP_8_8_8_DTR,\tSNOR_CMD_PP_8_8_8_DTR },\n"
- " \t};\n"
- " \n"
- " \treturn spi_nor_hwcaps2cmd(hwcaps, hwcaps_pp2cmd,\n"
- "@@ -2339,15 +2450,15 @@ static int spi_nor_spimem_check_readop(struct spi_nor *nor,\n"
- " {\n"
- " \tstruct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(read->opcode, 1),\n"
- " \t\t\t\t\t  SPI_MEM_OP_ADDR(3, 0, 1),\n"
- "-\t\t\t\t\t  SPI_MEM_OP_DUMMY(0, 1),\n"
- "-\t\t\t\t\t  SPI_MEM_OP_DATA_IN(0, NULL, 1));\n"
- "+\t\t\t\t\t  SPI_MEM_OP_DUMMY(1, 1),\n"
- "+\t\t\t\t\t  SPI_MEM_OP_DATA_IN(1, NULL, 1));\n"
- " \n"
- "-\top.cmd.buswidth = spi_nor_get_protocol_inst_nbits(read->proto);\n"
- "-\top.addr.buswidth = spi_nor_get_protocol_addr_nbits(read->proto);\n"
- "-\top.data.buswidth = spi_nor_get_protocol_data_nbits(read->proto);\n"
- "-\top.dummy.buswidth = op.addr.buswidth;\n"
- "-\top.dummy.nbytes = (read->num_mode_clocks + read->num_wait_states) *\n"
- "-\t\t\t  op.dummy.buswidth / 8;\n"
- "+\tspi_nor_spimem_setup_op(nor, &op, read->proto);\n"
- "+\n"
- "+\t/* convert the dummy cycles to the number of bytes */\n"
- "+\top.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->read_proto))\n"
- "+\t\top.dummy.nbytes *= 2;\n"
- " \n"
- " \treturn spi_nor_spimem_check_op(nor, &op);\n"
- " }\n"
- "@@ -2366,11 +2477,9 @@ static int spi_nor_spimem_check_pp(struct spi_nor *nor,\n"
- " \tstruct spi_mem_op op = SPI_MEM_OP(SPI_MEM_OP_CMD(pp->opcode, 1),\n"
- " \t\t\t\t\t  SPI_MEM_OP_ADDR(3, 0, 1),\n"
- " \t\t\t\t\t  SPI_MEM_OP_NO_DUMMY,\n"
- "-\t\t\t\t\t  SPI_MEM_OP_DATA_OUT(0, NULL, 1));\n"
- "+\t\t\t\t\t  SPI_MEM_OP_DATA_OUT(1, NULL, 1));\n"
- " \n"
- "-\top.cmd.buswidth = spi_nor_get_protocol_inst_nbits(pp->proto);\n"
- "-\top.addr.buswidth = spi_nor_get_protocol_addr_nbits(pp->proto);\n"
- "-\top.data.buswidth = spi_nor_get_protocol_data_nbits(pp->proto);\n"
- "+\tspi_nor_spimem_setup_op(nor, &op, pp->proto);\n"
- " \n"
- " \treturn spi_nor_spimem_check_op(nor, &op);\n"
- " }\n"
- "@@ -2388,12 +2497,16 @@ spi_nor_spimem_adjust_hwcaps(struct spi_nor *nor, u32 *hwcaps)\n"
- " \tstruct spi_nor_flash_parameter *params = nor->params;\n"
- " \tunsigned int cap;\n"
- " \n"
- "-\t/* DTR modes are not supported yet, mask them all. */\n"
- "-\t*hwcaps &= ~SNOR_HWCAPS_DTR;\n"
- "-\n"
- " \t/* X-X-X modes are not supported yet, mask them all. */\n"
- " \t*hwcaps &= ~SNOR_HWCAPS_X_X_X;\n"
- " \n"
- "+\t/*\n"
- "+\t * If the reset line is broken, we do not want to enter a stateful\n"
- "+\t * mode.\n"
- "+\t */\n"
- "+\tif (nor->flags & SNOR_F_BROKEN_RESET)\n"
- "+\t\t*hwcaps &= ~(SNOR_HWCAPS_X_X_X | SNOR_HWCAPS_X_X_X_DTR);\n"
- "+\n"
- " \tfor (cap = 0; cap < sizeof(*hwcaps) * BITS_PER_BYTE; cap++) {\n"
- " \t\tint rdidx, ppidx;\n"
- " \n"
- "@@ -2648,7 +2761,7 @@ static int spi_nor_default_setup(struct spi_nor *nor,\n"
- " \t\t * controller directly implements the spi_nor interface.\n"
- " \t\t * Yet another reason to switch to spi-mem.\n"
- " \t\t */\n"
- "-\t\tignored_mask = SNOR_HWCAPS_X_X_X;\n"
- "+\t\tignored_mask = SNOR_HWCAPS_X_X_X | SNOR_HWCAPS_X_X_X_DTR;\n"
- " \t\tif (shared_mask & ignored_mask) {\n"
- " \t\t\tdev_dbg(nor->dev,\n"
- " \t\t\t\t\"SPI n-n-n protocols are not supported.\\n\");\n"
- "@@ -2794,11 +2907,28 @@ static void spi_nor_info_init_params(struct spi_nor *nor)\n"
- " \t\t\t\t\t  SNOR_PROTO_1_1_8);\n"
- " \t}\n"
- " \n"
- "+\tif (info->flags & SPI_NOR_OCTAL_DTR_READ) {\n"
- "+\t\tparams->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8_DTR;\n"
- "+\t\tspi_nor_set_read_settings(&params->reads[SNOR_CMD_READ_8_8_8_DTR],\n"
- "+\t\t\t\t\t  0, 20, SPINOR_OP_READ_FAST,\n"
- "+\t\t\t\t\t  SNOR_PROTO_8_8_8_DTR);\n"
- "+\t}\n"
- "+\n"
- " \t/* Page Program settings. */\n"
- " \tparams->hwcaps.mask |= SNOR_HWCAPS_PP;\n"
- " \tspi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP],\n"
- " \t\t\t\tSPINOR_OP_PP, SNOR_PROTO_1_1_1);\n"
- " \n"
- "+\tif (info->flags & SPI_NOR_OCTAL_DTR_PP) {\n"
- "+\t\tparams->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;\n"
- "+\t\t/*\n"
- "+\t\t * Since xSPI Page Program opcode is backward compatible with\n"
- "+\t\t * Legacy SPI, use Legacy SPI opcode there as well.\n"
- "+\t\t */\n"
- "+\t\tspi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8_DTR],\n"
- "+\t\t\t\t\tSPINOR_OP_PP, SNOR_PROTO_8_8_8_DTR);\n"
- "+\t}\n"
- "+\n"
- " \t/*\n"
- " \t * Sector Erase settings. Sort Erase Types in ascending order, with the\n"
- " \t * smallest erase size starting at BIT(0).\n"
- "@@ -2906,7 +3036,8 @@ static int spi_nor_init_params(struct spi_nor *nor)\n"
- " \n"
- " \tspi_nor_manufacturer_init_params(nor);\n"
- " \n"
- "-\tif ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)) &&\n"
- "+\tif ((nor->info->flags & (SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ |\n"
- "+\t\t\t\t SPI_NOR_OCTAL_READ | SPI_NOR_OCTAL_DTR_READ)) &&\n"
- " \t    !(nor->info->flags & SPI_NOR_SKIP_SFDP))\n"
- " \t\tspi_nor_sfdp_init_params(nor);\n"
- " \n"
- "@@ -2969,7 +3100,9 @@ static int spi_nor_init(struct spi_nor *nor)\n"
- " \t\treturn err;\n"
- " \t}\n"
- " \n"
- "-\tif (nor->addr_width == 4 && !(nor->flags & SNOR_F_4B_OPCODES)) {\n"
- "+\tif (nor->addr_width == 4 &&\n"
- "+\t    !spi_nor_protocol_is_dtr(nor->read_proto) &&\n"
- "+\t    !(nor->flags & SNOR_F_4B_OPCODES)) {\n"
- " \t\t/*\n"
- " \t\t * If the RESET# pin isn't hooked up properly, or the system\n"
- " \t\t * otherwise doesn't perform a reset command in the boot\n"
- "@@ -3028,7 +3161,10 @@ static const struct flash_info *spi_nor_match_id(struct spi_nor *nor,\n"
- " \n"
- " static int spi_nor_set_addr_width(struct spi_nor *nor)\n"
- " {\n"
- "-\tif (nor->addr_width) {\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->read_proto)) {\n"
- "+\t\t /* Always use 4-byte addresses in DTR mode. */\n"
- "+\t\tnor->addr_width = 4;\n"
- "+\t} else if (nor->addr_width) {\n"
- " \t\t/* already configured from SFDP */\n"
- " \t} else if (nor->info->addr_width) {\n"
- " \t\tnor->addr_width = nor->info->addr_width;\n"
- "@@ -3267,14 +3403,19 @@ static int spi_nor_create_read_dirmap(struct spi_nor *nor)\n"
- " \t};\n"
- " \tstruct spi_mem_op *op = &info.op_tmpl;\n"
- " \n"
- "-\t/* get transfer protocols. */\n"
- "-\top->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->read_proto);\n"
- "-\top->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->read_proto);\n"
- "-\top->dummy.buswidth = op->addr.buswidth;\n"
- "-\top->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);\n"
- "+\tspi_nor_spimem_setup_op(nor, op, nor->read_proto);\n"
- " \n"
- " \t/* convert the dummy cycles to the number of bytes */\n"
- " \top->dummy.nbytes = (nor->read_dummy * op->dummy.buswidth) / 8;\n"
- "+\tif (spi_nor_protocol_is_dtr(nor->read_proto))\n"
- "+\t\top->dummy.nbytes *= 2;\n"
- "+\n"
- "+\t/*\n"
- "+\t * Since spi_nor_spimem_setup_op() only sets buswidth when the number\n"
- "+\t * of data bytes is non-zero, the data buswidth won't be set here. So,\n"
- "+\t * do it explicitly.\n"
- "+\t */\n"
- "+\top->data.buswidth = spi_nor_get_protocol_data_nbits(nor->read_proto);\n"
- " \n"
- " \tnor->dirmap.rdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,\n"
- " \t\t\t\t\t\t       &info);\n"
- "@@ -3293,15 +3434,18 @@ static int spi_nor_create_write_dirmap(struct spi_nor *nor)\n"
- " \t};\n"
- " \tstruct spi_mem_op *op = &info.op_tmpl;\n"
- " \n"
- "-\t/* get transfer protocols. */\n"
- "-\top->cmd.buswidth = spi_nor_get_protocol_inst_nbits(nor->write_proto);\n"
- "-\top->addr.buswidth = spi_nor_get_protocol_addr_nbits(nor->write_proto);\n"
- "-\top->dummy.buswidth = op->addr.buswidth;\n"
- "-\top->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);\n"
- "-\n"
- " \tif (nor->program_opcode == SPINOR_OP_AAI_WP && nor->sst_write_second)\n"
- " \t\top->addr.nbytes = 0;\n"
- " \n"
- "+\tspi_nor_spimem_setup_op(nor, op, nor->write_proto);\n"
- "+\n"
- "+\t/*\n"
- "+\t * Since spi_nor_spimem_setup_op() only sets buswidth when the number\n"
- "+\t * of data bytes is non-zero, the data buswidth won't be set here. So,\n"
- "+\t * do it explicitly.\n"
- "+\t */\n"
- "+\top->data.buswidth = spi_nor_get_protocol_data_nbits(nor->write_proto);\n"
- "+\n"
- " \tnor->dirmap.wdesc = devm_spi_mem_dirmap_create(nor->dev, nor->spimem,\n"
- " \t\t\t\t\t\t       &info);\n"
- " \treturn PTR_ERR_OR_ZERO(nor->dirmap.wdesc);\n"
- "diff --git a/drivers/mtd/spi-nor/core.h b/drivers/mtd/spi-nor/core.h\n"
- "index 95aa32f3ceb1..125d27b0a72f 100644\n"
- "--- a/drivers/mtd/spi-nor/core.h\n"
- "+++ b/drivers/mtd/spi-nor/core.h\n"
- "@@ -62,6 +62,7 @@ enum spi_nor_read_command_index {\n"
- " \tSNOR_CMD_READ_1_8_8,\n"
- " \tSNOR_CMD_READ_8_8_8,\n"
- " \tSNOR_CMD_READ_1_8_8_DTR,\n"
- "+\tSNOR_CMD_READ_8_8_8_DTR,\n"
- " \n"
- " \tSNOR_CMD_READ_MAX\n"
- " };\n"
- "@@ -78,6 +79,7 @@ enum spi_nor_pp_command_index {\n"
- " \tSNOR_CMD_PP_1_1_8,\n"
- " \tSNOR_CMD_PP_1_8_8,\n"
- " \tSNOR_CMD_PP_8_8_8,\n"
- "+\tSNOR_CMD_PP_8_8_8_DTR,\n"
- " \n"
- " \tSNOR_CMD_PP_MAX\n"
- " };\n"
- "@@ -311,6 +313,8 @@ struct flash_info {\n"
- " \t\t\t\t\t * BP3 is bit 6 of status register.\n"
- " \t\t\t\t\t * Must be used with SPI_NOR_4BIT_BP.\n"
- " \t\t\t\t\t */\n"
- "+#define SPI_NOR_OCTAL_DTR_READ\tBIT(19) /* Flash supports octal DTR Read. */\n"
- "+#define SPI_NOR_OCTAL_DTR_PP\tBIT(20) /* Flash supports Octal DTR Page Program */\n"
- " \n"
- " \t/* Part specific fixup hooks. */\n"
- " \tconst struct spi_nor_fixups *fixups;\n"
- "@@ -399,6 +403,9 @@ extern const struct spi_nor_manufacturer spi_nor_winbond;\n"
- " extern const struct spi_nor_manufacturer spi_nor_xilinx;\n"
- " extern const struct spi_nor_manufacturer spi_nor_xmc;\n"
- " \n"
- "+void spi_nor_spimem_setup_op(const struct spi_nor *nor,\n"
- "+\t\t\t     struct spi_mem_op *op,\n"
- "+\t\t\t     const enum spi_nor_protocol proto);\n"
- " int spi_nor_write_enable(struct spi_nor *nor);\n"
- " int spi_nor_write_disable(struct spi_nor *nor);\n"
- " int spi_nor_set_4byte_addr_mode(struct spi_nor *nor, bool enable);\n"
- "diff --git a/drivers/mtd/spi-nor/sfdp.c b/drivers/mtd/spi-nor/sfdp.c\n"
- "index e2a43d39eb5f..21fa9ab78eae 100644\n"
- "--- a/drivers/mtd/spi-nor/sfdp.c\n"
- "+++ b/drivers/mtd/spi-nor/sfdp.c\n"
- "@@ -1047,9 +1047,16 @@ static int spi_nor_parse_4bait(struct spi_nor *nor,\n"
- " \t}\n"
- " \n"
- " \t/* 4BAIT is the only SFDP table that indicates page program support. */\n"
- "-\tif (pp_hwcaps & SNOR_HWCAPS_PP)\n"
- "+\tif (pp_hwcaps & SNOR_HWCAPS_PP) {\n"
- " \t\tspi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP],\n"
- " \t\t\t\t\tSPINOR_OP_PP_4B, SNOR_PROTO_1_1_1);\n"
- "+\t\t/*\n"
- "+\t\t * Since xSPI Page Program opcode is backward compatible with\n"
- "+\t\t * Legacy SPI, use Legacy SPI opcode there as well.\n"
- "+\t\t */\n"
- "+\t\tspi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP_8_8_8_DTR],\n"
- "+\t\t\t\t\tSPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);\n"
- "+\t}\n"
- " \tif (pp_hwcaps & SNOR_HWCAPS_PP_1_1_4)\n"
- " \t\tspi_nor_set_pp_settings(&params_pp[SNOR_CMD_PP_1_1_4],\n"
- " \t\t\t\t\tSPINOR_OP_PP_1_1_4_4B,\n"
- "diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h\n"
- "index 60bac2c0ec45..cd549042c53d 100644\n"
- "--- a/include/linux/mtd/spi-nor.h\n"
- "+++ b/include/linux/mtd/spi-nor.h\n"
- "@@ -182,6 +182,7 @@ enum spi_nor_protocol {\n"
- " \tSNOR_PROTO_1_2_2_DTR = SNOR_PROTO_DTR(1, 2, 2),\n"
- " \tSNOR_PROTO_1_4_4_DTR = SNOR_PROTO_DTR(1, 4, 4),\n"
- " \tSNOR_PROTO_1_8_8_DTR = SNOR_PROTO_DTR(1, 8, 8),\n"
- "+\tSNOR_PROTO_8_8_8_DTR = SNOR_PROTO_DTR(8, 8, 8),\n"
- " };\n"
- " \n"
- " static inline bool spi_nor_protocol_is_dtr(enum spi_nor_protocol proto)\n"
- "@@ -228,7 +229,7 @@ struct spi_nor_hwcaps {\n"
- "  * then Quad SPI protocols before Dual SPI protocols, Fast Read and lastly\n"
- "  * (Slow) Read.\n"
- "  */\n"
- "-#define SNOR_HWCAPS_READ_MASK\t\tGENMASK(14, 0)\n"
- "+#define SNOR_HWCAPS_READ_MASK\t\tGENMASK(15, 0)\n"
- " #define SNOR_HWCAPS_READ\t\tBIT(0)\n"
- " #define SNOR_HWCAPS_READ_FAST\t\tBIT(1)\n"
- " #define SNOR_HWCAPS_READ_1_1_1_DTR\tBIT(2)\n"
- "@@ -245,11 +246,12 @@ struct spi_nor_hwcaps {\n"
- " #define SNOR_HWCAPS_READ_4_4_4\t\tBIT(9)\n"
- " #define SNOR_HWCAPS_READ_1_4_4_DTR\tBIT(10)\n"
- " \n"
- "-#define SNOR_HWCAPS_READ_OCTAL\t\tGENMASK(14, 11)\n"
- "+#define SNOR_HWCAPS_READ_OCTAL\t\tGENMASK(15, 11)\n"
- " #define SNOR_HWCAPS_READ_1_1_8\t\tBIT(11)\n"
- " #define SNOR_HWCAPS_READ_1_8_8\t\tBIT(12)\n"
- " #define SNOR_HWCAPS_READ_8_8_8\t\tBIT(13)\n"
- " #define SNOR_HWCAPS_READ_1_8_8_DTR\tBIT(14)\n"
- "+#define SNOR_HWCAPS_READ_8_8_8_DTR\tBIT(15)\n"
- " \n"
- " /*\n"
- "  * Page Program capabilities.\n"
- "@@ -260,18 +262,19 @@ struct spi_nor_hwcaps {\n"
- "  * JEDEC/SFDP standard to define them. Also at this moment no SPI flash memory\n"
- "  * implements such commands.\n"
- "  */\n"
- "-#define SNOR_HWCAPS_PP_MASK\tGENMASK(22, 16)\n"
- "-#define SNOR_HWCAPS_PP\t\tBIT(16)\n"
- "+#define SNOR_HWCAPS_PP_MASK\t\tGENMASK(23, 16)\n"
- "+#define SNOR_HWCAPS_PP\t\t\tBIT(16)\n"
- " \n"
- "-#define SNOR_HWCAPS_PP_QUAD\tGENMASK(19, 17)\n"
- "-#define SNOR_HWCAPS_PP_1_1_4\tBIT(17)\n"
- "-#define SNOR_HWCAPS_PP_1_4_4\tBIT(18)\n"
- "-#define SNOR_HWCAPS_PP_4_4_4\tBIT(19)\n"
- "+#define SNOR_HWCAPS_PP_QUAD\t\tGENMASK(19, 17)\n"
- "+#define SNOR_HWCAPS_PP_1_1_4\t\tBIT(17)\n"
- "+#define SNOR_HWCAPS_PP_1_4_4\t\tBIT(18)\n"
- "+#define SNOR_HWCAPS_PP_4_4_4\t\tBIT(19)\n"
- " \n"
- "-#define SNOR_HWCAPS_PP_OCTAL\tGENMASK(22, 20)\n"
- "-#define SNOR_HWCAPS_PP_1_1_8\tBIT(20)\n"
- "-#define SNOR_HWCAPS_PP_1_8_8\tBIT(21)\n"
- "-#define SNOR_HWCAPS_PP_8_8_8\tBIT(22)\n"
- "+#define SNOR_HWCAPS_PP_OCTAL\t\tGENMASK(23, 20)\n"
- "+#define SNOR_HWCAPS_PP_1_1_8\t\tBIT(20)\n"
- "+#define SNOR_HWCAPS_PP_1_8_8\t\tBIT(21)\n"
- "+#define SNOR_HWCAPS_PP_8_8_8\t\tBIT(22)\n"
- "+#define SNOR_HWCAPS_PP_8_8_8_DTR\tBIT(23)\n"
- " \n"
- " #define SNOR_HWCAPS_X_X_X\t(SNOR_HWCAPS_READ_2_2_2 |\t\\\n"
- " \t\t\t\t SNOR_HWCAPS_READ_4_4_4 |\t\\\n"
- "@@ -279,10 +282,14 @@ struct spi_nor_hwcaps {\n"
- " \t\t\t\t SNOR_HWCAPS_PP_4_4_4 |\t\t\\\n"
- " \t\t\t\t SNOR_HWCAPS_PP_8_8_8)\n"
- " \n"
- "+#define SNOR_HWCAPS_X_X_X_DTR\t(SNOR_HWCAPS_READ_8_8_8_DTR |\t\\\n"
- "+\t\t\t\t SNOR_HWCAPS_PP_8_8_8_DTR)\n"
- "+\n"
- " #define SNOR_HWCAPS_DTR\t\t(SNOR_HWCAPS_READ_1_1_1_DTR |\t\\\n"
- " \t\t\t\t SNOR_HWCAPS_READ_1_2_2_DTR |\t\\\n"
- " \t\t\t\t SNOR_HWCAPS_READ_1_4_4_DTR |\t\\\n"
- "-\t\t\t\t SNOR_HWCAPS_READ_1_8_8_DTR)\n"
- "+\t\t\t\t SNOR_HWCAPS_READ_1_8_8_DTR |\t\\\n"
- "+\t\t\t\t SNOR_HWCAPS_READ_8_8_8_DTR)\n"
- " \n"
- " #define SNOR_HWCAPS_ALL\t\t(SNOR_HWCAPS_READ_MASK |\t\\\n"
- " \t\t\t\t SNOR_HWCAPS_PP_MASK)\n"
- "@@ -318,6 +325,22 @@ struct spi_nor_controller_ops {\n"
- " \tint (*erase)(struct spi_nor *nor, loff_t offs);\n"
- " };\n"
- " \n"
- "+/**\n"
- "+ * enum spi_nor_cmd_ext - describes the command opcode extension in DTR mode\n"
- "+ * @SPI_NOR_EXT_NONE: no extension. This is the default, and is used in Legacy\n"
- "+ *\t\t      SPI mode\n"
- "+ * @SPI_NOR_EXT_REPEAT: the extension is same as the opcode\n"
- "+ * @SPI_NOR_EXT_INVERT: the extension is the bitwise inverse of the opcode\n"
- "+ * @SPI_NOR_EXT_HEX: the extension is any hex value. The command and opcode\n"
- "+ *\t\t     combine to form a 16-bit opcode.\n"
- "+ */\n"
- "+enum spi_nor_cmd_ext {\n"
- "+\tSPI_NOR_EXT_NONE = 0,\n"
- "+\tSPI_NOR_EXT_REPEAT,\n"
- "+\tSPI_NOR_EXT_INVERT,\n"
- "+\tSPI_NOR_EXT_HEX,\n"
- "+};\n"
- "+\n"
- " /*\n"
- "  * Forward declarations that are used internally by the core and manufacturer\n"
- "  * drivers.\n"
- "@@ -345,6 +368,7 @@ struct spi_nor_flash_parameter;\n"
- "  * @program_opcode:\tthe program opcode\n"
- "  * @sst_write_second:\tused by the SST write operation\n"
- "  * @flags:\t\tflag options for the current SPI NOR (SNOR_F_*)\n"
- "+ * @cmd_ext_type:\tthe command opcode extension type for DTR mode.\n"
- "  * @read_proto:\t\tthe SPI protocol for read operations\n"
- "  * @write_proto:\tthe SPI protocol for write operations\n"
- "  * @reg_proto:\t\tthe SPI protocol for read_reg/write_reg/erase operations\n"
- "@@ -376,6 +400,7 @@ struct spi_nor {\n"
- " \tenum spi_nor_protocol\treg_proto;\n"
- " \tbool\t\t\tsst_write_second;\n"
- " \tu32\t\t\tflags;\n"
- "+\tenum spi_nor_cmd_ext\tcmd_ext_type;\n"
- " \n"
- " \tconst struct spi_nor_controller_ops *controller_ops;\n"
- " \n"
- "-- \n"
- 2.28.0
 
-6d52ce73a74043b95d545933fc33f9875d5878c1b53dd2c8c6e86970bcf8340b
+d7ad0b97a3b2a9dd49cd46dc81241ae5749fae698534a4775f984ccf6d01b12d

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox