[U-Boot] [PATCH 3/3] 83xx, kmeter1: added NAND support

Signed-off-by: Heiko Schocher hs@denx.de --- board/keymile/kmeter1/Makefile | 2 +- board/keymile/kmeter1/nand.c | 153 ++++++++++++++++++++++++++++++++++++++++ include/configs/kmeter1.h | 5 ++ 3 files changed, 159 insertions(+), 1 deletions(-) create mode 100644 board/keymile/kmeter1/nand.c
diff --git a/board/keymile/kmeter1/Makefile b/board/keymile/kmeter1/Makefile index 12a1518..0eaa234 100644 --- a/board/keymile/kmeter1/Makefile +++ b/board/keymile/kmeter1/Makefile @@ -28,7 +28,7 @@ endif
LIB = $(obj)lib$(BOARD).a
-COBJS += $(BOARD).o ../common/common.o +COBJS += $(BOARD).o ../common/common.o nand.o
SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) OBJS := $(addprefix $(obj),$(COBJS)) diff --git a/board/keymile/kmeter1/nand.c b/board/keymile/kmeter1/nand.c new file mode 100644 index 0000000..0675b53 --- /dev/null +++ b/board/keymile/kmeter1/nand.c @@ -0,0 +1,153 @@ +/* + * (C) Copyright 2009 + * Heiko Schocher, DENX Software Engineering, hs@denx.de + * + * 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> + +#if defined(CONFIG_CMD_NAND) + +#include <nand.h> +#include <asm/io.h> + +#define CONFIG_NAND_MODE_REG (CONFIG_SYS_NAND_BASE + 0x20000) +#define CONFIG_NAND_DATA_REG (CONFIG_SYS_NAND_BASE + 0x30000) + +#define read_mode() in_8((volatile unsigned char __iomem *) \ + CONFIG_NAND_MODE_REG) +#define write_mode(val) out_8((volatile unsigned char __iomem *) \ + CONFIG_NAND_MODE_REG, val) +#define read_data() in_8((volatile unsigned char __iomem *) \ + CONFIG_NAND_DATA_REG) +#define write_data(val) out_8((volatile unsigned char __iomem *) \ + CONFIG_NAND_DATA_REG, val) + +#define KPN_RDY2 (1 << 7) +#define KPN_RDY1 (1 << 6) +#define KPN_WPN (1 << 4) +#define KPN_CE2N (1 << 3) +#define KPN_CE1N (1 << 2) +#define KPN_ALE (1 << 1) +#define KPN_CLE (1 << 0) + +#define KPN_DEFAULT_CHIP_DELAY 50 + +static int kpn_chip_ready(void) +{ + if (read_mode() & KPN_RDY1) + return 1; + + return 0; +} + +static void kpn_wait_rdy(void) +{ + int cnt = 1000000; + + while (--cnt && !kpn_chip_ready()) + udelay(1); + + if (!cnt) + printf ("timeout while waiting for RDY\n"); +} + +static void kpn_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + u8 reg_val = read_mode(); + + if (ctrl & NAND_CTRL_CHANGE) { + if ( ctrl & NAND_NCE) + reg_val = reg_val & ~KPN_CE1N; + else + reg_val = reg_val | KPN_CE1N; + write_mode(reg_val); + } + if (cmd == NAND_CMD_NONE) + return; + + reg_val = reg_val & ~(KPN_ALE + KPN_CLE); + if (ctrl & NAND_CLE) + reg_val = reg_val | KPN_CLE; + if (ctrl & NAND_ALE) + reg_val = reg_val | KPN_ALE; + + /* select register */ + write_mode(reg_val); + + /* write cmd */ + write_data(cmd); + + /* deselect register */ + reg_val = reg_val & ~(KPN_ALE + KPN_CLE); + write_mode(reg_val); + + /* wait until flash is ready */ + kpn_wait_rdy(); +} + +static u_char kpn_nand_read_byte(struct mtd_info *mtd) +{ + return read_data(); +} + +static void kpn_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + write_data(buf[i]); + kpn_wait_rdy(); + } +} + +static void kpn_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + buf[i] = read_data(); + } +} + +static int kpn_nand_dev_ready(struct mtd_info *mtd) +{ + kpn_wait_rdy(); + + return 1; +} + +int board_nand_init(struct nand_chip *nand) +{ + nand->ecc.mode = NAND_ECC_SOFT; + + /* Reference hardware control function */ + nand->cmd_ctrl = kpn_nand_hwcontrol; + nand->read_byte = kpn_nand_read_byte; + nand->write_buf = kpn_nand_write_buf; + nand->read_buf = kpn_nand_read_buf; + nand->dev_ready = kpn_nand_dev_ready; + nand->chip_delay = KPN_DEFAULT_CHIP_DELAY; + + /* reset mode register */ + write_mode(KPN_CE1N + KPN_CE2N + KPN_WPN); + return 0; +} +#endif diff --git a/include/configs/kmeter1.h b/include/configs/kmeter1.h index 811ba88..6471103 100644 --- a/include/configs/kmeter1.h +++ b/include/configs/kmeter1.h @@ -324,6 +324,11 @@ #define CONFIG_SYS_DTT_HYSTERESIS 3 #define CONFIG_SYS_DTT_BUS_NUM (CONFIG_SYS_MAX_I2C_BUS)
+#if defined(CONFIG_CMD_NAND) +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_BASE CONFIG_SYS_PIGGY_BASE +#endif + #if defined(CONFIG_PCI) #define CONFIG_CMD_PCI #endif

Hi Heiko,
On Thursday 09 July 2009 12:04:41 Heiko Schocher wrote:
Signed-off-by: Heiko Schocher hs@denx.de
board/keymile/kmeter1/Makefile | 2 +- board/keymile/kmeter1/nand.c
I suggest to move this NAND driver into the drivers/mtd/nand directory (e.g. drivers/mtd/nand/kmeter1_nand.c). We try to collect all drivers here. This makes maintenance easier.
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================

Hello Stefan,
Stefan Roese wrote:
On Thursday 09 July 2009 12:04:41 Heiko Schocher wrote:
Signed-off-by: Heiko Schocher hs@denx.de
board/keymile/kmeter1/Makefile | 2 +- board/keymile/kmeter1/nand.c
I suggest to move this NAND driver into the drivers/mtd/nand directory (e.g. drivers/mtd/nand/kmeter1_nand.c). We try to collect all drivers here. This makes maintenance easier.
Hmm... this is not a "nand driver", just some board specific functions. Should this go really in "drivers/mtd/nand"?
bye Heiko

On Thursday 09 July 2009 16:59:02 Heiko Schocher wrote:
board/keymile/kmeter1/Makefile | 2 +- board/keymile/kmeter1/nand.c
I suggest to move this NAND driver into the drivers/mtd/nand directory (e.g. drivers/mtd/nand/kmeter1_nand.c). We try to collect all drivers here. This makes maintenance easier.
Hmm... this is not a "nand driver", just some board specific functions.
Yes, it's still a NAND driver. Please take a look at a few of the other "drivers" in this directory. E.g. drivers/mtd/nand/atmel_nand.c. You will see that those are similar to your board specific driver. Implementing the HW- interface for the NAND infrastructure.
Should this go really in "drivers/mtd/nand"?
Yes, please.
Thanks.
Best regards, Stefan
===================================================================== DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-0 Fax: +49-8142-66989-80 Email: office@denx.de =====================================================================
participants (2)
-
Heiko Schocher
-
Stefan Roese