diff options
Diffstat (limited to 'drivers/mtd/nand/s3c64xx.c')
| -rw-r--r-- | drivers/mtd/nand/s3c64xx.c | 295 | 
1 files changed, 0 insertions, 295 deletions
| diff --git a/drivers/mtd/nand/s3c64xx.c b/drivers/mtd/nand/s3c64xx.c deleted file mode 100644 index 87f034106..000000000 --- a/drivers/mtd/nand/s3c64xx.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * (C) Copyright 2006 DENX Software Engineering - * - * Implementation for U-Boot 1.1.6 by Samsung - * - * (C) Copyright 2008 - * Guennadi Liakhovetki, DENX Software Engineering, <lg@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 <linux/mtd/nand.h> - -#include <asm/arch/s3c6400.h> - -#include <asm/io.h> -#include <asm/errno.h> - -#define MAX_CHIPS	2 -static int nand_cs[MAX_CHIPS] = {0, 1}; - -#ifdef CONFIG_NAND_SPL -#define printf(arg...) do {} while (0) -#endif - -/* Nand flash definition values by jsgood */ -#ifdef S3C_NAND_DEBUG -/* - * Function to print out oob buffer for debugging - * Written by jsgood - */ -static void print_oob(const char *header, struct mtd_info *mtd) -{ -	int i; -	struct nand_chip *chip = mtd->priv; - -	printf("%s:\t", header); - -	for (i = 0; i < 64; i++) -		printf("%02x ", chip->oob_poi[i]); - -	printf("\n"); -} -#endif /* S3C_NAND_DEBUG */ - -static void s3c_nand_select_chip(struct mtd_info *mtd, int chip) -{ -	int ctrl = readl(NFCONT); - -	switch (chip) { -	case -1: -		ctrl |= 6; -		break; -	case 0: -		ctrl &= ~2; -		break; -	case 1: -		ctrl &= ~4; -		break; -	default: -		return; -	} - -	writel(ctrl, NFCONT); -} - -/* - * Hardware specific access to control-lines function - * Written by jsgood - */ -static void s3c_nand_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl) -{ -	struct nand_chip *this = mtd->priv; - -	if (ctrl & NAND_CTRL_CHANGE) { -		if (ctrl & NAND_CLE) -			this->IO_ADDR_W = (void __iomem *)NFCMMD; -		else if (ctrl & NAND_ALE) -			this->IO_ADDR_W = (void __iomem *)NFADDR; -		else -			this->IO_ADDR_W = (void __iomem *)NFDATA; -		if (ctrl & NAND_NCE) -			s3c_nand_select_chip(mtd, *(int *)this->priv); -		else -			s3c_nand_select_chip(mtd, -1); -	} - -	if (cmd != NAND_CMD_NONE) -		writeb(cmd, this->IO_ADDR_W); -} - -/* - * Function for checking device ready pin - * Written by jsgood - */ -static int s3c_nand_device_ready(struct mtd_info *mtdinfo) -{ -	return !!(readl(NFSTAT) & NFSTAT_RnB); -} - -#ifdef CONFIG_SYS_S3C_NAND_HWECC -/* - * This function is called before encoding ecc codes to ready ecc engine. - * Written by jsgood - */ -static void s3c_nand_enable_hwecc(struct mtd_info *mtd, int mode) -{ -	u_long nfcont, nfconf; - -	/* -	 * The original driver used 4-bit ECC for "new" MLC chips, i.e., for -	 * those with non-zero ID[3][3:2], which anyway only holds for ST -	 * (Numonyx) chips -	 */ -	nfconf = readl(NFCONF) & ~NFCONF_ECC_4BIT; - -	writel(nfconf, NFCONF); - -	/* Initialize & unlock */ -	nfcont = readl(NFCONT); -	nfcont |= NFCONT_INITECC; -	nfcont &= ~NFCONT_MECCLOCK; - -	if (mode == NAND_ECC_WRITE) -		nfcont |= NFCONT_ECC_ENC; -	else if (mode == NAND_ECC_READ) -		nfcont &= ~NFCONT_ECC_ENC; - -	writel(nfcont, NFCONT); -} - -/* - * This function is called immediately after encoding ecc codes. - * This function returns encoded ecc codes. - * Written by jsgood - */ -static int s3c_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, -				  u_char *ecc_code) -{ -	u_long nfcont, nfmecc0; - -	/* Lock */ -	nfcont = readl(NFCONT); -	nfcont |= NFCONT_MECCLOCK; -	writel(nfcont, NFCONT); - -	nfmecc0 = readl(NFMECC0); - -	ecc_code[0] = nfmecc0 & 0xff; -	ecc_code[1] = (nfmecc0 >> 8) & 0xff; -	ecc_code[2] = (nfmecc0 >> 16) & 0xff; -	ecc_code[3] = (nfmecc0 >> 24) & 0xff; - -	return 0; -} - -/* - * This function determines whether read data is good or not. - * If SLC, must write ecc codes to controller before reading status bit. - * If MLC, status bit is already set, so only reading is needed. - * If status bit is good, return 0. - * If correctable errors occured, do that. - * If uncorrectable errors occured, return -1. - * Written by jsgood - */ -static int s3c_nand_correct_data(struct mtd_info *mtd, u_char *dat, -				 u_char *read_ecc, u_char *calc_ecc) -{ -	int ret = -1; -	u_long nfestat0, nfmeccdata0, nfmeccdata1, err_byte_addr; -	u_char err_type, repaired; - -	/* SLC: Write ecc to compare */ -	nfmeccdata0 = (calc_ecc[1] << 16) | calc_ecc[0]; -	nfmeccdata1 = (calc_ecc[3] << 16) | calc_ecc[2]; -	writel(nfmeccdata0, NFMECCDATA0); -	writel(nfmeccdata1, NFMECCDATA1); - -	/* Read ecc status */ -	nfestat0 = readl(NFESTAT0); -	err_type = nfestat0 & 0x3; - -	switch (err_type) { -	case 0: /* No error */ -		ret = 0; -		break; - -	case 1: -		/* -		 * 1 bit error (Correctable) -		 * (nfestat0 >> 7) & 0x7ff	:error byte number -		 * (nfestat0 >> 4) & 0x7	:error bit number -		 */ -		err_byte_addr = (nfestat0 >> 7) & 0x7ff; -		repaired = dat[err_byte_addr] ^ (1 << ((nfestat0 >> 4) & 0x7)); - -		printf("S3C NAND: 1 bit error detected at byte %ld. " -		       "Correcting from 0x%02x to 0x%02x...OK\n", -		       err_byte_addr, dat[err_byte_addr], repaired); - -		dat[err_byte_addr] = repaired; - -		ret = 1; -		break; - -	case 2: /* Multiple error */ -	case 3: /* ECC area error */ -		printf("S3C NAND: ECC uncorrectable error detected. " -		       "Not correctable.\n"); -		ret = -1; -		break; -	} - -	return ret; -} -#endif /* CONFIG_SYS_S3C_NAND_HWECC */ - -/* - * Board-specific NAND initialization. The following members of the - * argument are board-specific (per include/linux/mtd/nand.h): - * - IO_ADDR_R?: address to read the 8 I/O lines of the flash device - * - IO_ADDR_W?: address to write the 8 I/O lines of the flash device - * - hwcontrol: hardwarespecific function for accesing control-lines - * - dev_ready: hardwarespecific function for  accesing device ready/busy line - * - enable_hwecc?: function to enable (reset)  hardware ecc generator. Must - *   only be provided if a hardware ECC is available - * - eccmode: mode of ecc, see defines - * - chip_delay: chip dependent delay for transfering data from array to - *   read regs (tR) - * - options: various chip options. They can partly be set to inform - *   nand_scan about special functionality. See the defines for further - *   explanation - * Members with a "?" were not set in the merged testing-NAND branch, - * so they are not set here either. - */ -int board_nand_init(struct nand_chip *nand) -{ -	static int chip_n; - -	if (chip_n >= MAX_CHIPS) -		return -ENODEV; - -	NFCONT_REG = (NFCONT_REG & ~NFCONT_WP) | NFCONT_ENABLE | 0x6; - -	nand->IO_ADDR_R		= (void __iomem *)NFDATA; -	nand->IO_ADDR_W		= (void __iomem *)NFDATA; -	nand->cmd_ctrl		= s3c_nand_hwcontrol; -	nand->dev_ready		= s3c_nand_device_ready; -	nand->select_chip	= s3c_nand_select_chip; -	nand->options		= 0; -#ifdef CONFIG_NAND_SPL -	nand->read_byte		= nand_read_byte; -	nand->write_buf		= nand_write_buf; -	nand->read_buf		= nand_read_buf; -#endif - -#ifdef CONFIG_SYS_S3C_NAND_HWECC -	nand->ecc.hwctl		= s3c_nand_enable_hwecc; -	nand->ecc.calculate	= s3c_nand_calculate_ecc; -	nand->ecc.correct	= s3c_nand_correct_data; - -	/* -	 * If you get more than 1 NAND-chip with different page-sizes on the -	 * board one day, it will get more complicated... -	 */ -	nand->ecc.mode		= NAND_ECC_HW; -	nand->ecc.size		= CONFIG_SYS_NAND_ECCSIZE; -	nand->ecc.bytes		= CONFIG_SYS_NAND_ECCBYTES; -#else -	nand->ecc.mode		= NAND_ECC_SOFT; -#endif /* ! CONFIG_SYS_S3C_NAND_HWECC */ - -	nand->priv		= nand_cs + chip_n++; - -	return 0; -} |