diff options
| author | Heiko Schocher <hs@denx.de> | 2009-07-21 17:13:40 +0200 | 
|---|---|---|
| committer | Scott Wood <scottwood@freescale.com> | 2009-08-26 15:37:02 -0500 | 
| commit | de4250929f37e6c16860741b74546bedbe0bdaba (patch) | |
| tree | 311f9afdf3ee213a521e5b348043994090a00b97 /drivers/mtd/nand/kmeter1_nand.c | |
| parent | ecad289fc6bd9d89ef4d5093cc7b6fd712fd0d29 (diff) | |
| download | olio-uboot-2014.01-de4250929f37e6c16860741b74546bedbe0bdaba.tar.xz olio-uboot-2014.01-de4250929f37e6c16860741b74546bedbe0bdaba.zip | |
83xx, kmeter1: added NAND support
Signed-off-by: Heiko Schocher <hs@denx.de>
Signed-off-by: Scott Wood <scottwood@freescale.com>
Diffstat (limited to 'drivers/mtd/nand/kmeter1_nand.c')
| -rw-r--r-- | drivers/mtd/nand/kmeter1_nand.c | 135 | 
1 files changed, 135 insertions, 0 deletions
| diff --git a/drivers/mtd/nand/kmeter1_nand.c b/drivers/mtd/nand/kmeter1_nand.c new file mode 100644 index 000000000..e8e5b7b85 --- /dev/null +++ b/drivers/mtd/nand/kmeter1_nand.c @@ -0,0 +1,135 @@ +/* + * (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> +#include <nand.h> +#include <asm/io.h> + +#define CONFIG_NAND_MODE_REG	(void *)(CONFIG_SYS_NAND_BASE + 0x20000) +#define CONFIG_NAND_DATA_REG	(void *)(CONFIG_SYS_NAND_BASE + 0x30000) + +#define read_mode()	in_8(CONFIG_NAND_MODE_REG) +#define write_mode(val)	out_8(CONFIG_NAND_MODE_REG, val) +#define read_data()	in_8(CONFIG_NAND_DATA_REG) +#define write_data(val)	out_8(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) { +		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; +		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) +		write_data(cmd); + +	/* 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; +} |