2020-03-13 19:42:46 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
/*
|
|
|
|
* Copyright (C) 2005, Intec Automation Inc.
|
|
|
|
* Copyright (C) 2014, Freescale Semiconductor, Inc.
|
|
|
|
*/
|
|
|
|
|
2023-07-26 07:52:48 +00:00
|
|
|
#include <linux/bitfield.h>
|
2023-07-26 07:52:47 +00:00
|
|
|
#include <linux/device.h>
|
2023-07-26 07:52:50 +00:00
|
|
|
#include <linux/errno.h>
|
2020-03-13 19:42:46 +00:00
|
|
|
#include <linux/mtd/spi-nor.h>
|
|
|
|
|
|
|
|
#include "core.h"
|
|
|
|
|
2022-02-23 13:43:55 +00:00
|
|
|
/* flash_info mfr_flag. Used to clear sticky prorietary SR bits. */
|
|
|
|
#define USE_CLSR BIT(0)
|
2023-07-26 07:52:47 +00:00
|
|
|
#define USE_CLPEF BIT(1)
|
2022-02-23 13:43:55 +00:00
|
|
|
|
2022-02-23 13:43:54 +00:00
|
|
|
#define SPINOR_OP_CLSR 0x30 /* Clear status register 1 */
|
2023-07-26 07:52:47 +00:00
|
|
|
#define SPINOR_OP_CLPEF 0x82 /* Clear program/erase failure flags */
|
2020-10-05 15:31:37 +00:00
|
|
|
#define SPINOR_OP_RD_ANY_REG 0x65 /* Read any register */
|
|
|
|
#define SPINOR_OP_WR_ANY_REG 0x71 /* Write any register */
|
2023-04-07 06:41:01 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_VREG 0x00800000
|
|
|
|
#define SPINOR_REG_CYPRESS_STR1 0x0
|
|
|
|
#define SPINOR_REG_CYPRESS_STR1V \
|
|
|
|
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_STR1)
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR1 0x2
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR1V \
|
|
|
|
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR1)
|
2023-01-10 16:47:03 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR1_QUAD_EN BIT(1) /* Quad Enable */
|
2023-04-07 06:41:01 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR2 0x3
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR2V \
|
|
|
|
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR2)
|
2023-07-26 07:52:48 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK GENMASK(3, 0)
|
2023-01-10 16:47:03 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24 0xb
|
2023-03-31 07:46:06 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR2_ADRBYT BIT(7)
|
2023-04-07 06:41:01 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR3 0x4
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR3V \
|
|
|
|
(SPINOR_REG_CYPRESS_VREG + SPINOR_REG_CYPRESS_CFR3)
|
2023-01-10 16:47:03 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR3_PGSZ BIT(4) /* Page size. */
|
2023-04-07 06:41:01 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR5 0x6
|
2023-01-10 16:47:02 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR5_BIT6 BIT(6)
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR5_DDR BIT(1)
|
|
|
|
#define SPINOR_REG_CYPRESS_CFR5_OPI BIT(0)
|
2023-01-10 16:47:03 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN \
|
2023-01-10 16:47:02 +00:00
|
|
|
(SPINOR_REG_CYPRESS_CFR5_BIT6 | SPINOR_REG_CYPRESS_CFR5_DDR | \
|
|
|
|
SPINOR_REG_CYPRESS_CFR5_OPI)
|
2023-01-10 16:47:03 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS SPINOR_REG_CYPRESS_CFR5_BIT6
|
2020-10-05 15:31:37 +00:00
|
|
|
#define SPINOR_OP_CYPRESS_RD_FAST 0xee
|
2023-03-02 07:35:07 +00:00
|
|
|
#define SPINOR_REG_CYPRESS_ARCFN 0x00000006
|
2020-10-05 15:31:37 +00:00
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
/* Cypress SPI NOR flash operations. */
|
|
|
|
#define CYPRESS_NOR_WR_ANY_REG_OP(naddr, addr, ndata, buf) \
|
|
|
|
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_WR_ANY_REG, 0), \
|
|
|
|
SPI_MEM_OP_ADDR(naddr, addr, 0), \
|
|
|
|
SPI_MEM_OP_NO_DUMMY, \
|
|
|
|
SPI_MEM_OP_DATA_OUT(ndata, buf, 0))
|
|
|
|
|
2023-03-02 07:35:06 +00:00
|
|
|
#define CYPRESS_NOR_RD_ANY_REG_OP(naddr, addr, ndummy, buf) \
|
2022-04-20 10:34:25 +00:00
|
|
|
SPI_MEM_OP(SPI_MEM_OP_CMD(SPINOR_OP_RD_ANY_REG, 0), \
|
|
|
|
SPI_MEM_OP_ADDR(naddr, addr, 0), \
|
2023-03-02 07:35:06 +00:00
|
|
|
SPI_MEM_OP_DUMMY(ndummy, 0), \
|
2022-04-20 10:34:25 +00:00
|
|
|
SPI_MEM_OP_DATA_IN(1, buf, 0))
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
#define SPANSION_OP(opcode) \
|
|
|
|
SPI_MEM_OP(SPI_MEM_OP_CMD(opcode, 0), \
|
2022-04-20 10:34:25 +00:00
|
|
|
SPI_MEM_OP_NO_ADDR, \
|
|
|
|
SPI_MEM_OP_NO_DUMMY, \
|
|
|
|
SPI_MEM_OP_NO_DATA)
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
/**
|
|
|
|
* struct spansion_nor_params - Spansion private parameters.
|
|
|
|
* @clsr: Clear Status Register or Clear Program and Erase Failure Flag
|
|
|
|
* opcode.
|
|
|
|
*/
|
|
|
|
struct spansion_nor_params {
|
|
|
|
u8 clsr;
|
|
|
|
};
|
|
|
|
|
2023-04-07 06:41:03 +00:00
|
|
|
/**
|
|
|
|
* spansion_nor_clear_sr() - Clear the Status Register.
|
|
|
|
* @nor: pointer to 'struct spi_nor'.
|
|
|
|
*/
|
|
|
|
static void spansion_nor_clear_sr(struct spi_nor *nor)
|
|
|
|
{
|
2023-07-26 07:52:47 +00:00
|
|
|
const struct spansion_nor_params *priv_params = nor->params->priv;
|
2023-04-07 06:41:03 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (nor->spimem) {
|
2023-07-26 07:52:47 +00:00
|
|
|
struct spi_mem_op op = SPANSION_OP(priv_params->clsr);
|
2023-04-07 06:41:03 +00:00
|
|
|
|
|
|
|
spi_nor_spimem_setup_op(nor, &op, nor->reg_proto);
|
|
|
|
|
|
|
|
ret = spi_mem_exec_op(nor->spimem, &op);
|
|
|
|
} else {
|
|
|
|
ret = spi_nor_controller_ops_write_reg(nor, SPINOR_OP_CLSR,
|
|
|
|
NULL, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ret)
|
|
|
|
dev_dbg(nor->dev, "error %d clearing SR\n", ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cypress_nor_sr_ready_and_clear_reg(struct spi_nor *nor, u64 addr)
|
|
|
|
{
|
|
|
|
struct spi_mem_op op =
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes, addr,
|
|
|
|
0, nor->bouncebuf);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
|
|
|
|
if (nor->bouncebuf[0] & SR_E_ERR)
|
|
|
|
dev_err(nor->dev, "Erase Error occurred\n");
|
|
|
|
else
|
|
|
|
dev_err(nor->dev, "Programming Error occurred\n");
|
|
|
|
|
|
|
|
spansion_nor_clear_sr(nor);
|
|
|
|
|
|
|
|
ret = spi_nor_write_disable(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !(nor->bouncebuf[0] & SR_WIP);
|
|
|
|
}
|
|
|
|
/**
|
|
|
|
* cypress_nor_sr_ready_and_clear() - Query the Status Register of each die by
|
|
|
|
* using Read Any Register command to see if the whole flash is ready for new
|
|
|
|
* commands and clear it if there are any errors.
|
|
|
|
* @nor: pointer to 'struct spi_nor'.
|
|
|
|
*
|
|
|
|
* Return: 1 if ready, 0 if not ready, -errno on errors.
|
|
|
|
*/
|
|
|
|
static int cypress_nor_sr_ready_and_clear(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
u64 addr;
|
|
|
|
int ret;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
for (i = 0; i < params->n_dice; i++) {
|
|
|
|
addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_STR1;
|
|
|
|
ret = cypress_nor_sr_ready_and_clear_reg(nor, addr);
|
|
|
|
if (ret < 0)
|
|
|
|
return ret;
|
|
|
|
else if (ret == 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:49 +00:00
|
|
|
static int cypress_nor_set_memlat(struct spi_nor *nor, u64 addr)
|
2020-10-05 15:31:37 +00:00
|
|
|
{
|
|
|
|
struct spi_mem_op op;
|
|
|
|
u8 *buf = nor->bouncebuf;
|
|
|
|
int ret;
|
2022-07-28 04:14:50 +00:00
|
|
|
u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
|
2020-10-05 15:31:37 +00:00
|
|
|
|
2023-07-26 07:52:48 +00:00
|
|
|
op = (struct spi_mem_op)
|
2023-07-26 07:52:49 +00:00
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0, buf);
|
2023-07-26 07:52:48 +00:00
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
/* Use 24 dummy cycles for memory array reads. */
|
2023-07-26 07:52:48 +00:00
|
|
|
*buf &= ~SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK;
|
|
|
|
*buf |= FIELD_PREP(SPINOR_REG_CYPRESS_CFR2_MEMLAT_MASK,
|
|
|
|
SPINOR_REG_CYPRESS_CFR2_MEMLAT_11_24);
|
2022-04-20 10:34:24 +00:00
|
|
|
op = (struct spi_mem_op)
|
2023-07-26 07:52:49 +00:00
|
|
|
CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1, buf);
|
2020-10-05 15:31:37 +00:00
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
|
2020-10-05 15:31:37 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
nor->read_dummy = 24;
|
2020-10-05 15:31:37 +00:00
|
|
|
|
2023-07-26 07:52:49 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cypress_nor_set_octal_dtr_bits(struct spi_nor *nor, u64 addr)
|
|
|
|
{
|
|
|
|
struct spi_mem_op op;
|
|
|
|
u8 *buf = nor->bouncebuf;
|
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
/* Set the octal and DTR enable bits. */
|
2023-01-10 16:47:03 +00:00
|
|
|
buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_EN;
|
2022-04-20 10:34:24 +00:00
|
|
|
op = (struct spi_mem_op)
|
2023-07-26 07:52:49 +00:00
|
|
|
CYPRESS_NOR_WR_ANY_REG_OP(nor->params->addr_mode_nbytes,
|
|
|
|
addr, 1, buf);
|
2020-10-05 15:31:37 +00:00
|
|
|
|
2023-07-26 07:52:49 +00:00
|
|
|
return spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cypress_nor_octal_dtr_en(struct spi_nor *nor)
|
|
|
|
{
|
2023-07-26 07:52:50 +00:00
|
|
|
const struct spi_nor_flash_parameter *params = nor->params;
|
2023-07-26 07:52:49 +00:00
|
|
|
u8 *buf = nor->bouncebuf;
|
2023-07-26 07:52:50 +00:00
|
|
|
u64 addr;
|
2023-07-26 07:52:49 +00:00
|
|
|
int ret;
|
|
|
|
|
2023-07-26 07:52:50 +00:00
|
|
|
addr = params->vreg_offset[0] + SPINOR_REG_CYPRESS_CFR2;
|
|
|
|
ret = cypress_nor_set_memlat(nor, addr);
|
2023-07-26 07:52:49 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2023-07-26 07:52:50 +00:00
|
|
|
addr = params->vreg_offset[0] + SPINOR_REG_CYPRESS_CFR5;
|
|
|
|
ret = cypress_nor_set_octal_dtr_bits(nor, addr);
|
2020-10-05 15:31:37 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* Read flash ID to make sure the switch was successful. */
|
2022-07-28 04:14:50 +00:00
|
|
|
ret = spi_nor_read_id(nor, nor->addr_nbytes, 3, buf,
|
|
|
|
SNOR_PROTO_8_8_8_DTR);
|
2022-04-20 10:34:24 +00:00
|
|
|
if (ret) {
|
|
|
|
dev_dbg(nor->dev, "error %d reading JEDEC ID after enabling 8D-8D-8D mode\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (memcmp(buf, nor->info->id, nor->info->id_len))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:49 +00:00
|
|
|
static int cypress_nor_set_single_spi_bits(struct spi_nor *nor, u64 addr)
|
2022-04-20 10:34:24 +00:00
|
|
|
{
|
|
|
|
struct spi_mem_op op;
|
|
|
|
u8 *buf = nor->bouncebuf;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The register is 1-byte wide, but 1-byte transactions are not allowed
|
|
|
|
* in 8D-8D-8D mode. Since there is no register at the next location,
|
|
|
|
* just initialize the value to 0 and let the transaction go on.
|
|
|
|
*/
|
2023-01-10 16:47:03 +00:00
|
|
|
buf[0] = SPINOR_REG_CYPRESS_CFR5_OCT_DTR_DS;
|
2022-04-20 10:34:24 +00:00
|
|
|
buf[1] = 0;
|
|
|
|
op = (struct spi_mem_op)
|
2023-07-26 07:52:49 +00:00
|
|
|
CYPRESS_NOR_WR_ANY_REG_OP(nor->addr_nbytes, addr, 2, buf);
|
|
|
|
return spi_nor_write_any_volatile_reg(nor, &op, SNOR_PROTO_8_8_8_DTR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cypress_nor_octal_dtr_dis(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
u8 *buf = nor->bouncebuf;
|
2023-07-26 07:52:50 +00:00
|
|
|
u64 addr;
|
2023-07-26 07:52:49 +00:00
|
|
|
int ret;
|
|
|
|
|
2023-07-26 07:52:50 +00:00
|
|
|
addr = nor->params->vreg_offset[0] + SPINOR_REG_CYPRESS_CFR5;
|
|
|
|
ret = cypress_nor_set_single_spi_bits(nor, addr);
|
2020-10-05 15:31:37 +00:00
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
/* Read flash ID to make sure the switch was successful. */
|
|
|
|
ret = spi_nor_read_id(nor, 0, 0, buf, SNOR_PROTO_1_1_1);
|
|
|
|
if (ret) {
|
|
|
|
dev_dbg(nor->dev, "error %d reading JEDEC ID after disabling 8D-8D-8D mode\n", ret);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2020-10-05 15:31:37 +00:00
|
|
|
if (memcmp(buf, nor->info->id, nor->info->id_len))
|
|
|
|
return -EINVAL;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:41:02 +00:00
|
|
|
static int cypress_nor_quad_enable_volatile_reg(struct spi_nor *nor, u64 addr)
|
2022-07-25 09:25:05 +00:00
|
|
|
{
|
|
|
|
struct spi_mem_op op;
|
|
|
|
u8 addr_mode_nbytes = nor->params->addr_mode_nbytes;
|
|
|
|
u8 cfr1v_written;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
op = (struct spi_mem_op)
|
2023-04-07 06:41:02 +00:00
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
|
2022-07-25 09:25:05 +00:00
|
|
|
nor->bouncebuf);
|
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2023-01-10 16:47:03 +00:00
|
|
|
if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR1_QUAD_EN)
|
2022-07-25 09:25:05 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* Update the Quad Enable bit. */
|
2023-01-10 16:47:03 +00:00
|
|
|
nor->bouncebuf[0] |= SPINOR_REG_CYPRESS_CFR1_QUAD_EN;
|
2022-07-25 09:25:05 +00:00
|
|
|
op = (struct spi_mem_op)
|
2023-04-07 06:41:02 +00:00
|
|
|
CYPRESS_NOR_WR_ANY_REG_OP(addr_mode_nbytes, addr, 1,
|
2022-07-25 09:25:05 +00:00
|
|
|
nor->bouncebuf);
|
|
|
|
ret = spi_nor_write_any_volatile_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
cfr1v_written = nor->bouncebuf[0];
|
|
|
|
|
|
|
|
/* Read back and check it. */
|
|
|
|
op = (struct spi_mem_op)
|
2023-04-07 06:41:02 +00:00
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(addr_mode_nbytes, addr, 0,
|
2022-07-25 09:25:05 +00:00
|
|
|
nor->bouncebuf);
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (nor->bouncebuf[0] != cfr1v_written) {
|
|
|
|
dev_err(nor->dev, "CFR1: Read back test failed\n");
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:41:02 +00:00
|
|
|
/**
|
|
|
|
* cypress_nor_quad_enable_volatile() - enable Quad I/O mode in volatile
|
|
|
|
* register.
|
|
|
|
* @nor: pointer to a 'struct spi_nor'
|
|
|
|
*
|
|
|
|
* It is recommended to update volatile registers in the field application due
|
|
|
|
* to a risk of the non-volatile registers corruption by power interrupt. This
|
|
|
|
* function sets Quad Enable bit in CFR1 volatile. If users set the Quad Enable
|
|
|
|
* bit in the CFR1 non-volatile in advance (typically by a Flash programmer
|
|
|
|
* before mounting Flash on PCB), the Quad Enable bit in the CFR1 volatile is
|
|
|
|
* also set during Flash power-up.
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno otherwise.
|
|
|
|
*/
|
|
|
|
static int cypress_nor_quad_enable_volatile(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
u64 addr;
|
|
|
|
u8 i;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (!params->n_dice)
|
|
|
|
return cypress_nor_quad_enable_volatile_reg(nor,
|
|
|
|
SPINOR_REG_CYPRESS_CFR1V);
|
|
|
|
|
|
|
|
for (i = 0; i < params->n_dice; i++) {
|
|
|
|
addr = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR1;
|
|
|
|
ret = cypress_nor_quad_enable_volatile_reg(nor, addr);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-03-31 07:46:06 +00:00
|
|
|
/**
|
|
|
|
* cypress_nor_determine_addr_mode_by_sr1() - Determine current address mode
|
|
|
|
* (3 or 4-byte) by querying status
|
|
|
|
* register 1 (SR1).
|
|
|
|
* @nor: pointer to a 'struct spi_nor'
|
|
|
|
* @addr_mode: ponter to a buffer where we return the determined
|
|
|
|
* address mode.
|
|
|
|
*
|
|
|
|
* This function tries to determine current address mode by comparing SR1 value
|
|
|
|
* from RDSR1(no address), RDAR(3-byte address), and RDAR(4-byte address).
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno otherwise.
|
|
|
|
*/
|
|
|
|
static int cypress_nor_determine_addr_mode_by_sr1(struct spi_nor *nor,
|
|
|
|
u8 *addr_mode)
|
|
|
|
{
|
|
|
|
struct spi_mem_op op =
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(3, SPINOR_REG_CYPRESS_STR1V, 0,
|
|
|
|
nor->bouncebuf);
|
|
|
|
bool is3byte, is4byte;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = spi_nor_read_sr(nor, &nor->bouncebuf[1]);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
is3byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
|
|
|
|
|
|
|
|
op = (struct spi_mem_op)
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(4, SPINOR_REG_CYPRESS_STR1V, 0,
|
|
|
|
nor->bouncebuf);
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
is4byte = (nor->bouncebuf[0] == nor->bouncebuf[1]);
|
|
|
|
|
|
|
|
if (is3byte == is4byte)
|
|
|
|
return -EIO;
|
|
|
|
if (is3byte)
|
|
|
|
*addr_mode = 3;
|
|
|
|
else
|
|
|
|
*addr_mode = 4;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cypress_nor_set_addr_mode_nbytes() - Set the number of address bytes mode of
|
|
|
|
* current address mode.
|
|
|
|
* @nor: pointer to a 'struct spi_nor'
|
|
|
|
*
|
|
|
|
* Determine current address mode by reading SR1 with different methods, then
|
|
|
|
* query CFR2V[7] to confirm. If determination is failed, force enter to 4-byte
|
|
|
|
* address mode.
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno otherwise.
|
|
|
|
*/
|
|
|
|
static int cypress_nor_set_addr_mode_nbytes(struct spi_nor *nor)
|
|
|
|
{
|
2023-05-09 19:39:00 +00:00
|
|
|
struct spi_mem_op op = {};
|
2023-03-31 07:46:06 +00:00
|
|
|
u8 addr_mode;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read SR1 by RDSR1 and RDAR(3- AND 4-byte addr). Use write enable
|
|
|
|
* that sets bit-1 in SR1.
|
|
|
|
*/
|
|
|
|
ret = spi_nor_write_enable(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
ret = cypress_nor_determine_addr_mode_by_sr1(nor, &addr_mode);
|
|
|
|
if (ret) {
|
|
|
|
ret = spi_nor_set_4byte_addr_mode(nor, true);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
return spi_nor_write_disable(nor);
|
|
|
|
}
|
|
|
|
ret = spi_nor_write_disable(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Query CFR2V and make sure no contradiction between determined address
|
|
|
|
* mode and CFR2V[7].
|
|
|
|
*/
|
|
|
|
op = (struct spi_mem_op)
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(addr_mode, SPINOR_REG_CYPRESS_CFR2V,
|
|
|
|
0, nor->bouncebuf);
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR2_ADRBYT) {
|
|
|
|
if (addr_mode != 4)
|
|
|
|
return spi_nor_set_4byte_addr_mode(nor, true);
|
|
|
|
} else {
|
|
|
|
if (addr_mode != 3)
|
|
|
|
return spi_nor_set_4byte_addr_mode(nor, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
nor->params->addr_nbytes = addr_mode;
|
|
|
|
nor->params->addr_mode_nbytes = addr_mode;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:41:01 +00:00
|
|
|
static int cypress_nor_get_page_size_single_chip(struct spi_nor *nor)
|
2022-07-25 09:25:04 +00:00
|
|
|
{
|
|
|
|
struct spi_mem_op op =
|
2022-07-28 04:14:50 +00:00
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
|
2023-03-02 07:35:06 +00:00
|
|
|
SPINOR_REG_CYPRESS_CFR3V, 0,
|
2022-07-25 09:25:04 +00:00
|
|
|
nor->bouncebuf);
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2023-01-10 16:47:03 +00:00
|
|
|
if (nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ)
|
2022-07-25 09:25:04 +00:00
|
|
|
nor->params->page_size = 512;
|
|
|
|
else
|
|
|
|
nor->params->page_size = 256;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:41:01 +00:00
|
|
|
|
|
|
|
static int cypress_nor_get_page_size_mcp(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
struct spi_mem_op op =
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
|
|
|
|
0, 0, nor->bouncebuf);
|
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
int ret;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Use the minimum common page size configuration. Programming 256-byte
|
|
|
|
* under 512-byte page size configuration is safe.
|
|
|
|
*/
|
|
|
|
params->page_size = 256;
|
|
|
|
for (i = 0; i < params->n_dice; i++) {
|
|
|
|
op.addr.val = params->vreg_offset[i] + SPINOR_REG_CYPRESS_CFR3;
|
|
|
|
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (!(nor->bouncebuf[0] & SPINOR_REG_CYPRESS_CFR3_PGSZ))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
params->page_size = 512;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* cypress_nor_get_page_size() - Get flash page size configuration.
|
|
|
|
* @nor: pointer to a 'struct spi_nor'
|
|
|
|
*
|
|
|
|
* The BFPT table advertises a 512B or 256B page size depending on part but the
|
|
|
|
* page size is actually configurable (with the default being 256B). Read from
|
|
|
|
* CFR3V[4] and set the correct size.
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno otherwise.
|
|
|
|
*/
|
|
|
|
static int cypress_nor_get_page_size(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
if (nor->params->n_dice)
|
|
|
|
return cypress_nor_get_page_size_mcp(nor);
|
|
|
|
return cypress_nor_get_page_size_single_chip(nor);
|
|
|
|
}
|
|
|
|
|
2023-04-06 06:17:44 +00:00
|
|
|
static void cypress_nor_ecc_init(struct spi_nor *nor)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Programming is supported only in 16-byte ECC data unit granularity.
|
|
|
|
* Byte-programming, bit-walking, or multiple program operations to the
|
|
|
|
* same ECC data unit without an erase are not allowed.
|
|
|
|
*/
|
|
|
|
nor->params->writesize = 16;
|
|
|
|
nor->flags |= SNOR_F_ECC;
|
|
|
|
}
|
|
|
|
|
2023-03-02 07:35:07 +00:00
|
|
|
static int
|
|
|
|
s25fs256t_post_bfpt_fixup(struct spi_nor *nor,
|
|
|
|
const struct sfdp_parameter_header *bfpt_header,
|
|
|
|
const struct sfdp_bfpt *bfpt)
|
|
|
|
{
|
2023-05-09 19:39:00 +00:00
|
|
|
struct spi_mem_op op = {};
|
2023-03-02 07:35:07 +00:00
|
|
|
int ret;
|
|
|
|
|
2023-03-31 07:46:06 +00:00
|
|
|
ret = cypress_nor_set_addr_mode_nbytes(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
2023-03-02 07:35:07 +00:00
|
|
|
|
|
|
|
/* Read Architecture Configuration Register (ARCFN) */
|
|
|
|
op = (struct spi_mem_op)
|
|
|
|
CYPRESS_NOR_RD_ANY_REG_OP(nor->params->addr_mode_nbytes,
|
|
|
|
SPINOR_REG_CYPRESS_ARCFN, 1,
|
|
|
|
nor->bouncebuf);
|
|
|
|
ret = spi_nor_read_any_reg(nor, &op, nor->reg_proto);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
/* ARCFN value must be 0 if uniform sector is selected */
|
|
|
|
if (nor->bouncebuf[0])
|
|
|
|
return -ENODEV;
|
|
|
|
|
2023-04-07 06:40:57 +00:00
|
|
|
return cypress_nor_get_page_size(nor);
|
2023-03-02 07:35:07 +00:00
|
|
|
}
|
|
|
|
|
2023-04-07 06:40:58 +00:00
|
|
|
static int s25fs256t_post_sfdp_fixup(struct spi_nor *nor)
|
2023-03-02 07:35:07 +00:00
|
|
|
{
|
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
|
|
|
|
/* PP_1_1_4_4B is supported but missing in 4BAIT. */
|
|
|
|
params->hwcaps.mask |= SNOR_HWCAPS_PP_1_1_4;
|
|
|
|
spi_nor_set_pp_settings(¶ms->page_programs[SNOR_CMD_PP_1_1_4],
|
|
|
|
SPINOR_OP_PP_1_1_4_4B,
|
|
|
|
SNOR_PROTO_1_1_4);
|
2023-04-07 06:40:58 +00:00
|
|
|
|
|
|
|
return 0;
|
2023-03-02 07:35:07 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
static int s25fs256t_late_init(struct spi_nor *nor)
|
2023-03-02 07:35:07 +00:00
|
|
|
{
|
2023-04-06 06:17:46 +00:00
|
|
|
cypress_nor_ecc_init(nor);
|
2023-07-26 07:52:47 +00:00
|
|
|
|
|
|
|
return 0;
|
2023-03-02 07:35:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct spi_nor_fixups s25fs256t_fixups = {
|
|
|
|
.post_bfpt = s25fs256t_post_bfpt_fixup,
|
|
|
|
.post_sfdp = s25fs256t_post_sfdp_fixup,
|
|
|
|
.late_init = s25fs256t_late_init,
|
|
|
|
};
|
|
|
|
|
2022-07-25 09:25:05 +00:00
|
|
|
static int
|
|
|
|
s25hx_t_post_bfpt_fixup(struct spi_nor *nor,
|
|
|
|
const struct sfdp_parameter_header *bfpt_header,
|
|
|
|
const struct sfdp_bfpt *bfpt)
|
|
|
|
{
|
2023-03-31 07:46:06 +00:00
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = cypress_nor_set_addr_mode_nbytes(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
2022-07-25 09:25:05 +00:00
|
|
|
/* Replace Quad Enable with volatile version */
|
|
|
|
nor->params->quad_enable = cypress_nor_quad_enable_volatile;
|
|
|
|
|
2023-04-07 06:41:01 +00:00
|
|
|
return 0;
|
2022-07-25 09:25:05 +00:00
|
|
|
}
|
|
|
|
|
2023-04-07 06:40:58 +00:00
|
|
|
static int s25hx_t_post_sfdp_fixup(struct spi_nor *nor)
|
2022-07-25 09:25:05 +00:00
|
|
|
{
|
|
|
|
struct spi_nor_erase_type *erase_type =
|
|
|
|
nor->params->erase_map.erase_type;
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* In some parts, 3byte erase opcodes are advertised by 4BAIT.
|
|
|
|
* Convert them to 4byte erase opcodes.
|
|
|
|
*/
|
|
|
|
for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) {
|
|
|
|
switch (erase_type[i].opcode) {
|
|
|
|
case SPINOR_OP_SE:
|
|
|
|
erase_type[i].opcode = SPINOR_OP_SE_4B;
|
|
|
|
break;
|
|
|
|
case SPINOR_OP_BE_4K:
|
|
|
|
erase_type[i].opcode = SPINOR_OP_BE_4K_4B;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-04-07 06:40:58 +00:00
|
|
|
|
2023-04-07 06:41:04 +00:00
|
|
|
/* The 2 Gb parts duplicate info and advertise 4 dice instead of 2. */
|
|
|
|
if (nor->params->size == SZ_256M)
|
|
|
|
nor->params->n_dice = 2;
|
|
|
|
|
2023-04-07 06:41:01 +00:00
|
|
|
return cypress_nor_get_page_size(nor);
|
2022-07-25 09:25:05 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
static int s25hx_t_late_init(struct spi_nor *nor)
|
2022-07-25 09:25:05 +00:00
|
|
|
{
|
2023-04-07 06:41:03 +00:00
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
|
2022-07-25 09:25:05 +00:00
|
|
|
/* Fast Read 4B requires mode cycles */
|
2023-04-07 06:41:03 +00:00
|
|
|
params->reads[SNOR_CMD_READ_FAST].num_mode_clocks = 8;
|
2022-07-25 09:25:05 +00:00
|
|
|
|
2023-04-06 06:17:45 +00:00
|
|
|
cypress_nor_ecc_init(nor);
|
2023-04-07 06:41:03 +00:00
|
|
|
|
|
|
|
/* Replace ready() with multi die version */
|
|
|
|
if (params->n_dice)
|
|
|
|
params->ready = cypress_nor_sr_ready_and_clear;
|
2023-07-26 07:52:47 +00:00
|
|
|
|
|
|
|
return 0;
|
2022-07-25 09:25:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static struct spi_nor_fixups s25hx_t_fixups = {
|
|
|
|
.post_bfpt = s25hx_t_post_bfpt_fixup,
|
|
|
|
.post_sfdp = s25hx_t_post_sfdp_fixup,
|
|
|
|
.late_init = s25hx_t_late_init,
|
|
|
|
};
|
|
|
|
|
2022-04-20 10:34:24 +00:00
|
|
|
/**
|
2023-07-14 15:07:57 +00:00
|
|
|
* cypress_nor_set_octal_dtr() - Enable or disable octal DTR on Cypress flashes.
|
2022-04-20 10:34:24 +00:00
|
|
|
* @nor: pointer to a 'struct spi_nor'
|
|
|
|
* @enable: whether to enable or disable Octal DTR
|
|
|
|
*
|
|
|
|
* This also sets the memory access latency cycles to 24 to allow the flash to
|
|
|
|
* run at up to 200MHz.
|
|
|
|
*
|
|
|
|
* Return: 0 on success, -errno otherwise.
|
|
|
|
*/
|
2023-07-14 15:07:57 +00:00
|
|
|
static int cypress_nor_set_octal_dtr(struct spi_nor *nor, bool enable)
|
2022-04-20 10:34:24 +00:00
|
|
|
{
|
|
|
|
return enable ? cypress_nor_octal_dtr_en(nor) :
|
|
|
|
cypress_nor_octal_dtr_dis(nor);
|
|
|
|
}
|
|
|
|
|
2023-04-07 06:40:58 +00:00
|
|
|
static int s28hx_t_post_sfdp_fixup(struct spi_nor *nor)
|
2020-10-05 15:31:37 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* On older versions of the flash the xSPI Profile 1.0 table has the
|
|
|
|
* 8D-8D-8D Fast Read opcode as 0x00. But it actually should be 0xEE.
|
|
|
|
*/
|
|
|
|
if (nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode == 0)
|
|
|
|
nor->params->reads[SNOR_CMD_READ_8_8_8_DTR].opcode =
|
|
|
|
SPINOR_OP_CYPRESS_RD_FAST;
|
|
|
|
|
|
|
|
/* This flash is also missing the 4-byte Page Program opcode bit. */
|
|
|
|
spi_nor_set_pp_settings(&nor->params->page_programs[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(&nor->params->page_programs[SNOR_CMD_PP_8_8_8_DTR],
|
|
|
|
SPINOR_OP_PP_4B, SNOR_PROTO_8_8_8_DTR);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The xSPI Profile 1.0 table advertises the number of additional
|
|
|
|
* address bytes needed for Read Status Register command as 0 but the
|
|
|
|
* actual value for that is 4.
|
|
|
|
*/
|
|
|
|
nor->params->rdsr_addr_nbytes = 4;
|
2023-04-07 06:40:58 +00:00
|
|
|
|
2023-04-07 06:41:01 +00:00
|
|
|
return cypress_nor_get_page_size(nor);
|
2020-10-05 15:31:37 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 04:59:05 +00:00
|
|
|
static int s28hx_t_post_bfpt_fixup(struct spi_nor *nor,
|
|
|
|
const struct sfdp_parameter_header *bfpt_header,
|
|
|
|
const struct sfdp_bfpt *bfpt)
|
2020-10-05 15:31:37 +00:00
|
|
|
{
|
2023-07-21 17:09:11 +00:00
|
|
|
return cypress_nor_set_addr_mode_nbytes(nor);
|
2020-10-05 15:31:37 +00:00
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
static int s28hx_t_late_init(struct spi_nor *nor)
|
2022-08-31 04:59:04 +00:00
|
|
|
{
|
2023-07-26 07:52:50 +00:00
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
|
|
|
|
if (!params->n_dice || !params->vreg_offset) {
|
|
|
|
dev_err(nor->dev, "%s failed. The volatile register offset could not be retrieved from SFDP.\n",
|
|
|
|
__func__);
|
|
|
|
return -EOPNOTSUPP;
|
|
|
|
}
|
|
|
|
|
|
|
|
params->set_octal_dtr = cypress_nor_set_octal_dtr;
|
2023-07-26 07:52:51 +00:00
|
|
|
params->ready = cypress_nor_sr_ready_and_clear;
|
2023-04-06 06:17:44 +00:00
|
|
|
cypress_nor_ecc_init(nor);
|
2023-07-26 07:52:47 +00:00
|
|
|
|
|
|
|
return 0;
|
2022-08-31 04:59:04 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 04:59:05 +00:00
|
|
|
static const struct spi_nor_fixups s28hx_t_fixups = {
|
|
|
|
.post_sfdp = s28hx_t_post_sfdp_fixup,
|
|
|
|
.post_bfpt = s28hx_t_post_bfpt_fixup,
|
|
|
|
.late_init = s28hx_t_late_init,
|
2020-10-05 15:31:37 +00:00
|
|
|
};
|
|
|
|
|
2020-04-20 19:13:58 +00:00
|
|
|
static int
|
2022-02-23 13:43:38 +00:00
|
|
|
s25fs_s_nor_post_bfpt_fixups(struct spi_nor *nor,
|
|
|
|
const struct sfdp_parameter_header *bfpt_header,
|
|
|
|
const struct sfdp_bfpt *bfpt)
|
2020-04-20 19:13:58 +00:00
|
|
|
{
|
|
|
|
/*
|
|
|
|
* The S25FS-S chip family reports 512-byte pages in BFPT but
|
|
|
|
* in reality the write buffer still wraps at the safe default
|
|
|
|
* of 256 bytes. Overwrite the page size advertised by BFPT
|
|
|
|
* to get the writes working.
|
|
|
|
*/
|
2021-03-06 09:50:00 +00:00
|
|
|
nor->params->page_size = 256;
|
2020-04-20 19:13:58 +00:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-02-23 13:43:38 +00:00
|
|
|
static const struct spi_nor_fixups s25fs_s_nor_fixups = {
|
|
|
|
.post_bfpt = s25fs_s_nor_post_bfpt_fixups,
|
2020-04-20 19:13:58 +00:00
|
|
|
};
|
|
|
|
|
2022-02-23 13:43:38 +00:00
|
|
|
static const struct flash_info spansion_nor_parts[] = {
|
2020-03-13 19:42:46 +00:00
|
|
|
/* Spansion/Cypress -- single (large) sector size only, at least
|
|
|
|
* for the chips listed here (without boot sectors).
|
|
|
|
*/
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25sl032p", INFO(0x010215, 0x4d00, 64 * 1024, 64)
|
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25sl064p", INFO(0x010216, 0x4d00, 64 * 1024, 128)
|
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl128s0", INFO6(0x012018, 0x4d0080, 256 * 1024, 64)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fl128s1", INFO6(0x012018, 0x4d0180, 64 * 1024, 256)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fl256s0", INFO6(0x010219, 0x4d0080, 256 * 1024, 128)
|
2021-12-07 14:02:52 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_SKIP_SFDP | SPI_NOR_DUAL_READ |
|
2022-02-23 13:43:55 +00:00
|
|
|
SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fl256s1", INFO6(0x010219, 0x4d0180, 64 * 1024, 512)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fl512s", INFO6(0x010220, 0x4d0080, 256 * 1024, 256)
|
2022-02-23 13:43:55 +00:00
|
|
|
FLAGS(SPI_NOR_HAS_LOCK)
|
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fs128s1", INFO6(0x012018, 0x4d0181, 64 * 1024, 256)
|
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
2022-02-23 13:43:55 +00:00
|
|
|
MFR_FLAGS(USE_CLSR)
|
2022-02-23 13:43:38 +00:00
|
|
|
.fixups = &s25fs_s_nor_fixups, },
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fs256s0", INFO6(0x010219, 0x4d0081, 256 * 1024, 128)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fs256s1", INFO6(0x010219, 0x4d0181, 64 * 1024, 512)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fs512s", INFO6(0x010220, 0x4d0081, 256 * 1024, 256)
|
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
2022-02-23 13:43:55 +00:00
|
|
|
MFR_FLAGS(USE_CLSR)
|
2022-02-23 13:43:38 +00:00
|
|
|
.fixups = &s25fs_s_nor_fixups, },
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25sl12800", INFO(0x012018, 0x0300, 256 * 1024, 64) },
|
|
|
|
{ "s25sl12801", INFO(0x012018, 0x0301, 64 * 1024, 256) },
|
|
|
|
{ "s25fl129p0", INFO(0x012018, 0x4d00, 256 * 1024, 64)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25fl129p1", INFO(0x012018, 0x4d01, 64 * 1024, 256)
|
2022-02-23 13:43:55 +00:00
|
|
|
NO_SFDP_FLAGS(SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
MFR_FLAGS(USE_CLSR)
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s25sl004a", INFO(0x010212, 0, 64 * 1024, 8) },
|
|
|
|
{ "s25sl008a", INFO(0x010213, 0, 64 * 1024, 16) },
|
|
|
|
{ "s25sl016a", INFO(0x010214, 0, 64 * 1024, 32) },
|
|
|
|
{ "s25sl032a", INFO(0x010215, 0, 64 * 1024, 64) },
|
|
|
|
{ "s25sl064a", INFO(0x010216, 0, 64 * 1024, 128) },
|
|
|
|
{ "s25fl004k", INFO(0xef4013, 0, 64 * 1024, 8)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
|
|
|
SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl008k", INFO(0xef4014, 0, 64 * 1024, 16)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
|
|
|
SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl016k", INFO(0xef4015, 0, 64 * 1024, 32)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
|
|
|
SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl064k", INFO(0xef4017, 0, 64 * 1024, 128)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
|
|
|
SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl116k", INFO(0x014015, 0, 64 * 1024, 32)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ |
|
|
|
|
SPI_NOR_QUAD_READ) },
|
|
|
|
{ "s25fl132k", INFO(0x014016, 0, 64 * 1024, 64)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K) },
|
|
|
|
{ "s25fl164k", INFO(0x014017, 0, 64 * 1024, 128)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K) },
|
|
|
|
{ "s25fl204k", INFO(0x014013, 0, 64 * 1024, 8)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
|
|
|
|
{ "s25fl208k", INFO(0x014014, 0, 64 * 1024, 16)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ) },
|
|
|
|
{ "s25fl064l", INFO(0x016017, 0, 64 * 1024, 128)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
|
|
|
|
{ "s25fl128l", INFO(0x016018, 0, 64 * 1024, 256)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
|
|
|
|
{ "s25fl256l", INFO(0x016019, 0, 64 * 1024, 512)
|
|
|
|
NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ)
|
|
|
|
FIXUP_FLAGS(SPI_NOR_4B_OPCODES) },
|
2023-03-02 07:35:07 +00:00
|
|
|
{ "s25fs256t", INFO6(0x342b19, 0x0f0890, 0, 0)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2023-03-02 07:35:07 +00:00
|
|
|
.fixups = &s25fs256t_fixups },
|
2022-07-25 09:25:05 +00:00
|
|
|
{ "s25hl512t", INFO6(0x342a1a, 0x0f0390, 256 * 1024, 256)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-07-25 09:25:05 +00:00
|
|
|
.fixups = &s25hx_t_fixups },
|
|
|
|
{ "s25hl01gt", INFO6(0x342a1b, 0x0f0390, 256 * 1024, 512)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-07-25 09:25:05 +00:00
|
|
|
.fixups = &s25hx_t_fixups },
|
2023-04-07 06:41:04 +00:00
|
|
|
{ "s25hl02gt", INFO6(0x342a1c, 0x0f0090, 0, 0)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2023-04-07 06:41:04 +00:00
|
|
|
FLAGS(NO_CHIP_ERASE)
|
|
|
|
.fixups = &s25hx_t_fixups },
|
2022-07-25 09:25:05 +00:00
|
|
|
{ "s25hs512t", INFO6(0x342b1a, 0x0f0390, 256 * 1024, 256)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-07-25 09:25:05 +00:00
|
|
|
.fixups = &s25hx_t_fixups },
|
|
|
|
{ "s25hs01gt", INFO6(0x342b1b, 0x0f0390, 256 * 1024, 512)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-07-25 09:25:05 +00:00
|
|
|
.fixups = &s25hx_t_fixups },
|
2023-04-07 06:41:04 +00:00
|
|
|
{ "s25hs02gt", INFO6(0x342b1c, 0x0f0090, 0, 0)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2023-04-07 06:41:04 +00:00
|
|
|
FLAGS(NO_CHIP_ERASE)
|
|
|
|
.fixups = &s25hx_t_fixups },
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "cy15x104q", INFO6(0x042cc2, 0x7f7f7f, 512 * 1024, 1)
|
|
|
|
FLAGS(SPI_NOR_NO_ERASE) },
|
2022-08-31 04:59:06 +00:00
|
|
|
{ "s28hl512t", INFO(0x345a1a, 0, 256 * 1024, 256)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-08-31 04:59:06 +00:00
|
|
|
.fixups = &s28hx_t_fixups,
|
|
|
|
},
|
|
|
|
{ "s28hl01gt", INFO(0x345a1b, 0, 256 * 1024, 512)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-08-31 04:59:06 +00:00
|
|
|
.fixups = &s28hx_t_fixups,
|
|
|
|
},
|
mtd: spi-nor: Rework the flash_info flags
Clarify for what the flash_info flags are used for. Split them in
four categories and a bool:
1/ FLAGS: flags that indicate support that is not defined by the JESD216
standard in its SFDP tables.
2/ NO_SFDP_FLAGS: these flags are used when the flash does not define the
SFDP tables. These flags indicate support that can be discovered via
SFDP. Used together with SPI_NOR_SKIP_SFDP flag.
3/ FIXUP_FLAGS: flags that indicate support that can be discovered
via SFDP ideally, but can not be discovered for this particular flash
because the SFDP table that indicates this support is not defined by
the flash. In case the table for this support is defined but has wrong
values, one should instead use a post_sfdp() hook to set the SNOR_F
equivalent flag.
4/ MFR_FLAGS: manufacturer private flags. Used in the manufacturer
fixup hooks to differentiate support between flashes of the same
manufacturer.
5/ PARSE_SFDP: sets info->parse_sfdp to true. All flash_info entries
that support SFDP should be converted to set info->parse_sfdp to true.
SPI NOR flashes that statically declare one of the
SPI_NOR_{DUAL, QUAD, OCTAL, OCTAL_DTR}_READ flags and do not support
the RDSFDP command are gratuiously receiving the RDSFDP command
in the attempt of parsing the SFDP tables. It is not desirable to issue
commands that are not supported, so introduce PARSE_SFDP to help on this
situation.
New flash additions/updates should be declared/updated to use either
PARSE_SFDP or SPI_NOR_SKIP_SFDP. Once all the flash_info entries are
converted to use SPI_NOR_SKIP_SFDP or PARSE_SFDP, we can get rid of the
SPI_NOR_SKIP_SFDP flag and use just the bool nor->info->parse_sfdp to
determine whether to parse SFDP or not. SPI_NOR_SKIP_SFDP flag is kept
just as a way to differentiate whether a flash is converted to the new
flags logic or not.
Support that can be discovered when parsing SFDP should not be duplicated
by explicit flags at flash declaration. All the flash parameters will be
discovered when parsing SFDP. Sometimes manufacturers wrongly define some
fields in the SFDP tables. If that's the case, SFDP data can be amended
with the fixups() hooks. It is not common, but if the SFDP tables are
entirely wrong, and it does not worth the hassle to tweak the SFDP
parameters by using the fixups hooks, or if the flash does not define the
SFDP tables at all, then statically init the flash with the
SPI_NOR_SKIP_SFDP flag and specify the rest of flash capabilities with
the flash info flags.
With time, we want to convert all flashes to use PARSE_SFDP and
stop triggering the SFDP parsing with the
SPI_NOR_{DUAL, QUAD, OCTAL*}_READ flags. Getting rid of the
SPI_NOR_{OCTAL, OCTAL_DTR}_READ trigger is easily achievable,
the rest are a long term goal.
Manufacturer specific flags like USE_CLSR, USE_FSR, SPI_NOR_XSR_RDY,
will be removed in a future series.
No functional changes intended in this patch.
Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com>
Reviewed-by: Pratyush Yadav <p.yadav@ti.com>
Link: https://lore.kernel.org/r/20211207140254.87681-7-tudor.ambarus@microchip.com
2021-12-07 14:02:46 +00:00
|
|
|
{ "s28hs512t", INFO(0x345b1a, 0, 256 * 1024, 256)
|
2022-08-31 04:59:04 +00:00
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-08-31 04:59:05 +00:00
|
|
|
.fixups = &s28hx_t_fixups,
|
2020-10-05 15:31:37 +00:00
|
|
|
},
|
2022-08-31 04:59:06 +00:00
|
|
|
{ "s28hs01gt", INFO(0x345b1b, 0, 256 * 1024, 512)
|
|
|
|
PARSE_SFDP
|
2023-07-26 07:52:47 +00:00
|
|
|
MFR_FLAGS(USE_CLPEF)
|
2022-08-31 04:59:06 +00:00
|
|
|
.fixups = &s28hx_t_fixups,
|
|
|
|
},
|
2020-03-13 19:42:46 +00:00
|
|
|
};
|
|
|
|
|
2022-02-23 13:43:54 +00:00
|
|
|
/**
|
2022-02-23 13:43:56 +00:00
|
|
|
* spansion_nor_sr_ready_and_clear() - Query the Status Register to see if the
|
|
|
|
* flash is ready for new commands and clear it if there are any errors.
|
2022-02-23 13:43:54 +00:00
|
|
|
* @nor: pointer to 'struct spi_nor'.
|
|
|
|
*
|
|
|
|
* Return: 1 if ready, 0 if not ready, -errno on errors.
|
|
|
|
*/
|
2022-02-23 13:43:56 +00:00
|
|
|
static int spansion_nor_sr_ready_and_clear(struct spi_nor *nor)
|
2022-02-23 13:43:54 +00:00
|
|
|
{
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
ret = spi_nor_read_sr(nor, nor->bouncebuf);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
if (nor->bouncebuf[0] & (SR_E_ERR | SR_P_ERR)) {
|
|
|
|
if (nor->bouncebuf[0] & SR_E_ERR)
|
|
|
|
dev_err(nor->dev, "Erase Error occurred\n");
|
|
|
|
else
|
|
|
|
dev_err(nor->dev, "Programming Error occurred\n");
|
|
|
|
|
2022-02-23 13:43:56 +00:00
|
|
|
spansion_nor_clear_sr(nor);
|
2022-02-23 13:43:54 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* WEL bit remains set to one when an erase or page program
|
|
|
|
* error occurs. Issue a Write Disable command to protect
|
|
|
|
* against inadvertent writes that can possibly corrupt the
|
|
|
|
* contents of the memory.
|
|
|
|
*/
|
|
|
|
ret = spi_nor_write_disable(nor);
|
|
|
|
if (ret)
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
return -EIO;
|
|
|
|
}
|
|
|
|
|
|
|
|
return !(nor->bouncebuf[0] & SR_WIP);
|
|
|
|
}
|
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
static int spansion_nor_late_init(struct spi_nor *nor)
|
2020-03-13 19:42:46 +00:00
|
|
|
{
|
2023-07-26 07:52:47 +00:00
|
|
|
struct spi_nor_flash_parameter *params = nor->params;
|
|
|
|
struct spansion_nor_params *priv_params;
|
|
|
|
u8 mfr_flags = nor->info->mfr_flags;
|
|
|
|
|
|
|
|
if (params->size > SZ_16M) {
|
2022-02-23 13:43:53 +00:00
|
|
|
nor->flags |= SNOR_F_4B_OPCODES;
|
|
|
|
/* No small sector erase for 4-byte command set */
|
|
|
|
nor->erase_opcode = SPINOR_OP_SE;
|
|
|
|
nor->mtd.erasesize = nor->info->sector_size;
|
|
|
|
}
|
2022-02-23 13:43:54 +00:00
|
|
|
|
2023-07-26 07:52:47 +00:00
|
|
|
if (mfr_flags & (USE_CLSR | USE_CLPEF)) {
|
|
|
|
priv_params = devm_kmalloc(nor->dev, sizeof(*priv_params),
|
|
|
|
GFP_KERNEL);
|
|
|
|
if (!priv_params)
|
|
|
|
return -ENOMEM;
|
|
|
|
|
|
|
|
if (mfr_flags & USE_CLSR)
|
|
|
|
priv_params->clsr = SPINOR_OP_CLSR;
|
|
|
|
else if (mfr_flags & USE_CLPEF)
|
|
|
|
priv_params->clsr = SPINOR_OP_CLPEF;
|
|
|
|
|
|
|
|
params->priv = priv_params;
|
|
|
|
params->ready = spansion_nor_sr_ready_and_clear;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2020-03-13 19:42:46 +00:00
|
|
|
}
|
|
|
|
|
2022-02-23 13:43:38 +00:00
|
|
|
static const struct spi_nor_fixups spansion_nor_fixups = {
|
|
|
|
.late_init = spansion_nor_late_init,
|
2020-03-13 19:42:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
const struct spi_nor_manufacturer spi_nor_spansion = {
|
|
|
|
.name = "spansion",
|
2022-02-23 13:43:38 +00:00
|
|
|
.parts = spansion_nor_parts,
|
|
|
|
.nparts = ARRAY_SIZE(spansion_nor_parts),
|
|
|
|
.fixups = &spansion_nor_fixups,
|
2020-03-13 19:42:46 +00:00
|
|
|
};
|