[PATCH v4 03/16] mtd: rawnand: sunxi: Replace hard coded value by a define

Richard Genoud
2025-10-28T07:36:33Z

The user data length (4) used all over the code hard coded.
And sometimes, it's not that trivial to know that it's the user data
length and not something else.
Moreover, for the H6/H616 this value is no more fixed by hardware, but
could be modified.

Using a define here makes the code more readable.

Suggested-by: Miquel Raynal <miquel.raynal@bootlin.com>
Signed-off-by: Richard Genoud <richard.genoud@bootlin.com>
---
drivers/mtd/nand/raw/sunxi_nand.c | 63 ++++++++++++++++++-------------
1 file changed, 37 insertions(+), 26 deletions(-)

diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
index cb12179b63a5..f24e8d2083f8 100644
--- a/drivers/mtd/nand/raw/sunxi_nand.c
+++ b/drivers/mtd/nand/raw/sunxi_nand.c
@@ -157,6 +157,17 @@

#define NFC_MAX_CS 7

+/*
+ * On A10/A23, this is the size of the NDFC User Data Register, containing the
+ * mandatory user data bytes following the ECC for each ECC step.
+ * Thus, for each ECC step, we need the ECC bytes + USER_DATA_SZ.
+ * Those bits are currently unsused, and kept as default value 0xffffffff.
+ *
+ * On H6/H616, this size became configurable, from 0 bytes to 32, via the
+ * USER_DATA_LEN registers.
+ */
+#define USER_DATA_SZ 4
+
/**
* struct sunxi_nand_chip_sel - stores information related to NAND Chip Select
*
@@ -729,7 +740,7 @@ static void sunxi_nfc_hw_ecc_set_prot_oob_bytes(struct nand_chip *nand,
bool bbm, int page)
{
struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller);
- u8 user_data[4];
+ u8 user_data[USER_DATA_SZ];

/* Randomize the Bad Block Marker. */
if (bbm && (nand->options & NAND_NEED_SCRAMBLING)) {
@@ -781,7 +792,7 @@ static int sunxi_nfc_hw_ecc_correct(struct nand_chip *nand, u8 *data, u8 *oob,
memset(data, pattern, ecc->size);

if (oob)
- memset(oob, pattern, ecc->bytes + 4);
+ memset(oob, pattern, ecc->bytes + USER_DATA_SZ);

return 0;
}
@@ -826,7 +837,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
if (ret)
return ret;

- *cur_off = oob_off + ecc->bytes + 4;
+ *cur_off = oob_off + ecc->bytes + USER_DATA_SZ;

ret = sunxi_nfc_hw_ecc_correct(nand, data, oob_required ? oob : NULL, 0,
readl(nfc->regs + NFC_REG_ECC_ST),
@@ -846,11 +857,11 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE,
ecc->size);

- nand_change_read_column_op(nand, oob_off, oob, ecc->bytes + 4,
- false);
+ nand_change_read_column_op(nand, oob_off, oob,
+ ecc->bytes + USER_DATA_SZ, false);

- ret = nand_check_erased_ecc_chunk(data, ecc->size,
- oob, ecc->bytes + 4,
+ ret = nand_check_erased_ecc_chunk(data, ecc->size, oob,
+ ecc->bytes + USER_DATA_SZ,
NULL, 0, ecc->strength);
if (ret >= 0)
raw_mode = 1;
@@ -860,7 +871,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct nand_chip *nand,
if (oob_required) {
nand_change_read_column_op(nand, oob_off, NULL, 0,
false);
- sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + 4,
+ sunxi_nfc_randomizer_read_buf(nand, oob, ecc->bytes + USER_DATA_SZ,
true, page);

sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, 0,
@@ -954,7 +965,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf

for (i = 0; i < nchunks; i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
u8 *data = buf + data_off;
u8 *oob = nand->oob_poi + oob_off;
bool erased;
@@ -971,7 +982,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf
/* TODO: use DMA to retrieve OOB */
nand_change_read_column_op(nand,
mtd->writesize + oob_off,
- oob, ecc->bytes + 4, false);
+ oob, ecc->bytes + USER_DATA_SZ, false);

sunxi_nfc_hw_ecc_get_prot_oob_bytes(nand, oob, i,
!i, page);
@@ -986,7 +997,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf
if (status & NFC_ECC_ERR_MSK) {
for (i = 0; i < nchunks; i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
u8 *data = buf + data_off;
u8 *oob = nand->oob_poi + oob_off;

@@ -1006,10 +1017,10 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, uint8_t *buf
/* TODO: use DMA to retrieve OOB */
nand_change_read_column_op(nand,
mtd->writesize + oob_off,
- oob, ecc->bytes + 4, false);
+ oob, ecc->bytes + USER_DATA_SZ, false);

- ret = nand_check_erased_ecc_chunk(data, ecc->size,
- oob, ecc->bytes + 4,
+ ret = nand_check_erased_ecc_chunk(data, ecc->size, oob,
+ ecc->bytes + USER_DATA_SZ,
NULL, 0,
ecc->strength);
if (ret >= 0)
@@ -1062,7 +1073,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand,
if (ret)
return ret;

- *cur_off = oob_off + ecc->bytes + 4;
+ *cur_off = oob_off + ecc->bytes + USER_DATA_SZ;

return 0;
}
@@ -1073,7 +1084,7 @@ static void sunxi_nfc_hw_ecc_write_extra_oob(struct nand_chip *nand,
{
struct mtd_info *mtd = nand_to_mtd(nand);
struct nand_ecc_ctrl *ecc = &nand->ecc;
- int offset = ((ecc->bytes + 4) * ecc->steps);
+ int offset = ((ecc->bytes + USER_DATA_SZ) * ecc->steps);
int len = mtd->oobsize - offset;

if (len <= 0)
@@ -1106,7 +1117,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf,

for (i = 0; i < ecc->steps; i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
u8 *data = buf + data_off;
u8 *oob = nand->oob_poi + oob_off;

@@ -1165,7 +1176,7 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand,
for (i = data_offs / ecc->size;
i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
u8 *data = bufpoi + data_off;
u8 *oob = nand->oob_poi + oob_off;

@@ -1219,7 +1230,7 @@ static int sunxi_nfc_hw_ecc_write_page(struct nand_chip *nand,

for (i = 0; i < ecc->steps; i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
const u8 *data = buf + data_off;
const u8 *oob = nand->oob_poi + oob_off;

@@ -1257,7 +1268,7 @@ static int sunxi_nfc_hw_ecc_write_subpage(struct nand_chip *nand,
for (i = data_offs / ecc->size;
i < DIV_ROUND_UP(data_offs + data_len, ecc->size); i++) {
int data_off = i * ecc->size;
- int oob_off = i * (ecc->bytes + 4);
+ int oob_off = i * (ecc->bytes + USER_DATA_SZ);
const u8 *data = buf + data_off;
const u8 *oob = nand->oob_poi + oob_off;

@@ -1296,7 +1307,7 @@ static int sunxi_nfc_hw_ecc_write_page_dma(struct nand_chip *nand,
goto pio_fallback;

for (i = 0; i < ecc->steps; i++) {
- const u8 *oob = nand->oob_poi + (i * (ecc->bytes + 4));
+ const u8 *oob = nand->oob_poi + (i * (ecc->bytes + USER_DATA_SZ));

sunxi_nfc_hw_ecc_set_prot_oob_bytes(nand, oob, i, !i, page);
}
@@ -1566,7 +1577,7 @@ static int sunxi_nand_ooblayout_ecc(struct mtd_info *mtd, int section,
if (section >= ecc->steps)
return -ERANGE;

- oobregion->offset = section * (ecc->bytes + 4) + 4;
+ oobregion->offset = section * (ecc->bytes + USER_DATA_SZ) + 4;
oobregion->length = ecc->bytes;

return 0;
@@ -1600,10 +1611,10 @@ static int sunxi_nand_ooblayout_free(struct mtd_info *mtd, int section,
if (section == ecc->steps && ecc->engine_type == NAND_ECC_ENGINE_TYPE_ON_HOST)
return -ERANGE;

- oobregion->offset = section * (ecc->bytes + 4);
+ oobregion->offset = section * (ecc->bytes + USER_DATA_SZ);

if (section < ecc->steps)
- oobregion->length = 4;
+ oobregion->length = USER_DATA_SZ;
else
oobregion->length = mtd->oobsize - oobregion->offset;

@@ -1637,7 +1648,7 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,
bytes = (mtd->oobsize - 2) / nsectors;

/* 4 non-ECC bytes are added before each ECC bytes section */
- bytes -= 4;
+ bytes -= USER_DATA_SZ;

/* and bytes has to be even. */
if (bytes % 2)
@@ -1690,7 +1701,7 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct nand_chip *nand,

nsectors = mtd->writesize / ecc->size;

- if (mtd->oobsize < ((ecc->bytes + 4) * nsectors))
+ if (mtd->oobsize < ((ecc->bytes + USER_DATA_SZ) * nsectors))
return -EINVAL;

ecc->read_oob = sunxi_nfc_hw_ecc_read_oob;