From patchwork Tue Jul 5 13:33:48 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?UTF-8?q?J=C3=BCrgen=20Lambrecht?= X-Patchwork-Id: 103285 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from merlin.infradead.org (merlin.infradead.org [IPv6:2001:4978:20e::2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CAF67B6EDF for ; Tue, 5 Jul 2011 23:39:30 +1000 (EST) Received: from canuck.infradead.org ([2001:4978:20e::1]) by merlin.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qe5q0-0005kg-JH; Tue, 05 Jul 2011 13:38:53 +0000 Received: from localhost ([127.0.0.1] helo=canuck.infradead.org) by canuck.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1Qe5py-0002KB-8F; Tue, 05 Jul 2011 13:38:50 +0000 Received: from mail-wy0-f177.google.com ([74.125.82.177]) by canuck.infradead.org with esmtps (Exim 4.76 #1 (Red Hat Linux)) id 1Qe5pa-0002H0-Sy; Tue, 05 Jul 2011 13:38:28 +0000 Received: by wyf23 with SMTP id 23so5040889wyf.36 for ; Tue, 05 Jul 2011 06:38:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:mime-version :content-type:content-transfer-encoding; bh=CJTF8tqA9P6AFKmvWnHcuYa0KhxtmMaLXieedK8qNWw=; b=Chzgxd5Y3LR1h0DorwQ2O08wInSEzyPga5uSNJ1FPIxw3nQnQmyiXnXi368Wim5qDE zjyjTTNwSnmCnRalm1eC/rMRz4LEb32QK2gg/DKlWtEs0TxUkeDRSkHgChqbugcCJmdQ UE/9tEnOhA5pi8hPfFhmsdv/A/H3DEFLoRXRw= Received: by 10.216.60.4 with SMTP id t4mr5956723wec.101.1309872857024; Tue, 05 Jul 2011 06:34:17 -0700 (PDT) Received: from localhost.localdomain ([188.189.87.107]) by mx.google.com with ESMTPS id w62sm3662097wec.42.2011.07.05.06.34.10 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 05 Jul 2011 06:34:15 -0700 (PDT) From: "=?UTF-8?q?J=C3=BCrgen=20Lambrecht?=" To: linux-arm-kernel@lists.infradead.org Subject: [PATCH] Add 'config IMX_NFC_V1_BISWAP' to swap the Bad block Indicator, and use for imx27pdk nand support. Date: Tue, 5 Jul 2011 15:33:48 +0200 Message-Id: <1309872828-13942-1-git-send-email-J.Lambrecht@televic.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20110705_093827_211135_2143F7B2 X-CRM114-Status: GOOD ( 25.35 ) X-Spam-Score: -0.8 (/) X-Spam-Report: SpamAssassin version 3.3.1 on canuck.infradead.org summary: Content analysis details: (-0.8 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.7 RCVD_IN_DNSWL_LOW RBL: Sender listed at http://www.dnswl.org/, low trust [74.125.82.177 listed in list.dnswl.org] 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail provider (juergen.lambrecht[at]gmail.com) -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.0 T_TO_NO_BRKTS_FREEMAIL To: misformatted and free email service Cc: linux-mtd@lists.infradead.org X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org - 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 --- 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. + +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 #include #include +#include #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);