[PATCH] [MTD] MXC NAND support for 2k page size flashes

Alberto Panizzo maramaopercheseimorto at gmail.com
Mon May 25 05:52:20 EDT 2009


On Mon, 25 May 2009 13:06:17 +0400
Vladimir Barinov <vova.barinov at gmail.com> wrote:

> - Add support for 2k page size flashes
> - Fix page address access for large pages
> - Detect oob layout at runtime
> - handle pagesize_2k variable
> - Fix oob16 layout: reserve location 5 of oob area since it's used for bbt
> ---
>  drivers/mtd/nand/mxc_nand.c |   60 ++++++++++++++++++++++++++++++++++++------
>  1 files changed, 51 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c
> index f3548d0..5ab8985 100644
> --- a/drivers/mtd/nand/mxc_nand.c
> +++ b/drivers/mtd/nand/mxc_nand.c
> @@ -138,7 +138,14 @@ static struct nand_ecclayout nand_hw_eccoob_8 = {
>  static struct nand_ecclayout nand_hw_eccoob_16 = {
>  	.eccbytes = 5,
>  	.eccpos = {6, 7, 8, 9, 10},
> -	.oobfree = {{0, 6}, {12, 4}, }
> +	.oobfree = {{0, 5}, {11, 5}, }
> +};
> +
> +static struct nand_ecclayout nand_hw_eccoob_64 = {
> +	.eccbytes = 20,
> +	.eccpos = {6, 7, 8, 9, 10, 22, 23, 24, 25, 26,
> +		   38, 39, 40, 41, 42, 54, 55, 56, 57, 58},
> +	.oobfree = {{2, 4}, {11, 10}, {27, 10}, {43, 10}, {59, 5}, }
>  };
>  
>  #ifdef CONFIG_MTD_PARTITIONS
> @@ -795,9 +802,13 @@ static void mxc_nand_command(struct mtd_info *mtd, unsigned command,
>  		send_addr(host, (page_addr & 0xff), false);
>  
>  		if (host->pagesize_2k) {
> -			send_addr(host, (page_addr >> 8) & 0xFF, false);
> -			if (mtd->size >= 0x40000000)
> +			if (mtd->size >= 0x10000000) {
> +				/* paddr_8 - paddr_15 */
> +				send_addr(host, (page_addr >> 8) & 0xff, false);
>  				send_addr(host, (page_addr >> 16) & 0xff, true);
> +			} else
> +				/* paddr_8 - paddr_15 */
> +				send_addr(host, (page_addr >> 8) & 0xff, true);
>  		} else {
>  			/* One more address cycle for higher density devices */
>  			if (mtd->size >= 0x4000000) {
> @@ -919,7 +930,6 @@ static int __init mxcnd_probe(struct platform_device *pdev)
>  		this->ecc.mode = NAND_ECC_HW;
>  		this->ecc.size = 512;
>  		this->ecc.bytes = 3;
> -		this->ecc.layout = &nand_hw_eccoob_8;
>  		tmp = readw(host->regs + NFC_CONFIG1);
>  		tmp |= NFC_ECC_EN;
>  		writew(tmp, host->regs + NFC_CONFIG1);
> @@ -953,12 +963,44 @@ static int __init mxcnd_probe(struct platform_device *pdev)
>  		this->ecc.layout = &nand_hw_eccoob_16;
>  	}
>  
> -	host->pagesize_2k = 0;
> +	/* first scan to find the device and get the page size */
> +	if (nand_scan_ident(mtd, 1)) {
> +		err = -ENXIO;
> +		goto escan;
> +	}
>  
> -	/* Scan to find existence of the device */
> -	if (nand_scan(mtd, 1)) {
> -		DEBUG(MTD_DEBUG_LEVEL0,
> -		      "MXC_ND: Unable to find any NAND device.\n");
> +	host->pagesize_2k = (mtd->writesize == 2048) ? 1 : 0;
> +
> +	if (this->ecc.mode == NAND_ECC_HW) {
> +		switch (mtd->oobsize) {
> +		case 8:
> +			this->ecc.layout = &nand_hw_eccoob_8;
> +			break;
> +		case 16:
> +			this->ecc.layout = &nand_hw_eccoob_16;
> +			break;
> +		case 64:
> +			this->ecc.layout = &nand_hw_eccoob_64;
> +			break;
> +		default:
> +			/* page size not handled by HW ECC */
> +			/* switching back to soft ECC */
> +			this->ecc.size = 512;
> +			this->ecc.bytes = 3;
> +			this->ecc.layout = &nand_hw_eccoob_8;
> +			this->ecc.mode = NAND_ECC_SOFT;
> +			this->ecc.calculate = NULL;
> +			this->ecc.correct = NULL;
> +			this->ecc.hwctl = NULL;
> +			tmp = readw(host->regs + NFC_CONFIG1);
> +			tmp &= ~NFC_ECC_EN;
> +			writew(tmp, host->regs + NFC_CONFIG1);
> +			break;
> +		}
> +	}
> +
> +	/* second phase scan */
> +	if (nand_scan_tail(mtd)) {
>  		err = -ENXIO;
>  		goto escan;
>  	}

Hi Vladimir! Very thanks for your patch! This and setting correct value of NFMS bit, solve the problem!

Alberto!



More information about the linux-mtd mailing list