From: Archit Taneja <architt@codeaurora.org>
To: Kevin Cernekee <cernekee@gmail.com>,
Brian Norris <computersforpeace@gmail.com>
Cc: Daniel Ehrenberg <dehrenberg@google.com>,
linux-arm-msm@vger.kernel.org, agross@codeaurora.org,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
"linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>,
galak@codeaurora.org
Subject: Re: [PATCH 2/5] mtd: nand: Add qcom nand controller driver
Date: Tue, 27 Jan 2015 09:26:09 +0530 [thread overview]
Message-ID: <54C70C59.4090407@codeaurora.org> (raw)
In-Reply-To: <CAJiQ=7B+2xp_XPA6_nieG30+dQUSxQeLGN=xBX0e3zQqgiPqNA@mail.gmail.com>
On 01/27/2015 02:35 AM, Kevin Cernekee wrote:
> On Wed, Jan 21, 2015 at 10:36 PM, Archit Taneja <architt@codeaurora.org> wrote:
>> On 01/21/2015 06:24 AM, Daniel Ehrenberg wrote:
>>> On Fri, Jan 16, 2015 at 6:48 AM, Archit Taneja <architt@codeaurora.org>
>>> wrote:
>>>>
>>>> +/*
>>>> + * the bad block marker is readable only when we read the page with ECC
>>>> + * disabled. all the read/write commands like NAND_CMD_READOOB,
>>>> NAND_CMD_READ0
>>>> + * and NAND_CMD_PAGEPROG are executed in the driver with ECC enabled.
>>>> therefore,
>>>> + * the default nand helper functions to detect a bad block or mark a bad
>>>> block
>>>> + * can't be used.
>>>> + */
>>>> +static int qcom_nandc_block_bad(struct mtd_info *mtd, loff_t ofs, int
>>>> getchip)
>>>> +{
>>>> + int page, r, mark, bad = 0;
>>>> + struct nand_chip *chip = mtd->priv;
>>>> + struct nand_ecc_ctrl *ecc = &chip->ecc;
>>>> + int cwperpage = ecc->steps;
>>>> + struct qcom_nandc_data *this = chip->priv;
>>>> + u32 flash_status;
>>>> +
>>>> + pre_command(this, NAND_CMD_NONE);
>>>> +
>>>> + page = (int)(ofs >> chip->page_shift) & chip->pagemask;
>>>> +
>>>> + /*
>>>> + * configure registers for a raw page read, the address is set to
>>>> the
>>>> + * beginning of the last codeword
>>>> + */
>>>> + this->use_ecc = false;
>>>> + set_address(this, this->cw_size * (cwperpage - 1), page);
>>>> +
>>>> + /* we just read one codeword that contains the bad block marker
>>>> */
>>>> + update_rw_regs(this, 1, true);
>>>> +
>>>> + read_cw(this, this->cw_size, 0);
>>>> +
>>>> + r = submit_descs(this);
>>>> + if (r) {
>>>> + dev_err(this->dev, "error submitting descs\n");
>>>> + goto err;
>>>> + }
>>>> +
>>>> + flash_status = this->reg_read_buf[0];
>>>> +
>>>> + /*
>>>> + * unable to read the marker successfully, is that sufficient to
>>>> report
>>>> + * the block as bad?
>>>> + */
>>>> + if (flash_status & (FS_OP_ERR | FS_MPU_ERR)) {
>>>> + dev_warn(this->dev, "error while reading bad block
>>>> mark\n");
>>>> + goto err;
>>>> + }
>>>> +
>>>> + mark = mtd->writesize - (this->cw_size * (cwperpage - 1));
>>>> +
>>>> + if (chip->options & NAND_BUSWIDTH_16)
>>>> + bad = this->data_buffer[mark] != 0xff ||
>>>> + this->data_buffer[mark + 1] != 0xff;
>>>> +
>>>> + bad = this->data_buffer[mark] != 0xff;
>>>> +err:
>>>> + free_descs(this);
>>>> +
>>>> + return bad;
>>>> +}
>>>> +
>>>> +static int qcom_nandc_block_markbad(struct mtd_info *mtd, loff_t ofs)
>>>> +{
>>>> + int page, r;
>>>> + struct nand_chip *chip = mtd->priv;
>>>> + struct nand_ecc_ctrl *ecc = &chip->ecc;
>>>> + int cwperpage = ecc->steps;
>>>> + struct qcom_nandc_data *this = chip->priv;
>>>> + u32 flash_status;
>>>> +
>>>> + pre_command(this, NAND_CMD_NONE);
>>>> +
>>>> + /* fill our internal buffer's oob area with 0's */
>>>> + memset(this->data_buffer, 0x00, mtd->writesize + mtd->oobsize);
>>>> +
>>>> + page = (int)(ofs >> chip->page_shift) & chip->pagemask;
>>>> +
>>>> + this->use_ecc = false;
>>>> + set_address(this, this->cw_size * (cwperpage - 1), page);
>>>> +
>>>> + /* we just write to one codeword that contains the bad block
>>>> marker*/
>>>> + update_rw_regs(this, 1, false);
>>>> +
>>>> + /*
>>>> + * overwrite the last codeword with 0s, this will result in
>>>> setting
>>>> + * the bad block marker to 0 too
>>>> + */
>>>> + write_cw(this, this->cw_size, 0);
>>>> +
>>>> + r = submit_descs(this);
>>>> + if (r) {
>>>> + dev_err(this->dev, "error submitting descs\n");
>>>> + r = -EIO;
>>>> + goto err;
>>>> + }
>>>> +
>>>> + flash_status = this->reg_read_buf[0];
>>>> +
>>>> + if (flash_status & (FS_OP_ERR | FS_MPU_ERR))
>>>> + r = -EIO;
>>>> +
>>>> +err:
>>>> + free_descs(this);
>>>> +
>>>> + return r;
>>>> +}
>
> Would it be possible to refactor this code so that it implements
> generic read_oob_raw() and write_oob_raw() callbacks, which can
> read/write arbitrary uncorrected OOB bytes instead of just the BBI?
> Or is the controller limited in which OOB bytes can be directly
> accessed?
When accessing the page with ECC disabled, there doesn't seem to be any
limitation.
We have 528/32 bytes per codeword, and we can access all of it in raw mode.
>
> One advantage of implementing the generic raw read/write callbacks is
> that the MTD subsystem already has logic to handle old NAND chips with
> different BBI positions, bitflips in the BBI, and other corner cases.
>
>>> Looks like this code marks block bad and reads bad block information
>>> based on information in the OOB area. And in qcom_nandc_init,
>>> NAND_SKIP_BBTSCAN is set, meaning that this is the code used in
>>> practice on the chip in the mtd_block_isbad path. Can this driver be
>>> used with an on-flash OOB table by editing the init function's chip
>>> flags, or would it need more significant changes to allow that?
>>
>>
>> The code doesn't exactly read the OOB area. When the ECC HW block is
>> enabled, the bad block isn't in either oob or data area! We can access it
>> only when ECC is disabled. With ECC disabled, the bad block marker lies in
>> the last codeword somewhere in the middle of the user data. For the
>> mtd_read_oob()/write_oob() functions, we have the ECC always enabled, hence,
>> we never access the bad block marker through them at all.
>>
>> Creating an on-flash bad block table won't work right now. The reason is
>> that the nand_bbt library assumes that it can find the bad block marker by
>> reading oob. While creating a bbt in memory, it scans the device for bad
>> blocks using the function scan_block_fast(). This would currently result in
>> not reading the bad block marker, and therefore break things.
>>
>> I'm trying to find out if there is a way by which the controller can access
>> the bad block marker with ECC HW enabled. If that works, we can use the
>> nand_bbt helper as is. For now, I wanted to get the driver upstream without
>> the BBT functionality.
>
> So, back in commit a7e68834fc2739 ("mtd: nand: use ECC, if present,
> when scanning OOB"), the BBT code was changed to use MTD_OPS_PLACE_OOB
> instead of MTD_OPS_RAW, because some controllers offer the ability to
> provide corrected OOB data and we wanted to use it if possible. The
> changelog notes that many existing drivers still disabled ECC when
> reading OOB in MTD_OPS_PLACE_OOB mode.
>
> Now it sounds like the qcom_nandc controller can either provide access
> to some corrected OOB bytes (not including the BBI) when
> MTD_OPS_PLACE_OOB is used, or all (?) uncorrected OOB bytes (including
> the BBI) when MTD_OPS_RAW is used.
That's right.
>
> Two possible options are:
>
> 1) qcom_nandc should just disable ECC when performing OOB reads/writes
> in MTD_OPS_PLACE_OOB mode
What prevented me from doing this was how the
chip->ecc.read_page/write_page funcs are defined. They take
the param called oob_required.
If oob_required is set, we would need to read/write page contents with
ECC disabled too. Or, perform 2 rounds of acceses. One for the page
contents with ECC enabled, and other for oob with ECC disabled.
I don't know how often oob_required is set by the mtd subsystem, if it's
a path that is never exercised, we could try this option.
>
> 2) MTD should be made aware of whether the controller can access the
> BBI in MTD_OPS_PLACE_OOB mode, and fall back to MTD_OPS_RAW mode if
> the hardware cannot do so
That sounds like a good option. A NAND chip option mentioning this
capability could be helpful here.
Thanks,
Archit
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
next prev parent reply other threads:[~2015-01-27 3:56 UTC|newest]
Thread overview: 144+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-16 14:48 [PATCH 0/5] mtd: Qualcomm NAND controller driver Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-16 14:48 ` [PATCH 1/5] clk: qcom: Add EBI2 clocks for IPQ806x Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-16 21:56 ` Stephen Boyd
2015-01-16 21:56 ` Stephen Boyd
2015-01-19 10:32 ` Archit Taneja
2015-01-19 10:32 ` Archit Taneja
2015-01-29 22:21 ` Stephen Boyd
2015-01-29 22:21 ` Stephen Boyd
2015-01-16 14:48 ` [PATCH 2/5] mtd: nand: Add qcom nand controller driver Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-21 0:54 ` Daniel Ehrenberg
2015-01-21 0:54 ` Daniel Ehrenberg
2015-01-22 6:36 ` Archit Taneja
2015-01-22 6:36 ` Archit Taneja
2015-01-26 21:05 ` Kevin Cernekee
2015-01-26 21:05 ` Kevin Cernekee
2015-01-27 3:56 ` Archit Taneja [this message]
[not found] ` <1421419702-17812-1-git-send-email-architt-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2015-01-16 14:48 ` [PATCH 3/5] Documentaion: dt: add DT bindings for Qualcomm NAND controller Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-16 14:48 ` [PATCH 4/5] arm: qcom: dts: Add NAND controller node for ipq806x Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-01-16 14:48 ` [PATCH 5/5] arm: qcom: dts: Enale NAND node on IPQ8064 AP148 pplatform Archit Taneja
2015-01-16 14:48 ` Archit Taneja
2015-02-18 6:03 ` [PATCH 0/5] mtd: Qualcomm NAND controller driver Archit Taneja
2015-02-18 6:03 ` Archit Taneja
2015-07-21 10:34 ` [PATCH v2 " Archit Taneja
2015-07-21 10:34 ` [PATCH v2 1/5] mtd: nand: Create a BBT flag to access bad block markers in raw mode Archit Taneja
2015-07-21 10:34 ` Archit Taneja
2015-07-24 19:01 ` Andy Gross
2015-07-21 10:34 ` [PATCH v2 2/5] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2015-07-24 19:39 ` Andy Gross
2015-07-25 0:51 ` Stephen Boyd
2015-07-28 4:34 ` Archit Taneja
2015-07-29 1:48 ` Stephen Boyd
2015-07-29 5:14 ` Archit Taneja
2015-07-29 18:33 ` Stephen Boyd
2015-07-30 6:53 ` Archit Taneja
2015-07-21 10:34 ` [PATCH v2 3/5] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2015-07-24 18:57 ` Andy Gross
2015-07-24 19:37 ` Stephen Boyd
2015-07-21 10:34 ` [PATCH v2 4/5] arm: qcom: dts: Add NAND controller node for ipq806x Archit Taneja
2015-07-24 19:01 ` Andy Gross
2015-07-21 10:34 ` [PATCH v2 5/5] arm: qcom: dts: Enale NAND node on IPQ8064 AP148 platform Archit Taneja
2015-07-24 18:58 ` Andy Gross
2015-07-24 18:59 ` Andy Gross
2015-08-03 5:08 ` [PATCH v3 0/5] mtd: Qualcomm NAND controller driver Archit Taneja
2015-08-03 5:08 ` [PATCH v3 1/5] mtd: nand: Create a BBT flag to access bad block markers in raw mode Archit Taneja
2015-08-03 5:08 ` [PATCH v3 2/5] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2015-08-03 23:38 ` Stephen Boyd
2015-08-04 15:04 ` Archit Taneja
2015-08-04 17:53 ` Stephen Boyd
2015-08-03 5:08 ` [PATCH v3 3/5] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2015-08-03 5:08 ` [PATCH v3 4/5] arm: qcom: dts: Add NAND controller node for ipq806x Archit Taneja
[not found] ` <1438578498-32254-1-git-send-email-architt-sgV2jX0FEOL9JmXXK+q4OQ@public.gmane.org>
2015-08-03 5:08 ` [PATCH v3 5/5] arm: qcom: dts: Enable NAND node on IPQ8064 AP148 platform Archit Taneja
2015-08-03 5:08 ` Archit Taneja
2015-08-03 19:35 ` Andy Gross
2015-08-04 15:05 ` Archit Taneja
2015-08-03 20:58 ` Stephen Boyd
2015-08-04 15:06 ` Archit Taneja
2015-08-19 4:49 ` [PATCH v4 0/5] mtd: Qualcomm NAND controller driver Archit Taneja
2015-08-19 4:49 ` [PATCH v4 1/5] mtd: nand: Create a BBT flag to access bad block markers in raw mode Archit Taneja
2015-10-02 2:44 ` Brian Norris
2015-10-02 6:27 ` Boris Brezillon
2015-10-11 20:03 ` Brian Norris
2015-11-10 5:13 ` Archit Taneja
2015-08-19 4:49 ` [PATCH v4 2/5] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2015-08-26 23:37 ` Stephen Boyd
2015-09-13 13:42 ` Archit Taneja
2015-10-02 3:05 ` Brian Norris
2015-10-05 6:51 ` Archit Taneja
2015-10-06 9:17 ` Brian Norris
2015-10-07 4:11 ` Archit Taneja
2015-10-02 17:31 ` Brian Norris
2015-12-16 9:15 ` Boris Brezillon
2015-12-16 11:57 ` Archit Taneja
2015-12-16 14:18 ` Boris Brezillon
2015-12-16 14:18 ` Boris Brezillon
2015-12-17 9:48 ` Archit Taneja
2015-12-18 18:48 ` Boris Brezillon
2015-12-16 19:16 ` Brian Norris
2015-08-19 4:49 ` [PATCH v4 3/5] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2015-12-16 6:33 ` Boris Brezillon
2015-12-16 8:11 ` Archit Taneja
2015-08-19 4:49 ` [PATCH v4 4/5] arm: qcom: dts: Add NAND controller node for ipq806x Archit Taneja
2015-08-19 4:49 ` [PATCH v4 5/5] arm: qcom: dts: Enable NAND node on IPQ8064 AP148 platform Archit Taneja
2016-01-05 5:24 ` [PATCH v5 0/3] mtd: Qualcomm NAND controller driver Archit Taneja
2016-01-05 5:24 ` [PATCH v5 1/3] mtd: nand: don't select chip in nand_chip's block_bad op Archit Taneja
2016-01-06 16:05 ` Boris Brezillon
2016-01-07 4:27 ` Archit Taneja
2016-01-05 5:25 ` [PATCH v5 2/3] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2016-01-06 17:05 ` Boris Brezillon
2016-01-08 6:33 ` Archit Taneja
2016-01-08 8:01 ` Boris Brezillon
2016-01-08 10:23 ` Archit Taneja
2016-01-08 10:31 ` Boris Brezillon
2016-01-08 10:42 ` Archit Taneja
2016-01-05 5:25 ` [PATCH v5 3/3] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2016-01-06 15:05 ` Boris Brezillon
2016-01-06 15:14 ` Rob Herring
2016-01-06 15:37 ` Boris Brezillon
2016-01-06 16:13 ` Rob Herring
2016-01-06 16:36 ` Boris Brezillon
2016-01-18 9:50 ` [PATCH v6 0/3] mtd: Qualcomm NAND controller driver Archit Taneja
2016-01-18 9:50 ` [PATCH v6 1/3] mtd: nand: don't select chip in nand_chip's block_bad op Archit Taneja
2016-01-18 10:29 ` Boris Brezillon
2016-01-18 10:47 ` Archit Taneja
2016-01-18 9:50 ` [PATCH v6 2/3] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2016-01-18 11:01 ` Boris Brezillon
2016-01-18 11:14 ` Archit Taneja
2016-01-18 9:50 ` [PATCH v6 3/3] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2016-01-20 14:46 ` Rob Herring
2016-01-21 7:13 ` [PATCH v7 0/3] mtd: Qualcomm NAND controller driver Archit Taneja
2016-01-21 7:13 ` [PATCH v7 1/3] mtd: nand: don't select chip in nand_chip's block_bad op Archit Taneja
2016-01-21 8:33 ` Boris Brezillon
2016-01-21 7:13 ` [PATCH v7 2/3] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2016-01-21 8:51 ` Boris Brezillon
2016-01-21 9:52 ` Archit Taneja
2016-01-21 10:13 ` Boris Brezillon
2016-01-21 11:00 ` Archit Taneja
2016-01-21 12:36 ` Boris Brezillon
2016-01-21 13:08 ` Archit Taneja
2016-01-21 13:25 ` Boris Brezillon
2016-01-25 7:43 ` Archit Taneja
2016-01-21 7:13 ` [PATCH v7 3/3] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2016-01-21 7:23 ` Archit Taneja
2016-02-03 8:59 ` [PATCH v8 0/3] mtd: Qualcomm NAND controller driver Archit Taneja
2016-02-03 8:59 ` [PATCH v8 1/3] mtd: nand: don't select chip in nand_chip's block_bad op Archit Taneja
2016-02-03 8:59 ` [PATCH v8 2/3] mtd: nand: Qualcomm NAND controller driver Archit Taneja
2016-02-04 10:39 ` Boris Brezillon
2016-02-04 16:13 ` Archit Taneja
2016-02-16 6:50 ` Archit Taneja
2016-03-08 10:13 ` Archit Taneja
2016-03-18 15:49 ` Boris Brezillon
2016-03-18 16:48 ` Boris Brezillon
2016-03-19 10:14 ` Archit Taneja
2016-03-19 10:34 ` Boris Brezillon
2016-03-22 13:10 ` Archit Taneja
2016-03-22 14:05 ` Boris Brezillon
2016-02-03 8:59 ` [PATCH v8 3/3] dt/bindings: qcom_nandc: Add DT bindings Archit Taneja
2016-03-10 19:47 ` [PATCH v8 0/3] mtd: Qualcomm NAND controller driver Brian Norris
2016-03-16 5:43 ` Archit Taneja
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=54C70C59.4090407@codeaurora.org \
--to=architt@codeaurora.org \
--cc=agross@codeaurora.org \
--cc=cernekee@gmail.com \
--cc=computersforpeace@gmail.com \
--cc=dehrenberg@google.com \
--cc=galak@codeaurora.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mtd@lists.infradead.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.