Message ID | 1309872828-13942-1-git-send-email-J.Lambrecht@televic.com |
---|---|
State | New |
Headers | show |
Hi Jürgen, Please add Sascha Hauer <kernel@pengutronix.de> to Cc on i.MX related patches. See the MAINTAINERS file. 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@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(-) > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig > index 0519dd7..e8b16a9 100644 > --- a/arch/arm/mach-imx/Kconfig > +++ b/arch/arm/mach-imx/Kconfig > @@ -274,7 +274,7 @@ config MACH_EUKREA_MBIMX27_BASEBOARD > endchoice > > config MACH_MX27_3DS > - bool "MX27PDK platform" > + bool "MX27PDK (3DS) platform" This change is not related to this patch. > select SOC_IMX27 > select IMX_HAVE_PLATFORM_FSL_USB2_UDC > select IMX_HAVE_PLATFORM_IMX2_WDT > @@ -284,13 +284,39 @@ config MACH_MX27_3DS > select IMX_HAVE_PLATFORM_IMX_UART > select IMX_HAVE_PLATFORM_MXC_EHCI > select IMX_HAVE_PLATFORM_MXC_MMC > + select IMX_HAVE_PLATFORM_MXC_NAND > select IMX_HAVE_PLATFORM_SPI_IMX > select MXC_DEBUG_BOARD > select MXC_ULPI if USB_ULPI > help > - Include support for MX27PDK platform. This includes specific > + Include support for MX27PDK (3DS) platform. This includes specific Ditto. > configurations for the board and its peripherals. > > +config MACH_MXC_NAND_USE_BBT The name of this option should indicate somehow that it's an i.MX27 specific hack. > + bool "Make the MXC NAND driver use the in flash Bad Block Table" > + depends on MACH_MX27_3DS > + depends on MTD_NAND_MXC > + help > + Enable this if you want that the MXC NAND driver uses the in flash > + Bad Block Table to know what blocks are bad instead of scanning the > + entire flash looking for bad block markers. > + > +config IMX_NFC_V1_BISWAP > + bool "Make the MXC 2kB-page NAND driver swap the Bad Block Indicator" > + depends on MACH_MX27_3DS Not PDK 3DS specific. Should be 'depends on SOC_IMX27 || SOC_IMX31'. > + 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!! > + > config MACH_IMX27_VISSTRIM_M10 > bool "Vista Silicon i.MX27 Visstrim_m10" > select SOC_IMX27 > diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c > index 526cbe1..84114aa 100644 > --- a/arch/arm/mach-imx/mach-mx27_3ds.c > +++ b/arch/arm/mach-imx/mach-mx27_3ds.c > @@ -40,6 +40,7 @@ > #include <mach/ulpi.h> > #include <mach/irqs.h> > #include <mach/3ds_debugboard.h> > +#include <mach/mxc_nand.h> > > #include "devices-imx27.h" > > @@ -369,6 +370,18 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { > }, > }; > > +/* > + * NAND Flash > + */ > +static const struct mxc_nand_platform_data > +mx27_3ds_nand_board_info __initconst = { > + .width = 1, > + .hw_ecc = 1, > +#ifdef MACH_MXC_NAND_USE_BBT CONFIG_MACH_MXC_NAND_USE_BBT ? > + .flash_bbt = 1, > +#endif > +}; > + > static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = { > .bitrate = 100000, > }; > @@ -380,6 +393,7 @@ static void __init mx27pdk_init(void) > mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), > "mx27pdk"); > mx27_3ds_sdhc1_enable_level_translator(); > + imx27_add_mxc_nand(&mx27_3ds_nand_board_info); This should also be in a separate patch. > imx27_add_imx_uart0(&uart_pdata); > imx27_add_fec(NULL); > imx27_add_imx_keypad(&mx27_3ds_keymap_data); > diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c > index 90df34c..83f54d6 100644 > --- a/drivers/mtd/nand/mxc_nand.c > +++ b/drivers/mtd/nand/mxc_nand.c > @@ -612,6 +612,30 @@ static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, > return 0; > } > > +/* > + * Swap the BI-byte on position 0x7D0 with a data byte at 0x835. > + * To fix a bug in 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. > + */ > +#ifdef CONFIG_IMX_NFC_V1_BISWAP > +static void imx_bi_swap(struct mtd_info *mtd) > +{ > + struct nand_chip *nand_chip = mtd->priv; > + struct mxc_nand_host *host = nand_chip->priv; > + unsigned short temp1, temp2, new_temp1; > + > + temp1 = *((volatile unsigned short*)(host->main_area0 + 0x7D0)); > + temp2 = *((volatile unsigned short*)(host->main_area0 + 0x834)); > + new_temp1 = (temp1 & 0xFF00) | (temp2 >> 8); > + temp2 = (temp2 & 0x00FF) | (temp1 << 8); > + *((volatile unsigned short*)(host->main_area0 + 0x7D0)) = new_temp1; > + *((volatile unsigned short*)(host->main_area0 + 0x834)) = temp2; > +} > +#else > +static inline void imx_bi_swap(struct mtd_info *mtd) {} > +#endif > + > static u_char mxc_nand_read_byte(struct mtd_info *mtd) > { > struct nand_chip *nand_chip = mtd->priv; > @@ -971,6 +995,9 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, > > host->send_page(mtd, NFC_OUTPUT); > > + if ((mtd->writesize > 512) && nfc_is_v1()) > + imx_bi_swap(mtd); > + > memcpy(host->data_buf, host->main_area0, mtd->writesize); > copy_spare(mtd, true); > break; > @@ -989,6 +1016,8 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, > case NAND_CMD_PAGEPROG: > memcpy(host->main_area0, host->data_buf, mtd->writesize); > copy_spare(mtd, false); > + if ((mtd->writesize > 512) && nfc_is_v1()) > + imx_bi_swap(mtd); > host->send_page(mtd, NFC_INPUT); > host->send_cmd(host, command, true); > mxc_do_addr_cycle(mtd, column, page_addr); baruch
Hi, On Tue, 2011-07-05 at 15:33 +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. Sounds like 2 independent changes in one patch - please, split on 2 patches. > +config MACH_MXC_NAND_USE_BBT > + bool "Make the MXC NAND driver use the in flash Bad Block Table" > + depends on MACH_MX27_3DS > + depends on MTD_NAND_MXC > + help > + Enable this if you want that the MXC NAND driver uses the in flash > + Bad Block Table to know what blocks are bad instead of scanning the > + entire flash looking for bad block markers. Sorry, but we have tons of NAND drivers, and if each driver will have a config option for "BBT or scanning", our configuration menu will blow up :-) Really, it does not make sense to make this a config option - the BBT should be detected automatically, and if it is present and correct - scanning should not be done, otherwise, we should fall back to scanning. And this should be a feature of the NAND base support. Please, look at this and change the NAND base support if needed. > +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!! Sorry, but again, things like this should be automatically detected - check the versions and some other magic ids and decide dynamically whether to swap or not. If it is impossible, then this information should be taken from the device tree (which does not exist yet, but people are working on this). In any case, the rule of thumb is to think twice before adding a kenel config option - we have too many of them already.
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@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(-) > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig > index 0519dd7..e8b16a9 100644 > --- a/arch/arm/mach-imx/Kconfig > +++ b/arch/arm/mach-imx/Kconfig > @@ -274,7 +274,7 @@ config MACH_EUKREA_MBIMX27_BASEBOARD > endchoice > > config MACH_MX27_3DS > - bool "MX27PDK platform" > + bool "MX27PDK (3DS) platform" > select SOC_IMX27 > select IMX_HAVE_PLATFORM_FSL_USB2_UDC > select IMX_HAVE_PLATFORM_IMX2_WDT > @@ -284,13 +284,39 @@ config MACH_MX27_3DS > select IMX_HAVE_PLATFORM_IMX_UART > select IMX_HAVE_PLATFORM_MXC_EHCI > select IMX_HAVE_PLATFORM_MXC_MMC > + select IMX_HAVE_PLATFORM_MXC_NAND > select IMX_HAVE_PLATFORM_SPI_IMX > select MXC_DEBUG_BOARD > select MXC_ULPI if USB_ULPI > help > - Include support for MX27PDK platform. This includes specific > + Include support for MX27PDK (3DS) platform. This includes specific > configurations for the board and its peripherals. > > +config MACH_MXC_NAND_USE_BBT > + bool "Make the MXC NAND driver use the in flash Bad Block Table" > + depends on MACH_MX27_3DS > + depends on MTD_NAND_MXC > + help > + Enable this if you want that the MXC NAND driver uses the in flash > + Bad Block Table to know what blocks are bad instead of scanning the > + entire flash looking for bad block markers. Besides the fact that we have too many kconfig options there's another problem. We try to build kernels which run on as many boards as possible. Adding options like this limit a kernel for a particular usecase (bbt vs. scanning) > + > +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. 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. Sascha
> + temp1 = *((volatile unsigned short*)(host->main_area0 + 0x7D0)); > + temp2 = *((volatile unsigned short*)(host->main_area0 + 0x834)); > + new_temp1 = (temp1 & 0xFF00) | (temp2 >> 8); > + temp2 = (temp2 & 0x00FF) | (temp1 << 8); > + *((volatile unsigned short*)(host->main_area0 + 0x7D0)) = new_temp1; > + *((volatile unsigned short*)(host->main_area0 + 0x834)) = temp2; Please use proper io-accessors and no magic values in V2.
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@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(-) > > > > diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig > > index 0519dd7..e8b16a9 100644 > > --- a/arch/arm/mach-imx/Kconfig > > +++ b/arch/arm/mach-imx/Kconfig > > @@ -274,7 +274,7 @@ config MACH_EUKREA_MBIMX27_BASEBOARD > > endchoice > > > > config MACH_MX27_3DS > > - bool "MX27PDK platform" > > + bool "MX27PDK (3DS) platform" > > select SOC_IMX27 > > select IMX_HAVE_PLATFORM_FSL_USB2_UDC > > select IMX_HAVE_PLATFORM_IMX2_WDT > > @@ -284,13 +284,39 @@ config MACH_MX27_3DS > > select IMX_HAVE_PLATFORM_IMX_UART > > select IMX_HAVE_PLATFORM_MXC_EHCI > > select IMX_HAVE_PLATFORM_MXC_MMC > > + select IMX_HAVE_PLATFORM_MXC_NAND > > select IMX_HAVE_PLATFORM_SPI_IMX > > select MXC_DEBUG_BOARD > > select MXC_ULPI if USB_ULPI > > help > > - Include support for MX27PDK platform. This includes specific > > + Include support for MX27PDK (3DS) platform. This includes > specific > > configurations for the board and its peripherals. > > > > +config MACH_MXC_NAND_USE_BBT > > + bool "Make the MXC NAND driver use the in flash Bad Block Table" > > + depends on MACH_MX27_3DS > > + depends on MTD_NAND_MXC > > + help > > + Enable this if you want that the MXC NAND driver uses the in > flash > > + Bad Block Table to know what blocks are bad instead of > scanning the > > + entire flash looking for bad block markers. > > Besides the fact that we have too many kconfig options there's another > problem. We try to build kernels which run on as many boards as > possible. Adding options like this limit a kernel for a particular > usecase (bbt vs. scanning) > Indeed. I just copied it from MACH_MX31_3DS_MXC_NAND_USE_BBT, and thought it was good to do the same. If I want to use it, better just do it without that option, as other _3ds boards do (and davinci and atmel also do in another way). I will remove the option in a separate nand patch for imx27pdk. Regards, Jürgen [snip]
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@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())'. 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". regards, juergen > > Sascha > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > > ______________________________________________________ > Linux MTD discussion mailing list > http://lists.infradead.org/mailman/listinfo/linux-mtd/
Hi, Lambrecht Jürgen writes: > 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@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. > That's nonsense. You cannot copy a byte inside a page that is not programmable (that's what Bad Blocks are). You only need to check the byte in a well known location once and create a BBT in flash that carries the bad block information. After that you need not check for any bad block markers any more, but simply use the BBT. Since you need to program the bootloader with some external tool anyway, that tool is the right instance to do the bad block scan and create the BBT. That's what we at Ka-Ro are doing since the early days of the i.MX27 for all our i.MX boards. > 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.. > You are mixing up two different things. The Bad block markers in certain locations in the OOB area mark 'Factory bad blocks' i.e. blocks that are already bad when you apply power to the flash for the first time. The manufacturer guarantees that initial bad blocks can be detected by checking those locations for a non-FF value. There is no guarantee that you may be able to write any specific value to a certain byte in a block that has turned bad due to wearout or whatever at any later time. Thus bad blocks that appear due to wearout should be kept track of in the BBT, not by writing any 'bad block markers' to the defective blocks themselves. > > 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())'. > 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". > It's not exactly a bug (which would be possible to get fixed), but an inherent feature of the controller which handles NAND flash with a page size larger than 512 byte like it has n pages of 512 byte. Lothar Waßmann
On Wed, 2011-07-06 at 13:48 +0200, Lothar Waßmann wrote: > You are mixing up two different things. The Bad block markers in > certain locations in the OOB area mark 'Factory bad blocks' > i.e. blocks that are already bad when you apply power to the flash for > the first time. The manufacturer guarantees that initial bad blocks > can be detected by checking those locations for a non-FF value. > There is no guarantee that you may be able to write any specific value > to a certain byte in a block that has turned bad due to wearout or > whatever at any later time. Thus bad blocks that appear due to wearout > should be kept track of in the BBT, not by writing any 'bad block > markers' to the defective blocks themselves. That's a good point. In practice, though, many systems do not have a separate BBT and they write a bad block marker to the OOB area of the first page, or the second if the first page cannot be written. This works. But yes, in theory, if an eraseblock became bad, there is a possibility that you cannot write to the OOB areas anymore. However, as I said, in practice, one of the OOBs is still writable. Hmm... Any comments or practical observations?
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@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. > 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
Sascha Hauer writes: > 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@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. > > > 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. > Are you sure? As mentioned in my other mail in this thread that's an inherent side effect of the way how the i.MX flash controllers handle the large page flash, not a bug of a certain silicon that could be fixed somehow. i.MX51, i.MX28 also have the same problem! Lothar Waßmann
On 07/06/2011 01:48 PM, Lothar Waßmann wrote: > > Hi, > > Lambrecht Jürgen writes: > > 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@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. > > > That's nonsense. You cannot copy a byte inside a page that is not > programmable (that's what Bad Blocks are). > No, a Factory Bad Block is a block that when tested under worst-case conditions has more erroneous bits that the ECC correctable ones. So anyhow only those bits cannot be written, and under normal conditions (room temperature..) it is best possible that all bits are again ok (my Micron datasheets even warns that you should not erase a Factory Bad Block, because there is a risk that it succeeds, hence also erasing the bad block mark). But having investigated the matter further that i already had done, you are indeed right that my 3d solution is a bit wrong: it may not be possible to write that "swapped" place. But then the next page of the block can be taken, as there are many pages, and only a few bad bits, that will work. > > You only need to check the byte in a well known location once and > create a BBT in flash that carries the bad block information. After > that you need not check for any bad block markers any more, but simply > use the BBT. > Since you need to program the bootloader with some external tool > anyway, that tool is the right instance to do the bad block scan and > create the BBT. > That's what we at Ka-Ro are doing since the early days of the i.MX27 > for all our i.MX boards. > Seems indeed the best solution. (but we took another solution because of time, and being new to linux) But am I right that the BBT is a file-system dependent meta data? > > > > 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.. > > > You are mixing up two different things. The Bad block markers in > certain locations in the OOB area mark 'Factory bad blocks' > i.e. blocks that are already bad when you apply power to the flash for > the first time. The manufacturer guarantees that initial bad blocks > can be detected by checking those locations for a non-FF value. > There is no guarantee that you may be able to write any specific value > to a certain byte in a block that has turned bad due to wearout or > whatever at any later time. Thus bad blocks that appear due to wearout > should be kept track of in the BBT, not by writing any 'bad block > markers' to the defective blocks themselves. > Same remark: not completely right: only some bits are wrong (number of ECC bits +1, and as you do not touch the block anymore, no more bits will get corrupted). But indeed the byte of the bad-block-marker location in the first page could contain erroneous bits. And to comment on Artem Bityutskiy's mail, then the next page of that (bad) block can be tried (and so on), finally it will work. But then of course the flash file system must be designed to do that. However, I agree that bad blocks should be kept track of in the BBT. > > > > > 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())'. > > 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". > > > It's not exactly a bug (which would be possible to get fixed), but an > inherent feature of the controller which handles NAND flash with a > page size larger than 512 byte like it has n pages of 512 byte. > OK, a "hardware bug" then (can be fixed with a re-write of the VHDL/Verilog code of the NFC, giving v2). It seems to me Freescale tried to enhance their 512B-page controller with to possibility to also handle 2kB pages, but they forgot about the Factory Bad Block byte (n=4 only). So to reply to your next mail: only the imx27 and imx31 (thanks sascha, it was a typo to mention 51) have the NFC v1, I believe all the others have NFC v2, which are fixed. Kind regards, Jürgen > > > > Lothar Waßmann > -- > ___________________________________________________________ > > Ka-Ro electronics GmbH | Pascalstraße 22 | D - 52076 Aachen > Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10 > Geschäftsführer: Matthias Kaussen > Handelsregistereintrag: Amtsgericht Aachen, HRB 4996 > > www.karo-electronics.de | info@karo-electronics.de > ___________________________________________________________ > -- Jürgen Lambrecht R&D Associate Tel: +32 (0)51 303045 Fax: +32 (0)51 310670 http://www.televic-rail.com Televic Rail NV - Leo Bekaertlaan 1 - 8870 Izegem - Belgium Company number 0825.539.581 - RPR Kortrijk
Hi, Lambrecht Jürgen writes: > On 07/06/2011 01:48 PM, Lothar Waßmann wrote: > > > 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". > > > > > It's not exactly a bug (which would be possible to get fixed), but an > > inherent feature of the controller which handles NAND flash with a > > page size larger than 512 byte like it has n pages of 512 byte. > > > OK, a "hardware bug" then (can be fixed with a re-write of the > VHDL/Verilog code of the NFC, giving v2). It seems to me Freescale tried > to enhance their 512B-page controller with to possibility to also handle > 2kB pages, but they forgot about the Factory Bad Block byte (n=4 only). > So to reply to your next mail: only the imx27 and imx31 (thanks sascha, > it was a typo to mention 51) have the NFC v1, I believe all the others > have NFC v2, which are fixed. > How do you come to that conclusion? All the controllers share the same flash buffer layout and map it to the actual flash data in the same way. Thus the problem exists for all of them. And the original Freescale code for i.MX5 et al. handles the bad block markers in the same way as for i.MX2 or i.MX3. Lothar Waßmann
On Wed, Jul 06, 2011 at 03:53:05PM +0200, Lothar Waßmann wrote: > Hi, > > Lambrecht Jürgen writes: > > On 07/06/2011 01:48 PM, Lothar Waßmann wrote: > > > > 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". > > > > > > > It's not exactly a bug (which would be possible to get fixed), but an > > > inherent feature of the controller which handles NAND flash with a > > > page size larger than 512 byte like it has n pages of 512 byte. > > > > > OK, a "hardware bug" then (can be fixed with a re-write of the > > VHDL/Verilog code of the NFC, giving v2). It seems to me Freescale tried > > to enhance their 512B-page controller with to possibility to also handle > > 2kB pages, but they forgot about the Factory Bad Block byte (n=4 only). > > So to reply to your next mail: only the imx27 and imx31 (thanks sascha, > > it was a typo to mention 51) have the NFC v1, I believe all the others > > have NFC v2, which are fixed. > > > How do you come to that conclusion? I remember fsl code which does this only for the v1 controller, but I can't find this anymore, so maybe my mind fooled me. Have you checked this somehow that it is indeed swapped for all controllers or do you believe the fsl code? > All the controllers share the same > flash buffer layout and map it to the actual flash data in the same > way. Thus the problem exists for all of them. > And the original Freescale code for i.MX5 et al. handles the bad block > markers in the same way as for i.MX2 or i.MX3. Indeed :( >From what I've seen neither barebox nor the kernel nor u-boot handle this in Mainline versions. I think we have to do something. Maybe we can handle this in a way that when no bad block table is present we create one with the correct values? This way we could eliminate the problem at least on boards with virgin flashes. This whole topic totally sucks. Whatever we do now we end up with corrupted flashes in one way or the other. BTW the Bootrom code expects non swapped flash layout, so applying a swap patch makes it impossible to update the bootloader in NAND. Maybe that's the reason the FSL code has this disable_bi_swap sysfs attribute in it. Not calling this a bug makes me think you work for the Freescale marketing department ;) Sascha
Hi, Sascha Hauer writes: > On Wed, Jul 06, 2011 at 03:53:05PM +0200, Lothar Waßmann wrote: [...] > Not calling this a bug makes me think you work for the Freescale > marketing department ;) > A bug can normally be fixed somehow. This 'feature' is an inherent design flaw from the 'broken-by-design' category that cannot easily be fixed. That's why I wouldn't call it a bug. Lothar Waßmann
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@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
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig index 0519dd7..e8b16a9 100644 --- a/arch/arm/mach-imx/Kconfig +++ b/arch/arm/mach-imx/Kconfig @@ -274,7 +274,7 @@ config MACH_EUKREA_MBIMX27_BASEBOARD endchoice config MACH_MX27_3DS - bool "MX27PDK platform" + bool "MX27PDK (3DS) platform" select SOC_IMX27 select IMX_HAVE_PLATFORM_FSL_USB2_UDC select IMX_HAVE_PLATFORM_IMX2_WDT @@ -284,13 +284,39 @@ config MACH_MX27_3DS select IMX_HAVE_PLATFORM_IMX_UART select IMX_HAVE_PLATFORM_MXC_EHCI select IMX_HAVE_PLATFORM_MXC_MMC + select IMX_HAVE_PLATFORM_MXC_NAND select IMX_HAVE_PLATFORM_SPI_IMX select MXC_DEBUG_BOARD select MXC_ULPI if USB_ULPI help - Include support for MX27PDK platform. This includes specific + Include support for MX27PDK (3DS) platform. This includes specific configurations for the board and its peripherals. +config MACH_MXC_NAND_USE_BBT + bool "Make the MXC NAND driver use the in flash Bad Block Table" + depends on MACH_MX27_3DS + depends on MTD_NAND_MXC + help + Enable this if you want that the MXC NAND driver uses the in flash + Bad Block Table to know what blocks are bad instead of scanning the + entire flash looking for bad block markers. + +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!! + config MACH_IMX27_VISSTRIM_M10 bool "Vista Silicon i.MX27 Visstrim_m10" select SOC_IMX27 diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c index 526cbe1..84114aa 100644 --- a/arch/arm/mach-imx/mach-mx27_3ds.c +++ b/arch/arm/mach-imx/mach-mx27_3ds.c @@ -40,6 +40,7 @@ #include <mach/ulpi.h> #include <mach/irqs.h> #include <mach/3ds_debugboard.h> +#include <mach/mxc_nand.h> #include "devices-imx27.h" @@ -369,6 +370,18 @@ static struct spi_board_info mx27_3ds_spi_devs[] __initdata = { }, }; +/* + * NAND Flash + */ +static const struct mxc_nand_platform_data +mx27_3ds_nand_board_info __initconst = { + .width = 1, + .hw_ecc = 1, +#ifdef MACH_MXC_NAND_USE_BBT + .flash_bbt = 1, +#endif +}; + static const struct imxi2c_platform_data mx27_3ds_i2c0_data __initconst = { .bitrate = 100000, }; @@ -380,6 +393,7 @@ static void __init mx27pdk_init(void) mxc_gpio_setup_multiple_pins(mx27pdk_pins, ARRAY_SIZE(mx27pdk_pins), "mx27pdk"); mx27_3ds_sdhc1_enable_level_translator(); + imx27_add_mxc_nand(&mx27_3ds_nand_board_info); imx27_add_imx_uart0(&uart_pdata); imx27_add_fec(NULL); imx27_add_imx_keypad(&mx27_3ds_keymap_data); diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 90df34c..83f54d6 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -612,6 +612,30 @@ static int mxc_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, return 0; } +/* + * Swap the BI-byte on position 0x7D0 with a data byte at 0x835. + * To fix a bug in 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. + */ +#ifdef CONFIG_IMX_NFC_V1_BISWAP +static void imx_bi_swap(struct mtd_info *mtd) +{ + struct nand_chip *nand_chip = mtd->priv; + struct mxc_nand_host *host = nand_chip->priv; + unsigned short temp1, temp2, new_temp1; + + temp1 = *((volatile unsigned short*)(host->main_area0 + 0x7D0)); + temp2 = *((volatile unsigned short*)(host->main_area0 + 0x834)); + new_temp1 = (temp1 & 0xFF00) | (temp2 >> 8); + temp2 = (temp2 & 0x00FF) | (temp1 << 8); + *((volatile unsigned short*)(host->main_area0 + 0x7D0)) = new_temp1; + *((volatile unsigned short*)(host->main_area0 + 0x834)) = temp2; +} +#else +static inline void imx_bi_swap(struct mtd_info *mtd) {} +#endif + static u_char mxc_nand_read_byte(struct mtd_info *mtd) { struct nand_chip *nand_chip = mtd->priv; @@ -971,6 +995,9 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, host->send_page(mtd, NFC_OUTPUT); + if ((mtd->writesize > 512) && nfc_is_v1()) + imx_bi_swap(mtd); + memcpy(host->data_buf, host->main_area0, mtd->writesize); copy_spare(mtd, true); break; @@ -989,6 +1016,8 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command, case NAND_CMD_PAGEPROG: memcpy(host->main_area0, host->data_buf, mtd->writesize); copy_spare(mtd, false); + if ((mtd->writesize > 512) && nfc_is_v1()) + imx_bi_swap(mtd); host->send_page(mtd, NFC_INPUT); host->send_cmd(host, command, true); mxc_do_addr_cycle(mtd, column, page_addr);
- 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@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(-)