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(¶ms->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(¶ms->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(¶ms->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(¶ms_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(¶ms_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(¶ms_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(¶ms->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(¶ms->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(¶ms->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(¶ms_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(¶ms_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(¶ms_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