diff options
| author | Heiko Schocher <hs@denx.de> | 2008-08-28 13:50:42 +0200 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2008-09-06 23:32:04 +0200 | 
| commit | a6f2e455b774d0c5d56e44e5661df9adb69b6e07 (patch) | |
| tree | 2a56e30e0959f024e5c7abf8febeaa9768466419 /board/tqc/tqm8272/nand.c | |
| parent | 584f979f7ee914e32d408739cbdd2c4457ec18b8 (diff) | |
| download | olio-uboot-2014.01-a6f2e455b774d0c5d56e44e5661df9adb69b6e07.tar.xz olio-uboot-2014.01-a6f2e455b774d0c5d56e44e5661df9adb69b6e07.zip | |
TQM8272: move NAND part in seperate File
I didn't try to use drivers/mtd/nand/fsl_upm.c for the NAND driver,
because I have no longer access to the hardware.
Signed-off-by: Heiko Schocher <hs@denx.de>
Diffstat (limited to 'board/tqc/tqm8272/nand.c')
| -rw-r--r-- | board/tqc/tqm8272/nand.c | 276 | 
1 files changed, 276 insertions, 0 deletions
| diff --git a/board/tqc/tqm8272/nand.c b/board/tqc/tqm8272/nand.c new file mode 100644 index 000000000..b988ffa0e --- /dev/null +++ b/board/tqc/tqm8272/nand.c @@ -0,0 +1,276 @@ +/* + * (C) Copyright 2008 + * 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 <ioports.h> +#include <mpc8260.h> + +#include "tqm8272.h" + +/* UPM pattern for bus clock = 66.7 MHz */ +static const uint upmTable67[] = +{ +    /* Offset	UPM Read Single RAM array entry -> NAND Read Data */ +    /* 0x00 */	0x0fa3f100, 0x0fa3b000, 0x0fa33100, 0x0fa33000, +    /* 0x04 */	0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x08 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x0C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x10 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x14 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */ +    /* 0x18 */	0x00a3fc00, 0x00a3fc00, 0x00a3fc00, 0x00a3fc00, +    /* 0x1C */	0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00, + +		/* UPM Write Burst RAM array entry -> unused */ +    /* 0x20 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x24 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x28 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x2C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Refresh Timer RAM array entry -> unused */ +    /* 0x30 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x34 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x38 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Exception RAM array entry -> unsused */ +    /* 0x3C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, +}; + +/* UPM pattern for bus clock = 100 MHz */ +static const uint upmTable100[] = +{ +    /* Offset	UPM Read Single RAM array entry -> NAND Read Data */ +    /* 0x00 */	0x0fa3f200, 0x0fa3b000, 0x0fa33300, 0x0fa33000, +    /* 0x04 */	0x0fa33000, 0x0fa33004, 0xfffffc01, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x08 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x0C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x10 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x14 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */ +    /* 0x18 */	0x00a3ff00, 0x00a3fc00, 0x00a3fc00, 0x0fa3fc00, +    /* 0x1C */	0x0fa3fc00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00, + +		/* UPM Write Burst RAM array entry -> unused */ +    /* 0x20 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x24 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x28 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x2C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Refresh Timer RAM array entry -> unused */ +    /* 0x30 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x34 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x38 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Exception RAM array entry -> unsused */ +    /* 0x3C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, +}; + +/* UPM pattern for bus clock = 133.3 MHz */ +static const uint upmTable133[] = +{ +    /* Offset	UPM Read Single RAM array entry -> NAND Read Data */ +    /* 0x00 */	0x0fa3f300, 0x0fa3b000, 0x0fa33300, 0x0fa33000, +    /* 0x04 */	0x0fa33200, 0x0fa33004, 0xfffffc01, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x08 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x0C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Read Burst RAM array entry -> unused */ +    /* 0x10 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x14 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, + +		/* UPM Write Single RAM array entry -> NAND Write Data, ADDR and CMD */ +    /* 0x18 */	0x00a3ff00, 0x00a3fc00, 0x00a3fd00, 0x0fa3fc00, +    /* 0x1C */	0x0fa3fd00, 0x0fa3fc04, 0xfffffc01, 0xfffffc00, + +		/* UPM Write Burst RAM array entry -> unused */ +    /* 0x20 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x24 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x28 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x2C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Refresh Timer RAM array entry -> unused */ +    /* 0x30 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x34 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc00, +    /* 0x38 */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, + +		/* UPM Exception RAM array entry -> unsused */ +    /* 0x3C */	0xfffffc00, 0xfffffc00, 0xfffffc00, 0xfffffc01, +}; + +static int	chipsel = 0; + +#if defined(CONFIG_CMD_NAND) + +#include <nand.h> +#include <linux/mtd/mtd.h> + +static u8 hwctl = 0; + +static void upmnand_write_byte(struct mtd_info *mtdinfo, u_char byte) +{ +	struct nand_chip *this = mtdinfo->priv; +	ulong base = (ulong) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST); + +	if (hwctl & 0x1) { +		WRITE_NAND_UPM(byte, base, CFG_NAND_UPM_WRITE_CMD_OFS); +	} else if (hwctl & 0x2) { +		WRITE_NAND_UPM(byte, base, CFG_NAND_UPM_WRITE_ADDR_OFS); +	} else { +		WRITE_NAND(byte, base); +	} +} + +static void upmnand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ +	if (ctrl & NAND_CTRL_CHANGE) { +		if ( ctrl & NAND_CLE ) +			hwctl |= 0x1; +		else +			hwctl &= ~0x1; +		if ( ctrl & NAND_ALE ) +			hwctl |= 0x2; +		else +			hwctl &= ~0x2; +	} +	if (cmd != NAND_CMD_NONE) +		upmnand_write_byte (mtd, cmd); +} + +static u_char upmnand_read_byte(struct mtd_info *mtdinfo) +{ +	struct nand_chip *this = mtdinfo->priv; +	ulong base = (ulong) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST); + +	return READ_NAND(base); +} + +static int tqm8272_dev_ready(struct mtd_info *mtdinfo) +{ +	/* constant delay (see also tR in the datasheet) */ +	udelay(12); \ +	return 1; +} + +#ifndef CONFIG_NAND_SPL +static void tqm8272_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len) +{ +	struct nand_chip *this = mtdinfo->priv; +	unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST); +	int	i; + +	for (i = 0; i< len; i++) +		buf[i] = *base; +} + +static void tqm8272_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) +{ +	struct nand_chip *this = mtdinfo->priv; +	unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST); +	int	i; + +	for (i = 0; i< len; i++) +		*base = buf[i]; +} + +static int tqm8272_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len) +{ +	struct nand_chip *this = mtdinfo->priv; +	unsigned char *base = (unsigned char *) (this->IO_ADDR_W + chipsel * CFG_NAND_CS_DIST); +	int	i; + +	for (i = 0; i < len; i++) +		if (buf[i] != *base) +			return -1; +	return 0; +} +#endif /* #ifndef CONFIG_NAND_SPL */ + +void board_nand_select_device(struct nand_chip *nand, int chip) +{ +	chipsel = chip; +} + +int board_nand_init(struct nand_chip *nand) +{ +	static	int	UpmInit = 0; +	volatile immap_t * immr = (immap_t *)CFG_IMMR; +	volatile memctl8260_t *memctl = &immr->im_memctl; + +	if (hwinf.nand == 0) return -1; + +	/* Setup the UPM */ +	if (UpmInit == 0) { +		switch (hwinf.busclk_real) { +		case 100000000: +			upmconfig (UPMB, (uint *) upmTable100, +			   sizeof (upmTable100) / sizeof (uint)); +			break; +		case 133333333: +			upmconfig (UPMB, (uint *) upmTable133, +			   sizeof (upmTable133) / sizeof (uint)); +			break; +		default: +			upmconfig (UPMB, (uint *) upmTable67, +			   sizeof (upmTable67) / sizeof (uint)); +			break; +		} +		UpmInit = 1; +	} + +	/* Setup the memctrl */ +	memctl->memc_or3 = CFG_NAND_OR; +	memctl->memc_br3 = CFG_NAND_BR; +	memctl->memc_mbmr = (MxMR_OP_NORM); + +	nand->ecc.mode = NAND_ECC_SOFT; + +	nand->cmd_ctrl	 = upmnand_hwcontrol; +	nand->read_byte	 = upmnand_read_byte; +	nand->dev_ready	 = tqm8272_dev_ready; + +#ifndef CONFIG_NAND_SPL +	nand->write_buf	 = tqm8272_write_buf; +	nand->read_buf	 = tqm8272_read_buf; +	nand->verify_buf = tqm8272_verify_buf; +#endif + +	/* +	 * Select required NAND chip +	 */ +	board_nand_select_device(nand, 0); +	return 0; +} + +#endif |