From 6986aa092e816c757cb8acbcc10b4aa22780cd6f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 24 Nov 2009 12:21:35 +0100 Subject: i.MX Nand: Set correct datawidth/pagesize in CCM module Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/Makefile | 1 + arch/arm/mach-imx/include/mach/imx-nand.h | 1 + arch/arm/mach-imx/nand.c | 105 ++++++++++++++++++++++++++++++ drivers/nand/nand_imx.c | 3 + 4 files changed, 110 insertions(+) create mode 100644 arch/arm/mach-imx/nand.c diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index f6e03b1717..8eda61f309 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_ARCH_IMX27) += speed-imx27.o gpio.o imx27.o obj-$(CONFIG_ARCH_IMX31) += speed-imx31.o iomux-v2.o obj-$(CONFIG_ARCH_IMX35) += speed-imx35.o iomux-v3.o obj-$(CONFIG_IMX_CLKO) += clko.o +obj-$(CONFIG_NAND_IMX) += nand.o obj-y += speed.o diff --git a/arch/arm/mach-imx/include/mach/imx-nand.h b/arch/arm/mach-imx/include/mach/imx-nand.h index 3fdd8bf342..06acddb2f7 100644 --- a/arch/arm/mach-imx/include/mach/imx-nand.h +++ b/arch/arm/mach-imx/include/mach/imx-nand.h @@ -4,6 +4,7 @@ #include void imx_nand_load_image(void *dest, int size); +void imx_nand_set_layout(int writesize, int datawidth); struct imx_nand_platform_data { int width; diff --git a/arch/arm/mach-imx/nand.c b/arch/arm/mach-imx/nand.c new file mode 100644 index 0000000000..5b5f78ba08 --- /dev/null +++ b/arch/arm/mach-imx/nand.c @@ -0,0 +1,105 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include + +#if defined(CONFIG_ARCH_IMX35) || defined (CONFIG_ARCH_IMX25) + +#define RCSR_NFC_FMS (1 << 8) +#define RCSR_NFC_4K (1 << 9) +#define RCSR_NFC_16BIT_SEL (1 << 14) + +void imx_nand_set_layout(int writesize, int datawidth) +{ + unsigned int rcsr; + + rcsr = readl(IMX_CCM_BASE + CCM_RCSR); + + switch (writesize) { + case 512: + rcsr &= ~(RCSR_NFC_FMS | RCSR_NFC_4K); + break; + case 2048: + rcsr |= RCSR_NFC_FMS; + break; + case 4096: + rcsr |= RCSR_NFC_FMS | RCSR_NFC_4K; + break; + default: + break; + } + + switch (datawidth) { + case 8: + rcsr &= ~RCSR_NFC_16BIT_SEL; + break; + case 16: + rcsr |= RCSR_NFC_16BIT_SEL; + break; + default: + break; + } + + writel(rcsr, IMX_CCM_BASE + CCM_RCSR); +} + +#elif defined CONFIG_ARCH_IMX27 + +#define FMCR_NF_FMS (1 << 5) +#define FMCR_NF_16BIT_SEL (1 << 4) + +void imx_nand_set_layout(int writesize, int datawidth) +{ + unsigned int fmcr; + + fmcr = readl(FMCR); + + switch (writesize) { + case 512: + fmcr &= FMCR_NF_FMS; + break; + case 2048: + fmcr |= FMCR_NF_FMS; + break; + default: + break; + } + + switch (datawidth) { + case 8: + fmcr &= ~FMCR_NF_16BIT_SEL; + break; + case 16: + fmcr |= FMCR_NF_16BIT_SEL; + break; + default: + break; + } + + writel(fmcr, FMCR); +} + +#else +#warning using empty imx_nand_set_layout(). NAND flash will not work properly if not booting from it + +void imx_nand_set_layout(int writesize, int datawidth) +{ +} + +#endif diff --git a/drivers/nand/nand_imx.c b/drivers/nand/nand_imx.c index 1a708e9527..edd7cdf39f 100644 --- a/drivers/nand/nand_imx.c +++ b/drivers/nand/nand_imx.c @@ -932,6 +932,7 @@ static int __init imxnd_probe(struct device_d *dev) if (pdata->width == 2) { this->options |= NAND_BUSWIDTH_16; this->ecc.layout = &nandv1_hw_eccoob_smallpage; + imx_nand_set_layout(0, 16); } if (pdata->flash_bbt) { @@ -947,6 +948,8 @@ static int __init imxnd_probe(struct device_d *dev) goto escan; } + imx_nand_set_layout(mtd->writesize, pdata->width == 2 ? 16 : 8); + if (mtd->writesize == 2048) { this->ecc.layout = oob_largepage; host->pagesize_2k = 1; -- cgit v1.2.3