[PATCH v5 11/11] mtd: gpmi: set the BCH's geometry with the ecc info
Vikram Narayanan
vikram186 at gmail.com
Wed May 15 12:31:16 EDT 2013
Hello Huang,
On 5/15/2013 2:24 PM, Huang Shijie wrote:
> If the nand chip provides us the ECC info, we can use it firstly.
> The set_geometry_by_ecc_info() will use the ECC info, and
> calculate the parameters we need.
>
> Rename the old code to lagacy_set_geometry() which will takes effect
Couple of nitpicks.
Thorough out the code and in comments.
s/lagacy/legacy/
> when there is no ECC info from the nand chip or we fails in the ECC info case.
>
> Signed-off-by: Huang Shijie <b32955 at freescale.com>
> ---
> drivers/mtd/nand/gpmi-nand/gpmi-nand.c | 128 +++++++++++++++++++++++++++++++-
> 1 files changed, 127 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> index 25ecfa1..53180da 100644
> --- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> +++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
> @@ -112,7 +112,128 @@ static inline bool gpmi_check_ecc(struct gpmi_nand_data *this)
> return true;
> }
>
> -int common_nfc_set_geometry(struct gpmi_nand_data *this)
> +/*
> + * If we can get the ECC information from the nand chip, we do not
> + * need to calculate them ourselves.
> + *
> + * We may have available oob space in this case.
> + */
> +static bool set_geometry_by_ecc_info(struct gpmi_nand_data *this)
> +{
> + struct bch_geometry *geo = &this->bch_geometry;
> + struct mtd_info *mtd = &this->mtd;
> + struct nand_chip *chip = mtd->priv;
> + struct nand_oobfree *of = gpmi_hw_ecclayout.oobfree;
> + unsigned int block_mark_bit_offset;
> +
> + if (!(chip->ecc_strength > 0 && chip->ecc_step > 0))
> + return false;
> +
> + switch (chip->ecc_step) {
> + case SZ_512:
> + geo->gf_len = 13;
> + break;
> + case SZ_1K:
> + geo->gf_len = 14;
> + break;
> + default:
> + dev_err(this->dev,
> + "unsupported nand chip. ecc bits : %d, ecc size : %d\n",
> + chip->ecc_strength, chip->ecc_step);
> + return false;
> + }
> + geo->ecc_chunk_size = chip->ecc_step;
> + geo->ecc_strength = round_up(chip->ecc_strength, 2);
> + if (!gpmi_check_ecc(this))
> + return false;
> +
> + /* Keep the C >= O */
> + if (geo->ecc_chunk_size < mtd->oobsize) {
> + dev_err(this->dev,
> + "unsupported nand chip. ecc size: %d, oob size : %d\n",
> + chip->ecc_step, mtd->oobsize);
> + return false;
> + }
> +
> + /* The default value, see comment in the lagacy_set_geometry(). */
> + geo->metadata_size = 10;
If this not gonna change, would it be better to keep it as a macro?
> +
> + geo->ecc_chunk_count = mtd->writesize / geo->ecc_chunk_size;
> +
> + /*
> + * Now, the NAND chip with 2K page(data chunk is 512byte) shows below:
> + *
> + * | P |
> + * |<----------------------------------------------------->|
> + * | |
> + * | (Block Mark) |
> + * | P' | | | |
> + * |<-------------------------------------------->| D | | O' |
> + * | |<---->| |<--->|
> + * V V V V V
> + * +---+----------+-+----------+-+----------+-+----------+-+-----+
> + * | M | data |E| data |E| data |E| data |E| |
> + * +---+----------+-+----------+-+----------+-+----------+-+-----+
> + *
> + * P : the page size for BCH module.
> + * E : The ECC strength.
> + * G : the length of Galois Field.
> + * N : The chunk count of per page.
> + * M : the metasize of per page.
> + * C : the ecc chunk size, aka the "data" above.
> + * P': the nand chip's page size.
> + * O : the nand chip's oob size.
I am not sure if my eyes have gone bad. But I couldn't spot the 'O' in
the above NAND page diagram.
I think 's/D/O'.
Regards,
Vikram
More information about the linux-mtd
mailing list