
Signed-off-by: Vipin vipin.kumar@st.com --- board/spear/spear300/config.mk | 7 ++ board/spear/spear300/spear300.c | 26 +++++++ board/spear/spear310/config.mk | 7 ++ board/spear/spear310/spear310.c | 26 +++++++ board/spear/spear320/config.mk | 7 ++ board/spear/spear320/spear320.c | 26 +++++++ board/spear/spear600/config.mk | 7 ++ board/spear/spear600/spear600.c | 22 ++++++ drivers/mtd/nand/Makefile | 1 + drivers/mtd/nand/spr_nand.c | 123 +++++++++++++++++++++++++++++++++ include/asm-arm/arch-spear/spr_nand.h | 57 +++++++++++++++ include/configs/spear.h | 59 +++++++++++++--- 12 files changed, 357 insertions(+), 11 deletions(-) create mode 100755 drivers/mtd/nand/spr_nand.c create mode 100644 include/asm-arm/arch-spear/spr_nand.h
diff --git a/board/spear/spear300/config.mk b/board/spear/spear300/config.mk index 0bbb40f..e597326 100755 --- a/board/spear/spear300/config.mk +++ b/board/spear/spear300/config.mk @@ -26,3 +26,10 @@ TEXT_BASE = 0x00700000
ALL += $(obj)u-boot.img + +# Environment variables in NAND +ifeq ($(ENV),NAND) +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND +else +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH +endif diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c index 137f7b3..5fc5cdb 100755 --- a/board/spear/spear300/spear300.c +++ b/board/spear/spear300/spear300.c @@ -22,10 +22,36 @@ */
#include <common.h> +#include <nand.h> +#include <asm/io.h> #include <asm/arch/spr_defs.h> #include <asm/arch/spr_misc.h> +#include <asm/arch/spr_nand.h>
int board_init(void) { return spear_board_init(MACH_TYPE_SPEAR300); } + +/* + * board_nand_init - Board specific NAND initialization + * @nand: mtd private chip structure + * + * Called by nand_init_chip to initialize the board specific functions + */ + +int board_nand_init(struct nand_chip *nand) +{ + struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG30) || + ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG31)) { + + return spear_nand_init(nand); + } + + return -1; +} diff --git a/board/spear/spear310/config.mk b/board/spear/spear310/config.mk index 0bbb40f..e597326 100755 --- a/board/spear/spear310/config.mk +++ b/board/spear/spear310/config.mk @@ -26,3 +26,10 @@ TEXT_BASE = 0x00700000
ALL += $(obj)u-boot.img + +# Environment variables in NAND +ifeq ($(ENV),NAND) +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND +else +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH +endif diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c index 86c3e96..e4a91a8 100755 --- a/board/spear/spear310/spear310.c +++ b/board/spear/spear310/spear310.c @@ -23,10 +23,36 @@ */
#include <common.h> +#include <nand.h> +#include <asm/io.h> #include <asm/arch/spr_defs.h> #include <asm/arch/spr_misc.h> +#include <asm/arch/spr_nand.h>
int board_init(void) { return spear_board_init(MACH_TYPE_SPEAR300); } + +/* + * board_nand_init - Board specific NAND initialization + * @nand: mtd private chip structure + * + * Called by nand_init_chip to initialize the board specific functions + */ + +int board_nand_init(struct nand_chip *nand) +{ + struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG30) || + ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG31)) { + + return spear_nand_init(nand); + } + + return -1; +} diff --git a/board/spear/spear320/config.mk b/board/spear/spear320/config.mk index 0bbb40f..e597326 100755 --- a/board/spear/spear320/config.mk +++ b/board/spear/spear320/config.mk @@ -26,3 +26,10 @@ TEXT_BASE = 0x00700000
ALL += $(obj)u-boot.img + +# Environment variables in NAND +ifeq ($(ENV),NAND) +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND +else +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH +endif diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c index 86c3e96..e4a91a8 100755 --- a/board/spear/spear320/spear320.c +++ b/board/spear/spear320/spear320.c @@ -23,10 +23,36 @@ */
#include <common.h> +#include <nand.h> +#include <asm/io.h> #include <asm/arch/spr_defs.h> #include <asm/arch/spr_misc.h> +#include <asm/arch/spr_nand.h>
int board_init(void) { return spear_board_init(MACH_TYPE_SPEAR300); } + +/* + * board_nand_init - Board specific NAND initialization + * @nand: mtd private chip structure + * + * Called by nand_init_chip to initialize the board specific functions + */ + +int board_nand_init(struct nand_chip *nand) +{ + struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + if (((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG30) || + ((readl(&misc_regs_p->auto_cfg_reg) & MISC_SOCCFGMSK) == + MISC_SOCCFG31)) { + + return spear_nand_init(nand); + } + + return -1; +} diff --git a/board/spear/spear600/config.mk b/board/spear/spear600/config.mk index 0bbb40f..e597326 100755 --- a/board/spear/spear600/config.mk +++ b/board/spear/spear600/config.mk @@ -26,3 +26,10 @@ TEXT_BASE = 0x00700000
ALL += $(obj)u-boot.img + +# Environment variables in NAND +ifeq ($(ENV),NAND) +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_NAND +else +PLATFORM_RELFLAGS += -DCONFIG_ENV_IS_IN_FLASH +endif diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c index 8984358..5f4a78a 100755 --- a/board/spear/spear600/spear600.c +++ b/board/spear/spear600/spear600.c @@ -22,10 +22,32 @@ */
#include <common.h> +#include <nand.h> +#include <asm/io.h> #include <asm/arch/spr_defs.h> #include <asm/arch/spr_misc.h> +#include <asm/arch/spr_nand.h>
int board_init(void) { return spear_board_init(MACH_TYPE_SPEAR600); } + +/* + * board_nand_init - Board specific NAND initialization + * @nand: mtd private chip structure + * + * Called by nand_init_chip to initialize the board specific functions + */ + +int board_nand_init(struct nand_chip *nand) +{ + struct misc_regs *const misc_regs_p = + (struct misc_regs *)CONFIG_SPEAR_MISCBASE; + + if (!(readl(&misc_regs_p->auto_cfg_reg) & MISC_NANDDIS)) { + return spear_nand_init(nand); + } + + return -1; +} diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 02449ee..28f27da 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -47,6 +47,7 @@ COBJS-$(CONFIG_NAND_NDFC) += ndfc.o COBJS-$(CONFIG_NAND_NOMADIK) += nomadik.o COBJS-$(CONFIG_NAND_S3C2410) += s3c2410_nand.o COBJS-$(CONFIG_NAND_S3C64XX) += s3c64xx.o +COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o endif diff --git a/drivers/mtd/nand/spr_nand.c b/drivers/mtd/nand/spr_nand.c new file mode 100755 index 0000000..fbf1b8f --- /dev/null +++ b/drivers/mtd/nand/spr_nand.c @@ -0,0 +1,123 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 <common.h> +#include <nand.h> +#include <linux/mtd/nand_ecc.h> +#include <asm/io.h> +#include <asm/arch/spr_nand.h> + +static struct fsmc_regs *const fsmc_regs_p = + (struct fsmc_regs *)CONFIG_SPEAR_FSMCBASE; + +static struct nand_ecclayout spear_nand_ecclayout = { + .eccbytes = 24, + .eccpos = {2, 3, 4, 18, 19, 20, 34, 35, 36, 50, 51, 52, + 66, 67, 68, 82, 83, 84, 98, 99, 100, 114, 115, 116}, + .oobfree = { + {.offset = 8, .length = 8}, + {.offset = 24, .length = 8}, + {.offset = 40, .length = 8}, + {.offset = 56, .length = 8}, + {.offset = 72, .length = 8}, + {.offset = 88, .length = 8}, + {.offset = 104, .length = 8}, + {.offset = 120, .length = 8} + } +}; + +static void spear_nand_hwcontrol(struct mtd_info *mtd, int cmd, uint ctrl) +{ + struct nand_chip *this = mtd->priv; + ulong IO_ADDR_W; + + if (ctrl & NAND_CTRL_CHANGE) { + IO_ADDR_W = (ulong)this->IO_ADDR_W; + + IO_ADDR_W &= ~(CONFIG_SYS_NAND_CLE | CONFIG_SYS_NAND_ALE); + if (ctrl & NAND_CLE) + IO_ADDR_W |= CONFIG_SYS_NAND_CLE; + if (ctrl & NAND_ALE) + IO_ADDR_W |= CONFIG_SYS_NAND_ALE; + + if (ctrl & NAND_NCE) { + writel(readl(&fsmc_regs_p->genmemctrl_pc) | + FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc); + } else { + writel(readl(&fsmc_regs_p->genmemctrl_pc) & + ~FSMC_ENABLE, &fsmc_regs_p->genmemctrl_pc); + } + this->IO_ADDR_W = (void *)IO_ADDR_W; + } + + if (cmd != NAND_CMD_NONE) + writeb(cmd, this->IO_ADDR_W); +} + +static int spear_read_hwecc(struct mtd_info *mtd, + const u_char *data, u_char ecc[3]) +{ + u_int ecc_tmp; + + /* read the h/w ECC */ + ecc_tmp = readl(&fsmc_regs_p->genmemctrl_ecc); + + ecc[0] = (u_char) (ecc_tmp & 0xFF); + ecc[1] = (u_char) ((ecc_tmp & 0xFF00) >> 8); + ecc[2] = (u_char) ((ecc_tmp & 0xFF0000) >> 16); + + return 0; +} + +void spear_enable_hwecc(struct mtd_info *mtd, int mode) +{ + writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~0x80, + &fsmc_regs_p->genmemctrl_pc); + writel(readl(&fsmc_regs_p->genmemctrl_pc) & ~FSMC_ECCEN, + &fsmc_regs_p->genmemctrl_pc); + writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_ECCEN, + &fsmc_regs_p->genmemctrl_pc); +} + +int spear_nand_init(struct nand_chip *nand) +{ + writel(FSMC_DEVWID_8 | FSMC_DEVTYPE_NAND | FSMC_ENABLE | FSMC_WAITON, + &fsmc_regs_p->genmemctrl_pc); + writel(readl(&fsmc_regs_p->genmemctrl_pc) | FSMC_TCLR_1 | FSMC_TAR_1, + &fsmc_regs_p->genmemctrl_pc); + writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, + &fsmc_regs_p->genmemctrl_comm); + writel(FSMC_THIZ_1 | FSMC_THOLD_4 | FSMC_TWAIT_6 | FSMC_TSET_0, + &fsmc_regs_p->genmemctrl_attrib); + + nand->options = 0; + nand->ecc.mode = NAND_ECC_HW; + nand->ecc.layout = &spear_nand_ecclayout; + nand->ecc.size = 512; + nand->ecc.bytes = 3; + nand->ecc.calculate = spear_read_hwecc; + nand->ecc.hwctl = spear_enable_hwecc; + nand->ecc.correct = nand_correct_data; + nand->cmd_ctrl = spear_nand_hwcontrol; + return 0; +} diff --git a/include/asm-arm/arch-spear/spr_nand.h b/include/asm-arm/arch-spear/spr_nand.h new file mode 100644 index 0000000..2b63dc7 --- /dev/null +++ b/include/asm-arm/arch-spear/spr_nand.h @@ -0,0 +1,57 @@ +/* + * (C) Copyright 2009 + * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 + */ + +#ifndef __SPR_NAND_H__ +#define __SPR_NAND_H__ + +struct fsmc_regs { + u32 reserved_1[0x10]; + u32 genmemctrl_pc; + u32 reserved_2; + u32 genmemctrl_comm; + u32 genmemctrl_attrib; + u32 reserved_3; + u32 genmemctrl_ecc; +}; + +/* genmemctrl_pc register definitions */ +#define FSMC_RESET (1 << 0) +#define FSMC_WAITON (1 << 1) +#define FSMC_ENABLE (1 << 2) +#define FSMC_DEVTYPE_NAND (1 << 3) +#define FSMC_DEVWID_8 (0 << 4) +#define FSMC_DEVWID_16 (1 << 4) +#define FSMC_ECCEN (1 << 6) +#define FSMC_ECCPLEN_512 (0 << 7) +#define FSMC_ECCPLEN_256 (1 << 7) +#define FSMC_TCLR_1 (1 << 9) +#define FSMC_TAR_1 (1 << 13) + +/* genmemctrl_comm register definitions */ +#define FSMC_TSET_0 (0 << 0) +#define FSMC_TWAIT_6 (6 << 8) +#define FSMC_THOLD_4 (4 << 16) +#define FSMC_THIZ_1 (1 << 24) + +extern int spear_nand_init(struct nand_chip *nand); +#endif diff --git a/include/configs/spear.h b/include/configs/spear.h index 5589df8..da10f61 100755 --- a/include/configs/spear.h +++ b/include/configs/spear.h @@ -115,7 +115,35 @@ #define CONFIG_SPEAR_TIMERBASE (0xFC800000) #define CONFIG_SPEAR_MISCBASE (0xFCA80000)
+#define CONFIG_SYS_NAND_CLE (1 << 16) +#define CONFIG_SYS_NAND_ALE (1 << 17) + +#if defined(CONFIG_SPEAR600) #define CONFIG_SYS_I2C_BASE (0xD0200000) +#define CONFIG_SPEAR_FSMCBASE (0xD1800000) +#define CONFIG_SYS_NAND_BASE (0xD2000000) + +#elif defined(CONFIG_SPEAR300) +#define CONFIG_SYS_I2C_BASE (0xD0180000) +#define CONFIG_SPEAR_FSMCBASE (0x94000000) +#define CONFIG_SYS_NAND_BASE (0x80000000) + +#elif defined(CONFIG_SPEAR310) +#define CONFIG_SYS_I2C_BASE (0xD0180000) +#define CONFIG_SPEAR_FSMCBASE (0x44000000) +#define CONFIG_SYS_NAND_BASE (0x40000000) + +#undef CONFIG_SYS_NAND_CLE +#undef CONFIG_SYS_NAND_ALE +#define CONFIG_SYS_NAND_CLE (1 << 17) +#define CONFIG_SYS_NAND_ALE (1 << 16) + +#elif defined(CONFIG_SPEAR320) +#define CONFIG_SYS_I2C_BASE (0xD0180000) +#define CONFIG_SPEAR_FSMCBASE (0x4C000000) +#define CONFIG_SYS_NAND_BASE (0x50000000) + +#endif
#define CONFIG_SYS_HZ (1000) #define CONFIG_SYS_HZ_CLOCK (8300000) @@ -141,13 +169,12 @@ #define CONFIG_NAND_SPEAR 1 #define CONFIG_SYS_MAX_NAND_DEVICE 1 #define CONFIG_MTD_NAND_VERIFY_WRITE 1 -======= ->>>>>>> a15fb6e... SPEAr : Support for serial memory interface driver and serial NOR flash:include/configs/spear.h
/* * Command support defines */ #define CONFIG_CMD_I2C +#define CONFIG_CMD_NAND #define CONFIG_CMD_ENV #define CONFIG_CMD_MEMORY #define CONFIG_CMD_RUN @@ -162,30 +189,40 @@ * Default Environment Varible definitions */ #define CONFIG_BOOTDELAY 1 -#define CONFIG_BOOTARGS_NFS "root=/dev/nfs ip=dhcp " \ - "console=ttyS0 init=/bin/sh" - #define CONFIG_ENV_OVERWRITE
/* * U-Boot Environment placing definitions. */ -#define CONFIG_ENV_IS_IN_FLASH - -#ifdef CONFIG_ENV_IS_IN_FLASH +#if defined(CONFIG_ENV_IS_IN_FLASH) #define CONFIG_SYS_MONITOR_LEN 0x00040000 #define CONFIG_SYS_MONITOR_BASE CONFIG_SYS_FLASH_BASE #define CONFIG_ENV_SECT_SIZE 0x10000 +#define CONFIG_FSMTDBLK "/dev/mtdblock8 " #define CONFIG_ENV_ADDR (CONFIG_SYS_MONITOR_BASE + \ CONFIG_SYS_MONITOR_LEN)
-#define CONFIG_BOOTARGS "console=ttyS0 mem=128M " \ - "root=/dev/mtdblock3 " \ - "rootfstype=jffs2" #define CONFIG_BOOTCOMMAND "bootm 0xf8050000"
+#elif defined(CONFIG_ENV_IS_IN_NAND) + +#define CONFIG_ENV_OFFSET 0x60000 +#define CONFIG_ENV_SIZE 0x04000 +#define CONFIG_ENV_RANGE 0x10000 +#define CONFIG_FSMTDBLK "/dev/mtdblock12 " + +#define CONFIG_BOOTCOMMAND "nand read.jffs2 0x1600000 " \ + "0x80000 0x4C0000; " \ + "bootm 0x1600000" + #endif
+#define CONFIG_BOOTARGS_NFS "root=/dev/nfs ip=dhcp " \ + "console=ttyS0 init=/bin/sh" +#define CONFIG_BOOTARGS "console=ttyS0 mem=128M " \ + "root="CONFIG_FSMTDBLK \ + "rootfstype=jffs2" + #define CONFIG_ENV_SIZE 0x02000
/*