Skip to content

Commit

Permalink
mtd: spi-nore: core: Add in framework for 8S-8S-8S Octal STR mode
Browse files Browse the repository at this point in the history
While trying to bring up an Octal SPI device in STR mode, I found
that there is currently no support for 8S-8S-8S.  This patch adds
the necessary, additional logic for doing so.

Signed-off-by: Nathan Barrett-Morrison <nathan.morrison@timesys.com>
  • Loading branch information
timesys-nathan authored and intel-lab-lkp committed Nov 23, 2022
1 parent eb70814 commit 47217ef
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 3 deletions.
57 changes: 55 additions & 2 deletions drivers/mtd/spi-nor/core.c
Expand Up @@ -2253,7 +2253,8 @@ static int spi_nor_set_addr_nbytes(struct spi_nor *nor)
{
if (nor->params->addr_nbytes) {
nor->addr_nbytes = nor->params->addr_nbytes;
} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR) {
} else if (nor->read_proto == SNOR_PROTO_8_8_8_DTR ||
nor->read_proto == SNOR_PROTO_8_8_8) {
/*
* In 8D-8D-8D mode, one byte takes half a cycle to transfer. So
* in this protocol an odd addr_nbytes cannot be used because
Expand Down Expand Up @@ -2335,7 +2336,7 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
{
struct spi_nor_flash_parameter *params = nor->params;
struct spi_nor_erase_map *map = &params->erase_map;
const u8 no_sfdp_flags = nor->info->no_sfdp_flags;
const u16 no_sfdp_flags = nor->info->no_sfdp_flags;
u8 i, erase_mask;

if (no_sfdp_flags & SPI_NOR_DUAL_READ) {
Expand All @@ -2359,13 +2360,26 @@ static void spi_nor_no_sfdp_init_params(struct spi_nor *nor)
SNOR_PROTO_1_1_8);
}

if (no_sfdp_flags & SPI_NOR_OCTAL_STR_READ) {
params->hwcaps.mask |= SNOR_HWCAPS_READ_8_8_8;
spi_nor_set_read_settings(&params->reads[SNOR_HWCAPS_READ_8_8_8],
0, 20, SPINOR_OP_READ_FAST,
SNOR_PROTO_8_8_8);
}

if (no_sfdp_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);
}

if (no_sfdp_flags & SPI_NOR_OCTAL_STR_PP) {
params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8;
spi_nor_set_pp_settings(&params->page_programs[SNOR_CMD_PP_8_8_8],
SPINOR_OP_PP, SNOR_PROTO_8_8_8);
}

if (no_sfdp_flags & SPI_NOR_OCTAL_DTR_PP) {
params->hwcaps.mask |= SNOR_HWCAPS_PP_8_8_8_DTR;
/*
Expand Down Expand Up @@ -2631,6 +2645,38 @@ static int spi_nor_init_params(struct spi_nor *nor)
return 0;
}

/** spi_nor_octal_str_enable() - enable Octal STR I/O if needed
* @nor: pointer to a 'struct spi_nor'
* @enable: whether to enable or disable Octal STR
*
* Return: 0 on success, -errno otherwise.
*/
static int spi_nor_octal_str_enable(struct spi_nor *nor, bool enable)
{
int ret;

if (!nor->params->octal_str_enable)
return 0;

if (!(nor->read_proto == SNOR_PROTO_8_8_8 &&
nor->write_proto == SNOR_PROTO_8_8_8))
return 0;

if (!(nor->flags & SNOR_F_IO_MODE_EN_VOLATILE))
return 0;

ret = nor->params->octal_str_enable(nor, enable);
if (ret)
return ret;

if (enable)
nor->reg_proto = SNOR_PROTO_8_8_8;
else
nor->reg_proto = SNOR_PROTO_1_1_1;

return 0;
}

/** spi_nor_octal_dtr_enable() - enable Octal DTR I/O if needed
* @nor: pointer to a 'struct spi_nor'
* @enable: whether to enable or disable Octal DTR
Expand Down Expand Up @@ -2691,6 +2737,12 @@ static int spi_nor_init(struct spi_nor *nor)
return err;
}

err = spi_nor_octal_str_enable(nor, true);
if (err) {
dev_dbg(nor->dev, "octal STR mode not supported\n");
return err;
}

err = spi_nor_quad_enable(nor);
if (err) {
dev_dbg(nor->dev, "quad mode not supported\n");
Expand All @@ -2714,6 +2766,7 @@ static int spi_nor_init(struct spi_nor *nor)

if (nor->addr_nbytes == 4 &&
nor->read_proto != SNOR_PROTO_8_8_8_DTR &&
nor->read_proto != SNOR_PROTO_8_8_8 &&
!(nor->flags & SNOR_F_4B_OPCODES)) {
/*
* If the RESET# pin isn't hooked up properly, or the system
Expand Down
5 changes: 4 additions & 1 deletion drivers/mtd/spi-nor/core.h
Expand Up @@ -359,6 +359,7 @@ struct spi_nor_otp {
* Table.
* @otp: SPI NOR OTP info.
* @octal_dtr_enable: enables SPI NOR octal DTR mode.
* @octal_str_enable: enables SPI NOR octal STR mode.
* @quad_enable: enables SPI NOR quad mode.
* @set_4byte_addr_mode: puts the SPI NOR in 4 byte addressing mode.
* @convert_addr: converts an absolute address into something the flash
Expand Down Expand Up @@ -508,14 +509,16 @@ struct flash_info {
#define NO_CHIP_ERASE BIT(7)
#define SPI_NOR_NO_FR BIT(8)

u8 no_sfdp_flags;
u16 no_sfdp_flags;
#define SPI_NOR_SKIP_SFDP BIT(0)
#define SECT_4K BIT(1)
#define SPI_NOR_DUAL_READ BIT(3)
#define SPI_NOR_QUAD_READ BIT(4)
#define SPI_NOR_OCTAL_READ BIT(5)
#define SPI_NOR_OCTAL_DTR_READ BIT(6)
#define SPI_NOR_OCTAL_DTR_PP BIT(7)
#define SPI_NOR_OCTAL_STR_READ BIT(8)
#define SPI_NOR_OCTAL_STR_PP BIT(9)

u8 fixup_flags;
#define SPI_NOR_4B_OPCODES BIT(0)
Expand Down

0 comments on commit 47217ef

Please sign in to comment.