[PATCH] Add 'config IMX_NFC_V1_BISWAP' to swap the Bad block Indicator, and use for imx27pdk nand support.
Gaëtan Carlier
gcembed at gmail.com
Wed Aug 8 12:11:55 EDT 2012
Hi,
On 07/06/2011 02:05 PM, Sascha Hauer wrote:
> On Wed, Jul 06, 2011 at 11:30:00AM +0200, Lambrecht Jürgen wrote:
>> On 07/06/2011 10:09 AM, Sascha Hauer wrote:
>>> On Tue, Jul 05, 2011 at 03:33:48PM +0200, Jürgen Lambrecht wrote:
>>>> - Swap the BI-byte on position 0x7D0 with a data byte at 0x835. To
>>> fix a bug
>>>> in Freescale imx NFC v1 SoC's for 2K page NAND flashes: imx27 and
>>> imx31.
>>>> Warning: The same solution needs to be applied to the boot loader
>>> and the
>>>> flash programmer.
>>>> - Enable NAND support for the imx27pdk (3ds), and use BISWAP.
>>>>
>>>> Signed-off-by: Jürgen Lambrecht <J.Lambrecht at televic.com>
>>>> ---
>>>> arch/arm/mach-imx/Kconfig | 30 ++++++++++++++++++++++++++++--
>>>> arch/arm/mach-imx/mach-mx27_3ds.c | 14 ++++++++++++++
>>>> drivers/mtd/nand/mxc_nand.c | 29 +++++++++++++++++++++++++++++
>>>> 3 files changed, 71 insertions(+), 2 deletions(-)
>>>>
>>> [snip]
>>>
>>>> +
>>>> +config IMX_NFC_V1_BISWAP
>>>> + bool "Make the MXC 2kB-page NAND driver swap the Bad Block
>>> Indicator"
>>>> + depends on MACH_MX27_3DS
>>>> + depends on MTD_NAND_MXC
>>>> + help
>>>> + Enable this if you want that the MXC NAND driver swaps the
>>> Bad Block
>>>> + Indicator (BBI) byte. The IMX NFC v1 (present in IMX27 and
>>> IMX31)
>>>> + contains a bug for 2kB-page flashes: the 2kB page is read out in
>>>> + 4x512B chunks, so also the spare area is read out in 4
>>>> + chunks. Therefore the data area and the spare area becomes
>>>> + mixed. This causes a problem for the factory programmed BBI: it
>>>> + appears in the data area instead of the spare area, and is
>>>> + overwritten. This patch swaps that byte to the "real" spare
>>>> + area. WARNING: then also the bootloader and the flash
>>> programmer must
>>>> + be patched!!
>>>
>>> I don't like this approach. IMO some code should be run on a virgin
>>> flash which is aware of this issue and creates a correct bad block
>>> table. You run this once and forget about this afterwards and every
>>> kernel/bootloader can run without patching. Otherwise if you accidently
>>> or intentionally start an older (unpatched) kernel your Nand gets
>>> corrupted.
>>>
>> I see 3 solutions: rely on the quality of the NAND flash driver (1),
>> patch the SW (2) or patch the HW (3).
>>
>> 1. A normal NAND flash driver relies on the ECC to detect a
>> (potentially) bad block. But a factory bad block can have more bad bits
>> that the specified ECC bits.
>> Solution is to check after each write if the data was written
>> reliable: a write/read-back policy. (linux kernel option: Device Drivers
>> -> MTD support -> NAND Device Support -> Verify NAND page writes)
>> This will of course slow-down writing a lot.
>> 2. The Freescale solution: patch the SW:
>> 1. flash programmer
>> 2. boot-loader NAND driver
>> 3. OS NAND driver
>> 3. For the HW patch, a special SW must be written that must be executed
>> before the board is programmed. That special SW must run in RAM and copy
>> the BBI byte to the "swapped" place, so that after swapping, the BBI is
>> at the good place. Then the SW must not be patched.
>> Risk: if this step is skipped, the factory BBI information is lost,
>> and if the SW has no write/read-back policy (solution 1), data will be
>> lost in some point in time.
>>
>> Your solution is (3), but for the linux rootfs partition only, using the
>> BBT. Of course bootloader partitions and the linux kernel binary are not
>> written often, but I read (several times, and also been told) that even
>> when only reading a nand flash it can become bad!
>> I still have to investigate this for how to solve this in the bootloader..
>>
>> Because of the risk, and to have a fast solution, we went for solution (2).
>> But if no one else is interested in this solution, I guess there is no
>> point trying to get it accepted.
>>
>>> Also, my comment above applies here too. You added a 'depends on the
>>> board I care of', but usually my kernels have all available boards
>>> compiled in. So I can select this option and it will change the
>>> behaviour of all boards I might run the kernel on, not only the
>>> ones you depend on above.
>> Ok, i should then find a better way to do it.
>> But, the mxc_nand.c code contains this to protect it: 'if
>> ((mtd->writesize > 512) && nfc_is_v1())'.
>
> This is the correct way to limit the fix to the correct versions of the
> nand controller, but that's not what I tried to say. You might want
> to use solution (2) for your board whereas I want to use solution (3)
> for my boards. With the Kconfig approach it would not be possible for
> us to use the same kernel binary.
A few years ago, I assist to a training done by Adeneo France (partner
of Freescale). They gave us the sources (Bootloader + Kernel 2.6.22)
that include patches to swap bytes. So all of my work is now based with
the swap of bytes done by NFC driver in bootloader and Kernel.
I use OpenOCD to program NAND and the NFC driver that I send us also
include this patch. Now in OpenOCD 6.0rc1, there is an option to enable
or not the biswap at runtime (openocd command line).
So is there a way to add this option as module parameter and enable the
biswap via command-line at kernel boot. Is this solution better than
Kconfig ?
I really need this biswap patch otherwise my previous work will be
broken. If you told me that module parameter is an acceptable way to
implement this workaround, I will write the patch.
>
>> Am I correct that all nfc-v1's have that bug, so only imx27 and imx51?
>> The application note we finally got from freescale only mentions "FSL
>> IMX NFC".
>
> s/imx51/imx31/.
>
> Yes, only imx27 and imx31 a affected by this bug.
>
> Sascha
>
Thanks,
Gaëtan Carlier
More information about the linux-arm-kernel
mailing list