summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Brown <broonie@kernel.org>2025-07-03 17:02:43 +0100
committerMark Brown <broonie@kernel.org>2025-07-03 17:02:43 +0100
commit51106b830ad9dc0a2cf932e27a921e01de2df876 (patch)
tree6cd9a13c4b3ad5a737373af62aeb8bd49e910d23
parent7105fdd54a14bee49371b39374a61b3c967d74cb (diff)
parent913bf8d50cbd144c87e9660b591781179182ff59 (diff)
spi: spi-qpic-snand: enable 8 bits ECC strength
Merge series from Gabor Juhos <j4g8y7@gmail.com>: This small patch set adds support for 8 bits ECC strength, which widens the range of the usable SPI NAND chips with the driver. The first one is a preparatory patch which adds some defines which allows to avoid using magic values, and the second patch implements the actual support. The series should be integrated via the SPI tree, as that contains prerequisite changes.
-rw-r--r--drivers/mtd/nand/raw/qcom_nandc.c6
-rw-r--r--drivers/spi/spi-qpic-snand.c21
-rw-r--r--include/linux/mtd/nand-qpic-common.h2
3 files changed, 21 insertions, 8 deletions
diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 1003cf118c01..4dd6f1a4e797 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -1379,7 +1379,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
struct qcom_nand_controller *nandc = get_qcom_nand_controller(chip);
int cwperpage, bad_block_byte, ret;
bool wide_bus;
- int ecc_mode = 1;
+ int ecc_mode = ECC_MODE_8BIT;
/* controller only supports 512 bytes data steps */
ecc->size = NANDC_STEP_SIZE;
@@ -1400,7 +1400,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
if (ecc->strength >= 8) {
/* 8 bit ECC defaults to BCH ECC on all platforms */
host->bch_enabled = true;
- ecc_mode = 1;
+ ecc_mode = ECC_MODE_8BIT;
if (wide_bus) {
host->ecc_bytes_hw = 14;
@@ -1420,7 +1420,7 @@ static int qcom_nand_attach_chip(struct nand_chip *chip)
if (nandc->props->ecc_modes & ECC_BCH_4BIT) {
/* BCH */
host->bch_enabled = true;
- ecc_mode = 0;
+ ecc_mode = ECC_MODE_4BIT;
if (wide_bus) {
host->ecc_bytes_hw = 8;
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c
index ca55f9bcd17b..b711c8be42c1 100644
--- a/drivers/spi/spi-qpic-snand.c
+++ b/drivers/spi/spi-qpic-snand.c
@@ -277,9 +277,22 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
goto err_free_ecc_cfg;
}
- if (ecc_cfg->strength != 4) {
+ switch (ecc_cfg->strength) {
+ case 4:
+ ecc_cfg->ecc_mode = ECC_MODE_4BIT;
+ ecc_cfg->ecc_bytes_hw = 7;
+ ecc_cfg->spare_bytes = 4;
+ break;
+
+ case 8:
+ ecc_cfg->ecc_mode = ECC_MODE_8BIT;
+ ecc_cfg->ecc_bytes_hw = 13;
+ ecc_cfg->spare_bytes = 2;
+ break;
+
+ default:
dev_err(snandc->dev,
- "only 4 bits ECC strength is supported\n");
+ "only 4 or 8 bits ECC strength is supported\n");
ret = -EOPNOTSUPP;
goto err_free_ecc_cfg;
}
@@ -296,8 +309,6 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
nand->ecc.ctx.priv = ecc_cfg;
snandc->qspi->mtd = mtd;
- ecc_cfg->ecc_bytes_hw = 7;
- ecc_cfg->spare_bytes = 4;
ecc_cfg->bbm_size = 1;
ecc_cfg->bch_enabled = true;
ecc_cfg->bytes = ecc_cfg->ecc_bytes_hw + ecc_cfg->spare_bytes + ecc_cfg->bbm_size;
@@ -343,7 +354,7 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand)
FIELD_PREP(ECC_SW_RESET, 0) |
FIELD_PREP(ECC_NUM_DATA_BYTES_MASK, ecc_cfg->cw_data) |
FIELD_PREP(ECC_FORCE_CLK_OPEN, 1) |
- FIELD_PREP(ECC_MODE_MASK, 0) |
+ FIELD_PREP(ECC_MODE_MASK, ecc_cfg->ecc_mode) |
FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw);
ecc_cfg->ecc_buf_cfg = FIELD_PREP(NUM_STEPS_MASK, 0x203);
diff --git a/include/linux/mtd/nand-qpic-common.h b/include/linux/mtd/nand-qpic-common.h
index e8462deda6db..0d944db363cd 100644
--- a/include/linux/mtd/nand-qpic-common.h
+++ b/include/linux/mtd/nand-qpic-common.h
@@ -101,6 +101,8 @@
#define ECC_SW_RESET BIT(1)
#define ECC_MODE 4
#define ECC_MODE_MASK GENMASK(5, 4)
+#define ECC_MODE_4BIT 0
+#define ECC_MODE_8BIT 1
#define ECC_PARITY_SIZE_BYTES_BCH 8
#define ECC_PARITY_SIZE_BYTES_BCH_MASK GENMASK(12, 8)
#define ECC_NUM_DATA_BYTES 16