[PATCH 1/4] mtd: rawnand: sunxi: Replace hard coded value by a define

Michael Nazzareno Trimarchi michael at amarulasolutions.com
Tue Mar 10 22:22:42 CET 2026


Hi

On Mon, Mar 9, 2026 at 4:23 PM Richard Genoud
<richard.genoud at bootlin.com> wrote:
>
> 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 at bootlin.com>
> Signed-off-by: Richard Genoud <richard.genoud at bootlin.com>
> ---
>  drivers/mtd/nand/raw/sunxi_nand.c     | 58 +++++++++++++--------------
>  drivers/mtd/nand/raw/sunxi_nand.h     |  3 ++
>  drivers/mtd/nand/raw/sunxi_nand_spl.c |  7 +++-
>  3 files changed, 38 insertions(+), 30 deletions(-)
>
> diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c
> index ef27a4b7a36a..91f7da2c5ce5 100644
> --- a/drivers/mtd/nand/raw/sunxi_nand.c
> +++ b/drivers/mtd/nand/raw/sunxi_nand.c
> @@ -772,7 +772,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
>                 return ret;
>
>         sunxi_nfc_reset_user_data_len(nfc);
> -       sunxi_nfc_set_user_data_len(nfc, 4, 0);
> +       sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0);
>
>         sunxi_nfc_randomizer_enable(mtd);
>         writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD | NFC_ECC_OP,
> @@ -783,7 +783,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
>         if (ret)
>                 return ret;
>
> -       *cur_off = oob_off + ecc->bytes + 4;
> +       *cur_off = oob_off + ecc->bytes + USER_DATA_SZ;
>
>         pattern_found = readl(nfc->regs + nfc->caps->reg_pat_found);
>         pattern_found = field_get(NFC_ECC_PAT_FOUND_MSK(nfc), pattern_found);
> @@ -794,7 +794,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
>                         pattern = 0x0;
>
>                 memset(data, pattern, ecc->size);
> -               memset(oob, pattern, ecc->bytes + 4);
> +               memset(oob, pattern, ecc->bytes + USER_DATA_SZ);
>
>                 return 1;
>         }
> @@ -804,7 +804,7 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
>         memcpy_fromio(data, nfc->regs + NFC_RAM0_BASE, ecc->size);
>
>         nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
> -       sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + 4, true, page);
> +       sunxi_nfc_randomizer_read_buf(mtd, oob, ecc->bytes + USER_DATA_SZ, true, page);
>
>         status = readl(nfc->regs + NFC_REG_ECC_ST);
>         if (status & NFC_ECC_ERR(0)) {
> @@ -816,17 +816,17 @@ static int sunxi_nfc_hw_ecc_read_chunk(struct mtd_info *mtd,
>                         nand->cmdfunc(mtd, NAND_CMD_RNDOUT, data_off, -1);
>                         nand->read_buf(mtd, data, ecc->size);
>                         nand->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_off, -1);
> -                       nand->read_buf(mtd, oob, ecc->bytes + 4);
> +                       nand->read_buf(mtd, oob, ecc->bytes + USER_DATA_SZ);
>                 }
>
>                 ret = nand_check_erased_ecc_chunk(data, ecc->size,
> -                                                 oob, ecc->bytes + 4,
> +                                                 oob, ecc->bytes + USER_DATA_SZ,
>                                                   NULL, 0, ecc->strength);
>                 if (ret >= 0)
>                         raw_mode = 1;
>         } else {
>                 /*
> -                * The engine protects 4 bytes of OOB data per chunk.
> +                * The engine protects USER_DATA_SZ bytes of OOB data per chunk.
>                  * Retrieve the corrected OOB bytes.
>                  */
>                 sunxi_nfc_user_data_to_buf(readl(nfc->regs +
> @@ -854,7 +854,7 @@ static void sunxi_nfc_hw_ecc_read_extra_oob(struct mtd_info *mtd,
>  {
>         struct nand_chip *nand = mtd_to_nand(mtd);
>         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)
> @@ -896,9 +896,9 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
>
>         /* Fill OOB data in */
>         if ((nand->options & NAND_NEED_SCRAMBLING) && bbm) {
> -               u8 user_data[4];
> +               u8 user_data[USER_DATA_SZ];
>
> -               memcpy(user_data, oob, 4);
> +               memcpy(user_data, oob, USER_DATA_SZ);
>                 sunxi_nfc_randomize_bbm(mtd, page, user_data);
>                 writel(sunxi_nfc_buf_to_user_data(user_data),
>                        nfc->regs + NFC_REG_USER_DATA(nfc, 0));
> @@ -915,7 +915,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
>                 return ret;
>
>         sunxi_nfc_reset_user_data_len(nfc);
> -       sunxi_nfc_set_user_data_len(nfc, 4, 0);
> +       sunxi_nfc_set_user_data_len(nfc, USER_DATA_SZ, 0);
>
>         sunxi_nfc_randomizer_enable(mtd);
>         writel(NFC_DATA_TRANS | NFC_DATA_SWAP_METHOD |
> @@ -927,7 +927,7 @@ static int sunxi_nfc_hw_ecc_write_chunk(struct mtd_info *mtd,
>         if (ret)
>                 return ret;
>
> -       *cur_off = oob_off + ecc->bytes + 4;
> +       *cur_off = oob_off + ecc->bytes + USER_DATA_SZ;
>
>         return 0;
>  }
> @@ -938,7 +938,7 @@ static void sunxi_nfc_hw_ecc_write_extra_oob(struct mtd_info *mtd,
>  {
>         struct nand_chip *nand = mtd_to_nand(mtd);
>         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)
> @@ -966,7 +966,7 @@ static int sunxi_nfc_hw_ecc_read_page(struct mtd_info *mtd,
>
>         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 = chip->oob_poi + oob_off;
>
> @@ -1004,7 +1004,7 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct mtd_info *mtd,
>         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 = chip->oob_poi + oob_off;
>
> @@ -1032,7 +1032,7 @@ static int sunxi_nfc_hw_ecc_write_page(struct mtd_info *mtd,
>
>         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 = chip->oob_poi + oob_off;
>
> @@ -1066,7 +1066,7 @@ static int sunxi_nfc_hw_ecc_write_subpage(struct mtd_info *mtd,
>         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 = chip->oob_poi + oob_off;
>
> @@ -1095,10 +1095,10 @@ static int sunxi_nfc_hw_syndrome_ecc_read_page(struct mtd_info *mtd,
>         sunxi_nfc_hw_ecc_enable(mtd);
>
>         for (i = 0; i < ecc->steps; i++) {
> -               int data_off = i * (ecc->size + ecc->bytes + 4);
> +               int data_off = i * (ecc->size + ecc->bytes + USER_DATA_SZ);
>                 int oob_off = data_off + ecc->size;
>                 u8 *data = buf + (i * ecc->size);
> -               u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
> +               u8 *oob = chip->oob_poi + (i * (ecc->bytes + USER_DATA_SZ));
>
>                 ret = sunxi_nfc_hw_ecc_read_chunk(mtd, data, data_off, oob,
>                                                   oob_off, &cur_off,
> @@ -1129,10 +1129,10 @@ static int sunxi_nfc_hw_syndrome_ecc_write_page(struct mtd_info *mtd,
>         sunxi_nfc_hw_ecc_enable(mtd);
>
>         for (i = 0; i < ecc->steps; i++) {
> -               int data_off = i * (ecc->size + ecc->bytes + 4);
> +               int data_off = i * (ecc->size + ecc->bytes + USER_DATA_SZ);
>                 int oob_off = data_off + ecc->size;
>                 const u8 *data = buf + (i * ecc->size);
> -               const u8 *oob = chip->oob_poi + (i * (ecc->bytes + 4));
> +               const u8 *oob = chip->oob_poi + (i * (ecc->bytes + USER_DATA_SZ));
>
>                 ret = sunxi_nfc_hw_ecc_write_chunk(mtd, data, data_off,
>                                                    oob, oob_off, &cur_off,
> @@ -1390,7 +1390,7 @@ static int sunxi_nand_hw_common_ecc_ctrl_init(struct mtd_info *mtd,
>         layout = &data->layout;
>         nsectors = mtd->writesize / ecc->size;
>
> -       if (mtd->oobsize < ((ecc->bytes + 4) * nsectors)) {
> +       if (mtd->oobsize < ((ecc->bytes + USER_DATA_SZ) * nsectors)) {
>                 ret = -EINVAL;
>                 goto err;
>         }
> @@ -1440,14 +1440,14 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
>                                 layout->oobfree[i - 1].offset +
>                                 layout->oobfree[i - 1].length +
>                                 ecc->bytes;
> -                       layout->oobfree[i].length = 4;
> +                       layout->oobfree[i].length = USER_DATA_SZ;
>                 } else {
>                         /*
>                          * The first 2 bytes are used for BB markers, hence we
> -                        * only have 2 bytes available in the first user data
> -                        * section.
> +                        * only have USER_DATA_SZ - 2 bytes available in the
> +                        * first user data section.
>                          */
> -                       layout->oobfree[i].length = 2;
> +                       layout->oobfree[i].length = USER_DATA_SZ - 2;
>                         layout->oobfree[i].offset = 2;
>                 }
>
> @@ -1457,13 +1457,13 @@ static int sunxi_nand_hw_ecc_ctrl_init(struct mtd_info *mtd,
>                                         layout->oobfree[i].length + j;
>         }
>
> -       if (mtd->oobsize > (ecc->bytes + 4) * nsectors) {
> +       if (mtd->oobsize > (ecc->bytes + USER_DATA_SZ) * nsectors) {
>                 layout->oobfree[nsectors].offset =
>                                 layout->oobfree[nsectors - 1].offset +
>                                 layout->oobfree[nsectors - 1].length +
>                                 ecc->bytes;
>                 layout->oobfree[nsectors].length = mtd->oobsize -
> -                               ((ecc->bytes + 4) * nsectors);
> +                               ((ecc->bytes + USER_DATA_SZ) * nsectors);
>         }
>
>         return 0;
> @@ -1481,7 +1481,7 @@ static int sunxi_nand_hw_syndrome_ecc_ctrl_init(struct mtd_info *mtd,
>         if (ret)
>                 return ret;
>
> -       ecc->prepad = 4;
> +       ecc->prepad = USER_DATA_SZ;
>         ecc->read_page = sunxi_nfc_hw_syndrome_ecc_read_page;
>         ecc->write_page = sunxi_nfc_hw_syndrome_ecc_write_page;
>
> diff --git a/drivers/mtd/nand/raw/sunxi_nand.h b/drivers/mtd/nand/raw/sunxi_nand.h
> index 6ee3ea14ee17..d7a8b3dd40c3 100644
> --- a/drivers/mtd/nand/raw/sunxi_nand.h
> +++ b/drivers/mtd/nand/raw/sunxi_nand.h
> @@ -181,6 +181,9 @@
>
>  #define NFC_MAX_CS             7
>
> +/* On A10, the user data length register is 4 bytes */
> +#define USER_DATA_SZ 4
> +
>  /*
>   * NAND Controller capabilities structure: stores NAND controller capabilities
>   * for distinction between compatible strings.
> diff --git a/drivers/mtd/nand/raw/sunxi_nand_spl.c b/drivers/mtd/nand/raw/sunxi_nand_spl.c
> index 67f7d22ed2c8..3a5271b49c36 100644
> --- a/drivers/mtd/nand/raw/sunxi_nand_spl.c
> +++ b/drivers/mtd/nand/raw/sunxi_nand_spl.c
> @@ -269,6 +269,11 @@ static void sunxi_nfc_set_user_data_len(const struct nfc_config *nfc,
>         writel_nfc(val, NFC_REG_USER_DATA_LEN(nfc, step));
>  }
>
> +/*
> + * Values in this table are obtained by doing:
> + * DIV_ROUND_UP(info->ecc_strength * 14, 8) + USER_DATA_SZ
> + * So it's the number of bytes needed for ECC + user data for one step.
> + */
>  #if defined(CONFIG_MACH_SUN50I_H616) || defined(CONFIG_MACH_SUN50I_H6)
>  static const int ecc_bytes[] = {
>         32, 46, 54, 60, 74, 82, 88, 96, 102, 110, 116, 124, 130, 138, 144
> @@ -338,7 +343,7 @@ static int nand_read_page(const struct nfc_config *conf, u32 offs,
>                 nand_change_column(oob_off);
>
>                 sunxi_nfc_reset_user_data_len(conf);
> -               sunxi_nfc_set_user_data_len(conf, 4, 0);
> +               sunxi_nfc_set_user_data_len(conf, USER_DATA_SZ, 0);
>
>                 nand_exec_cmd(NFC_DATA_TRANS | NFC_ECC_OP);
>                 /* Get the ECC status */

Reviwed-By: Michael Trimarchi <michael at amarulasolutions.com>


More information about the U-Boot mailing list