From: Boris BREZILLON <b.brezillon.dev@gmail.com>
To: "Gupta, Pekon" <pekon@ti.com>,
David Woodhouse <dwmw2@infradead.org>,
Brian Norris <computersforpeace@gmail.com>
Cc: Maxime Ripard <maxime.ripard@free-electrons.com>,
"linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH] mtd: add per NAND partition ECC config
Date: Mon, 10 Feb 2014 13:28:16 +0100 [thread overview]
Message-ID: <52F8C5E0.8040804@gmail.com> (raw)
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EA6F1F0@DBDE04.ent.ti.com>
On 10/02/2014 12:55, Gupta, Pekon wrote:
> Hi Boris,
>
>> From: Boris BREZILLON
>>
>> This patch aims to add per partition ECC config for NAND devices.
>> It defines a new field in the mtd struct to store the mtd ECC config and
>> thus each mtd partition device can store its config instead of using the
>> default NAND chip config.
>>
>> This feature is needed to support the sunxi boot0 paritition case:
>> Allwinner boot code (BROM) requires a specific HW ECC for its boot code
>> that may not fit the HW NAND requirements for the entire NAND chip.
>>
>> Signed-off-by: Boris BREZILLON <b.brezillon.dev@gmail.com>
>> ---
>> Hello,
>>
>> This patch is just a draft that implement per partition ECC config.
>> It's currently not properly splitted (it should be separated in several
>> patches) and not documented either.
>>
>> There's at least one point that bother me in the current implementation:
>> I introduced DT notions in the nand core code by the mean of the get_ecc_ctrl
>> callback, and so far this was kept out of mtd/nand core code (I guess it was
>> on purpose).
>>
>> Please let me know if you see other drawbacks.
>>
>> If you think per partition ECC should not be implemented, could you help me
>> find a way to handle sunxi specific case decribed above ?
>>
> There was a discussion on having per partition based ECC earlier [1].
> Though I was not in favor of supporting it earlier, but your proposal looks good.
> However, I still feel there are more caveats here, to explore..
>
> [...]
>
>> @@ -364,7 +367,13 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
>> slave->mtd.writesize = master->writesize;
>> slave->mtd.writebufsize = master->writebufsize;
>> slave->mtd.oobsize = master->oobsize;
>> - slave->mtd.oobavail = master->oobavail;
>> + if (part->eccctrl) {
>> + slave->mtd.eccctrl = part->eccctrl;
>> + slave->mtd.oobavail = part->eccctrl->layout->oobavail;
>> + } else {
>> + slave->mtd.eccctrl = master->eccctrl;
>> + slave->mtd.oobavail = master->oobavail;
>> + }
>> slave->mtd.subpage_sft = master->subpage_sft;
>>
>> slave->mtd.name = name;
>> @@ -515,9 +524,15 @@ static struct mtd_part *allocate_partition(struct mtd_info *master,
>> part->name);
>> }
>>
>> - slave->mtd.ecclayout = master->ecclayout;
>> - slave->mtd.ecc_step_size = master->ecc_step_size;
>> - slave->mtd.ecc_strength = master->ecc_strength;
>> + if (part->eccctrl) {
>> + slave->mtd.ecclayout = part->eccctrl->layout;
>> + slave->mtd.ecc_step_size = part->eccctrl->size;
>> + slave->mtd.ecc_strength = part->eccctrl->strength;
> You have to replicate 'struct nand_ecc_ctrl' from 'nand_chip' to 'mtd_info'
> because each ECC algorithm may have its own callback for hwctl(), calculate(), and correct().
> How do you plan to populate those ? In driver probe ?
That's already handled (see parse_ofnandpart function):
For each new partition if a valid ecc-mode is detected the function will
call the get_ecc_ctrl
callback which is then supposed to allocate and initialize a new
nand_ecc_ctrl struct.
On nand probe (more precisely in the nand_scan_tail function), I simply
assign the mtd eccctrl
field to the nand chip ecc field, so that even when there's no partition
the mtd device have a
reference to a valid nand_ecc_ctrl struct.
Is that what you were talking about ?
>
>> + } else {
>> + slave->mtd.ecclayout = master->ecclayout;
>> + slave->mtd.ecc_step_size = master->ecc_step_size;
>> + slave->mtd.ecc_strength = master->ecc_strength;
>> + }
>> slave->mtd.bitflip_threshold = master->bitflip_threshold;
>>
>> if (master->_block_isbad) {
> [...]
>
>> +const struct nand_ecc_ctrl *nand_get_ecc_ctrl(struct mtd_info *mtd,
>> + nand_ecc_modes_t mode,
>> + struct device_node *np)
>> +{
>> + struct nand_chip *chip = mtd->priv;
>> + struct nand_ecc_ctrl *ecc;
>> + u32 ecc_step, ecc_strength;
>> + int ret;
>> +
>> + if (mode != NAND_ECC_NONE && mode != NAND_ECC_SOFT &&
>> + mode != NAND_ECC_SOFT_BCH)
>> + return ERR_PTR(-EINVAL);
>> +
>> + ecc = kzalloc(sizeof(*ecc), GFP_KERNEL);
>> + if (!ecc)
>> + return ERR_PTR(-ENOMEM);
>> +
>> + ecc->size = chip->ecc_step_ds;
>> + ecc->strength = chip->ecc_strength_ds;
>> + if (!of_get_nand_ecc_level(np, &ecc_strength, &ecc_step)) {
>> + ecc->size = ecc_step;
>> + ecc->strength = ecc_strength;
>> + }
>> +
> Here we may need to ecc_strength for each partition.
> Example: for OMAP3 ROM supports only HAM1 (1-bit hamming),
> but kernel may support up-to BCH8 (8-bit BCH) ECC schemes.
> But, anyways that's specific to OMAP platforms..
If you need HW specific handling, you just have to implement a new
get_ecc_ctrl
function and assign it to the get_ecc_ctrl field before calling
nand_scan_tail.
That's what I'm doing in the sunxi driver.
This nand_get_ecc_ctrl function is only used when no specific
get_ecc_ctrl is provided.
>> + switch (mode) {
>> + case NAND_ECC_NONE:
>> + break;
>> + case NAND_ECC_SOFT:
>> + break;
>> + case NAND_ECC_SOFT_BCH:
>> + ecc->bytes = ((ecc->strength * fls(8 * ecc->size)) + 7) / 8;
>> + break;
>> + default:
>> + ret = -EINVAL;
>> + goto err;
>> + }
>> +
>> + ecc->mode = mode;
>> + ret = nand_ecc_ctrl_init(mtd, ecc);
>> + if (ret)
>> + goto err;
>> +
>> + ecc->release = nand_release_ecc_ctrl;
>> +
>> + return ecc;
>> +
>> +err:
>> + kfree(ecc);
>> + return ERR_PTR(ret);
>> +}
>> +EXPORT_SYMBOL(nand_get_ecc_ctrl);
>> +
> I'll be happy to extend and test this, if you plan a complete version.
This version is fully functionnal (I tested it with the sunxi driver),
but it depends on a this
patch: https://lkml.org/lkml/2014/1/29/210.
I'll be happy to get it tested on other platforms.
Best Regards,
Boris
>
> [1] http://comments.gmane.org/gmane.linux.ports.arm.omap/108083
> (you can skip initial discussion about OMAP3, and jump to Thomas Petazzoni | 2 Dec 17:19 2013)
>
>
> with regards, pekon
next prev parent reply other threads:[~2014-02-10 12:28 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-02-08 10:26 [RFC PATCH] mtd: add per NAND partition ECC config Boris BREZILLON
2014-02-08 10:36 ` Boris BREZILLON
2014-02-10 11:55 ` Gupta, Pekon
2014-02-10 12:28 ` Boris BREZILLON [this message]
2014-02-10 18:11 ` Boris BREZILLON
2014-02-11 14:01 ` Ezequiel Garcia
2014-02-11 14:22 ` Boris BREZILLON
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52F8C5E0.8040804@gmail.com \
--to=b.brezillon.dev@gmail.com \
--cc=computersforpeace@gmail.com \
--cc=dwmw2@infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
--cc=maxime.ripard@free-electrons.com \
--cc=pekon@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).