All of lore.kernel.org
 help / color / mirror / Atom feed
From: Brian Norris <computersforpeace@gmail.com>
To: Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com>
Cc: mark.rutland@arm.com, jussi.kivilinna@iki.fi,
	linux-doc@vger.kernel.org, artem.bityutskiy@linux.intel.com,
	linux-mtd@lists.infradead.org,
	Punnaiah Choudary Kalluri <punnaia@xilinx.com>,
	arnd@arndb.de, svemula@xilinx.com, michal.simek@xilinx.com,
	ezequiel.garcia@free-electrons.com, grant.likely@linaro.org,
	devicetree@vger.kernel.org, jason@lakedaemon.net,
	pawel.moll@arm.com, ijc+devicetree@hellion.org.uk,
	anirudh@xilinx.com, joern@logfs.org, kpc528@gmail.com,
	robh+dt@kernel.org, acourbot@nvidia.com, pekon@ti.com,
	kalluripunnaiahchoudary@gmail.com, gregkh@linuxfoundation.org,
	linux-kernel@vger.kernel.org, rob@landley.net,
	galak@codeaurora.org, ivan.khoronzhuk@ti.com,
	dwmw2@infradead.org
Subject: Re: [PATCH RFC v4 3/4] nand: pl353: Add ONDIE ECC support
Date: Thu, 31 Jul 2014 00:06:43 -0700	[thread overview]
Message-ID: <20140731070643.GG11952@brian-ubuntu> (raw)
In-Reply-To: <27fce982-6598-44a0-ad80-c13d02a952ee@BN1AFFO11FD042.protection.gbl>

Hi Punnaiah,

I haven't looked too closely at everything here, but a few comments:

On Mon, Jul 28, 2014 at 09:01:39PM +0530, Punnaiah Choudary Kalluri wrote:
> Added ONDIE ECC support. Currently this ecc mode is supported for
> specific micron parts with oob size 64 bytes.
> 
> Signed-off-by: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
> ---
> Changes in v4:
> - Updated the driver to sync with pl353_smc driver APIs
> ---
>  drivers/mtd/nand/pl353_nand.c |  162 ++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 144 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/mtd/nand/pl353_nand.c b/drivers/mtd/nand/pl353_nand.c
> index 93dc4ca..5c9b60d 100644
> --- a/drivers/mtd/nand/pl353_nand.c
> +++ b/drivers/mtd/nand/pl353_nand.c
> @@ -140,6 +140,48 @@ static struct nand_ecclayout nand_oob_64 = {
>  		 .length = 50} }
>  };
>  
> +static struct nand_ecclayout ondie_nand_oob_64 = {
> +	.eccbytes = 32,
> +
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		56, 57, 58, 59, 60, 61, 62, 63
> +	},
> +
> +	.oobfree = {
> +		{ .offset = 4, .length = 4 },
> +		{ .offset = 20, .length = 4 },
> +		{ .offset = 36, .length = 4 },
> +		{ .offset = 52, .length = 4 }
> +	}
> +};
> +
> +/* Generic flash bbt decriptors */
> +static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
> +static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
> +
> +static struct nand_bbt_descr bbt_main_descr = {
> +	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
> +		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
> +	.offs = 4,
> +	.len = 4,
> +	.veroffs = 20,
> +	.maxblocks = 4,
> +	.pattern = bbt_pattern
> +};
> +
> +static struct nand_bbt_descr bbt_mirror_descr = {
> +	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
> +		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
> +	.offs = 4,
> +	.len = 4,
> +	.veroffs = 20,
> +	.maxblocks = 4,
> +	.pattern = mirror_pattern
> +};

Why do you need a custom BBT descriptor? It's much better to use the
standard ones. Perhaps you just want the NAND_BBT_NO_OOB_BBM option, so
you get the bbt_{main,mirror}_no_oob_descr structs from nand_bbt.c.

> +
>  /**
>   * pl353_nand_calculate_hwecc - Calculate Hardware ECC
>   * @mtd:	Pointer to the mtd_info structure
> @@ -816,15 +858,74 @@ static int pl353_nand_device_ready(struct mtd_info *mtd)
>  }
>  
>  /**
> + * pl353_nand_detect_ondie_ecc - Get the flash ondie ecc state
> + * @mtd:	Pointer to the mtd_info structure
> + *
> + * This function enables the ondie ecc for the Micron ondie ecc capable devices
> + *
> + * Return:	1 on detect, 0 if fail to detect
> + */
> +static int pl353_nand_detect_ondie_ecc(struct mtd_info *mtd)

No. On-die ECC support should not be added to a specific NAND driver; it
needs to be written generically as part of nand_base. There have been
recent attempts to do this for Toshiba (try searching the linux-mtd
archives, in the last 4 months or so), but they fell a little short. I'd
rather start with a nand_base approach though.

> +{
> +	struct nand_chip *nand_chip = mtd->priv;
> +	u8 maf_id, dev_id, i, get_feature;
> +	u8 set_feature[4] = { 0x08, 0x00, 0x00, 0x00 };
> +
> +	/* Check if On-Die ECC flash */
> +	nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
> +	nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
> +
> +	/* Read manufacturer and device IDs */
> +	maf_id = readb(nand_chip->IO_ADDR_R);
> +	dev_id = readb(nand_chip->IO_ADDR_R);
> +
> +	if ((maf_id == NAND_MFR_MICRON) &&
> +	    ((dev_id == 0xf1) || (dev_id == 0xa1) ||
> +	     (dev_id == 0xb1) || (dev_id == 0xaa) ||
> +	     (dev_id == 0xba) || (dev_id == 0xda) ||
> +	     (dev_id == 0xca) || (dev_id == 0xac) ||
> +	     (dev_id == 0xbc) || (dev_id == 0xdc) ||
> +	     (dev_id == 0xcc) || (dev_id == 0xa3) ||
> +	     (dev_id == 0xb3) ||
> +	     (dev_id == 0xd3) || (dev_id == 0xc3))) {

So you're writing this with a list of device IDs? Would it make more
sense to use the ONFI parameters?

> +
> +		nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
> +				   ONDIE_ECC_FEATURE_ADDR, -1);
> +		get_feature = readb(nand_chip->IO_ADDR_R);
> +
> +		if (get_feature & 0x08) {
> +			return 1;
> +		} else {
> +			nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
> +					   ONDIE_ECC_FEATURE_ADDR, -1);
> +			for (i = 0; i < 4; i++)
> +				writeb(set_feature[i], nand_chip->IO_ADDR_W);
> +
> +			ndelay(1000);
> +
> +			nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
> +					   ONDIE_ECC_FEATURE_ADDR, -1);
> +			get_feature = readb(nand_chip->IO_ADDR_R);
> +
> +			if (get_feature & 0x08)
> +				return 1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
>   * pl353_nand_ecc_init - Initialize the ecc information as per the ecc mode
>   * @mtd:	Pointer to the mtd_info structure
> + * @ondie_ecc_state:	ondie ecc status
>   *
>   * This function initializes the ecc block and functional pointers as per the
>   * ecc mode
>   *
>   * Return:	Zero on success and error on failure.
>   */
> -static int pl353_nand_ecc_init(struct mtd_info *mtd)
> +static int pl353_nand_ecc_init(struct mtd_info *mtd, int ondie_ecc_state)
>  {
>  	struct nand_chip *nand_chip = mtd->priv;
>  	struct pl353_nand_info *xnand =
> @@ -838,27 +939,50 @@ static int pl353_nand_ecc_init(struct mtd_info *mtd)
>  
>  	switch (xnand->ecc_mode) {
>  	case NAND_ECC_HW:
> -		if (mtd->writesize > 2048) {
> +		if ((mtd->writesize > 2048) || ((ondie_ecc_state) &&
> +						(mtd->oobsize != 64))) {
>  			pr_warn("hardware ECC not possible\n");
>  			return -ENOTSUPP;
>  		}
>  
>  		nand_chip->ecc.mode = NAND_ECC_HW;
> -		nand_chip->ecc.calculate = pl353_nand_calculate_hwecc;
> -		nand_chip->ecc.correct = pl353_nand_correct_data;
> -		nand_chip->ecc.hwctl = NULL;
> -		nand_chip->ecc.read_page = pl353_nand_read_page_hwecc;
> -		nand_chip->ecc.size = PL353_NAND_ECC_SIZE;
> -		nand_chip->ecc.write_page = pl353_nand_write_page_hwecc;
> -		pl353_smc_set_ecc_pg_size(mtd->dev.parent, mtd->writesize);
> -		pl353_smc_set_ecc_mode(mtd->dev.parent, PL353_SMC_ECCMODE_APB);
> -		/* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
> -		nand_chip->ecc.bytes = 3;
> -
> -		if (mtd->oobsize == 16)
> -			nand_chip->ecc.layout = &nand_oob_16;
> -		else
> -			nand_chip->ecc.layout = &nand_oob_64;
> +		if (ondie_ecc_state) {
> +			/* Bypass the controller ECC block */
> +			pl353_smc_set_ecc_mode(mtd->dev.parent,
> +						PL353_SMC_ECCMODE_BYPASS);
> +			nand_chip->ecc.bytes = 0;
> +			nand_chip->ecc.layout = &ondie_nand_oob_64;
> +			nand_chip->ecc.read_page = pl353_nand_read_page_raw;
> +			nand_chip->ecc.write_page = pl353_nand_write_page_raw;
> +			nand_chip->ecc.size = mtd->writesize;
> +			/*
> +			 * On-Die ECC spare bytes offset 8 is used for ECC codes
> +			 * Use the BBT pattern descriptors
> +			 */
> +			nand_chip->bbt_td = &bbt_main_descr;
> +			nand_chip->bbt_md = &bbt_mirror_descr;
> +		} else {
> +			nand_chip->ecc.calculate = pl353_nand_calculate_hwecc;
> +			nand_chip->ecc.correct = pl353_nand_correct_data;
> +			nand_chip->ecc.hwctl = NULL;
> +			nand_chip->ecc.read_page = pl353_nand_read_page_hwecc;
> +			nand_chip->ecc.size = PL353_NAND_ECC_SIZE;
> +			nand_chip->ecc.write_page = pl353_nand_write_page_hwecc;
> +			pl353_smc_set_ecc_pg_size(mtd->dev.parent,
> +							mtd->writesize);
> +			pl353_smc_set_ecc_mode(mtd->dev.parent,
> +							PL353_SMC_ECCMODE_APB);
> +			/*
> +			 * Hardware ECC generates 3 bytes ECC code for each
> +			 * 512 bytes
> +			 */
> +			nand_chip->ecc.bytes = 3;
> +
> +			if (mtd->oobsize == 16)
> +				nand_chip->ecc.layout = &nand_oob_16;
> +			else
> +				nand_chip->ecc.layout = &nand_oob_64;
> +		}
>  
>  		break;
>  	case NAND_ECC_SOFT:
> @@ -901,6 +1025,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  	struct nand_chip *nand_chip;
>  	struct resource *res;
>  	struct mtd_part_parser_data ppdata;
> +	int ondie_ecc_state;
>  
>  	xnand = devm_kzalloc(&pdev->dev, sizeof(*xnand), GFP_KERNEL);
>  	if (!xnand)
> @@ -944,6 +1069,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, xnand);
>  
> +	ondie_ecc_state = pl353_nand_detect_ondie_ecc(mtd);
>  	/* first scan to find the device and get the page size */
>  	if (nand_scan_ident(mtd, 1, NULL)) {
>  		dev_err(&pdev->dev, "nand_scan_ident for NAND failed\n");
> @@ -954,7 +1080,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  	if (xnand->ecc_mode < 0)
>  		xnand->ecc_mode = NAND_ECC_HW;
>  
> -	if (pl353_nand_ecc_init(mtd))
> +	if (pl353_nand_ecc_init(mtd, ondie_ecc_state))
>  		return -ENOTSUPP;
>  
>  	if (nand_chip->options & NAND_BUSWIDTH_16)

Brian

WARNING: multiple messages have this Message-ID (diff)
From: Brian Norris <computersforpeace@gmail.com>
To: Punnaiah Choudary Kalluri <punnaiah.choudary.kalluri@xilinx.com>
Cc: robh+dt@kernel.org, pawel.moll@arm.com, mark.rutland@arm.com,
	ijc+devicetree@hellion.org.uk, galak@codeaurora.org,
	rob@landley.net, michal.simek@xilinx.com,
	grant.likely@linaro.org, gregkh@linuxfoundation.org,
	jason@lakedaemon.net, ezequiel.garcia@free-electrons.com,
	arnd@arndb.de, dwmw2@infradead.org,
	artem.bityutskiy@linux.intel.com, pekon@ti.com,
	jussi.kivilinna@iki.fi, acourbot@nvidia.com,
	ivan.khoronzhuk@ti.com, joern@logfs.org,
	devicetree@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org,
	kpc528@gmail.com, kalluripunnaiahchoudary@gmail.com,
	anirudh@xilinx.com, svemula@xilinx.com,
	Punnaiah Choudary Kalluri <punnaia@xilinx.com>
Subject: Re: [PATCH RFC v4 3/4] nand: pl353: Add ONDIE ECC support
Date: Thu, 31 Jul 2014 00:06:43 -0700	[thread overview]
Message-ID: <20140731070643.GG11952@brian-ubuntu> (raw)
In-Reply-To: <27fce982-6598-44a0-ad80-c13d02a952ee@BN1AFFO11FD042.protection.gbl>

Hi Punnaiah,

I haven't looked too closely at everything here, but a few comments:

On Mon, Jul 28, 2014 at 09:01:39PM +0530, Punnaiah Choudary Kalluri wrote:
> Added ONDIE ECC support. Currently this ecc mode is supported for
> specific micron parts with oob size 64 bytes.
> 
> Signed-off-by: Punnaiah Choudary Kalluri <punnaia@xilinx.com>
> ---
> Changes in v4:
> - Updated the driver to sync with pl353_smc driver APIs
> ---
>  drivers/mtd/nand/pl353_nand.c |  162 ++++++++++++++++++++++++++++++++++++-----
>  1 files changed, 144 insertions(+), 18 deletions(-)
> 
> diff --git a/drivers/mtd/nand/pl353_nand.c b/drivers/mtd/nand/pl353_nand.c
> index 93dc4ca..5c9b60d 100644
> --- a/drivers/mtd/nand/pl353_nand.c
> +++ b/drivers/mtd/nand/pl353_nand.c
> @@ -140,6 +140,48 @@ static struct nand_ecclayout nand_oob_64 = {
>  		 .length = 50} }
>  };
>  
> +static struct nand_ecclayout ondie_nand_oob_64 = {
> +	.eccbytes = 32,
> +
> +	.eccpos = {
> +		8, 9, 10, 11, 12, 13, 14, 15,
> +		24, 25, 26, 27, 28, 29, 30, 31,
> +		40, 41, 42, 43, 44, 45, 46, 47,
> +		56, 57, 58, 59, 60, 61, 62, 63
> +	},
> +
> +	.oobfree = {
> +		{ .offset = 4, .length = 4 },
> +		{ .offset = 20, .length = 4 },
> +		{ .offset = 36, .length = 4 },
> +		{ .offset = 52, .length = 4 }
> +	}
> +};
> +
> +/* Generic flash bbt decriptors */
> +static uint8_t bbt_pattern[] = { 'B', 'b', 't', '0' };
> +static uint8_t mirror_pattern[] = { '1', 't', 'b', 'B' };
> +
> +static struct nand_bbt_descr bbt_main_descr = {
> +	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
> +		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
> +	.offs = 4,
> +	.len = 4,
> +	.veroffs = 20,
> +	.maxblocks = 4,
> +	.pattern = bbt_pattern
> +};
> +
> +static struct nand_bbt_descr bbt_mirror_descr = {
> +	.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
> +		| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
> +	.offs = 4,
> +	.len = 4,
> +	.veroffs = 20,
> +	.maxblocks = 4,
> +	.pattern = mirror_pattern
> +};

Why do you need a custom BBT descriptor? It's much better to use the
standard ones. Perhaps you just want the NAND_BBT_NO_OOB_BBM option, so
you get the bbt_{main,mirror}_no_oob_descr structs from nand_bbt.c.

> +
>  /**
>   * pl353_nand_calculate_hwecc - Calculate Hardware ECC
>   * @mtd:	Pointer to the mtd_info structure
> @@ -816,15 +858,74 @@ static int pl353_nand_device_ready(struct mtd_info *mtd)
>  }
>  
>  /**
> + * pl353_nand_detect_ondie_ecc - Get the flash ondie ecc state
> + * @mtd:	Pointer to the mtd_info structure
> + *
> + * This function enables the ondie ecc for the Micron ondie ecc capable devices
> + *
> + * Return:	1 on detect, 0 if fail to detect
> + */
> +static int pl353_nand_detect_ondie_ecc(struct mtd_info *mtd)

No. On-die ECC support should not be added to a specific NAND driver; it
needs to be written generically as part of nand_base. There have been
recent attempts to do this for Toshiba (try searching the linux-mtd
archives, in the last 4 months or so), but they fell a little short. I'd
rather start with a nand_base approach though.

> +{
> +	struct nand_chip *nand_chip = mtd->priv;
> +	u8 maf_id, dev_id, i, get_feature;
> +	u8 set_feature[4] = { 0x08, 0x00, 0x00, 0x00 };
> +
> +	/* Check if On-Die ECC flash */
> +	nand_chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
> +	nand_chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
> +
> +	/* Read manufacturer and device IDs */
> +	maf_id = readb(nand_chip->IO_ADDR_R);
> +	dev_id = readb(nand_chip->IO_ADDR_R);
> +
> +	if ((maf_id == NAND_MFR_MICRON) &&
> +	    ((dev_id == 0xf1) || (dev_id == 0xa1) ||
> +	     (dev_id == 0xb1) || (dev_id == 0xaa) ||
> +	     (dev_id == 0xba) || (dev_id == 0xda) ||
> +	     (dev_id == 0xca) || (dev_id == 0xac) ||
> +	     (dev_id == 0xbc) || (dev_id == 0xdc) ||
> +	     (dev_id == 0xcc) || (dev_id == 0xa3) ||
> +	     (dev_id == 0xb3) ||
> +	     (dev_id == 0xd3) || (dev_id == 0xc3))) {

So you're writing this with a list of device IDs? Would it make more
sense to use the ONFI parameters?

> +
> +		nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
> +				   ONDIE_ECC_FEATURE_ADDR, -1);
> +		get_feature = readb(nand_chip->IO_ADDR_R);
> +
> +		if (get_feature & 0x08) {
> +			return 1;
> +		} else {
> +			nand_chip->cmdfunc(mtd, NAND_CMD_SET_FEATURES,
> +					   ONDIE_ECC_FEATURE_ADDR, -1);
> +			for (i = 0; i < 4; i++)
> +				writeb(set_feature[i], nand_chip->IO_ADDR_W);
> +
> +			ndelay(1000);
> +
> +			nand_chip->cmdfunc(mtd, NAND_CMD_GET_FEATURES,
> +					   ONDIE_ECC_FEATURE_ADDR, -1);
> +			get_feature = readb(nand_chip->IO_ADDR_R);
> +
> +			if (get_feature & 0x08)
> +				return 1;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +/**
>   * pl353_nand_ecc_init - Initialize the ecc information as per the ecc mode
>   * @mtd:	Pointer to the mtd_info structure
> + * @ondie_ecc_state:	ondie ecc status
>   *
>   * This function initializes the ecc block and functional pointers as per the
>   * ecc mode
>   *
>   * Return:	Zero on success and error on failure.
>   */
> -static int pl353_nand_ecc_init(struct mtd_info *mtd)
> +static int pl353_nand_ecc_init(struct mtd_info *mtd, int ondie_ecc_state)
>  {
>  	struct nand_chip *nand_chip = mtd->priv;
>  	struct pl353_nand_info *xnand =
> @@ -838,27 +939,50 @@ static int pl353_nand_ecc_init(struct mtd_info *mtd)
>  
>  	switch (xnand->ecc_mode) {
>  	case NAND_ECC_HW:
> -		if (mtd->writesize > 2048) {
> +		if ((mtd->writesize > 2048) || ((ondie_ecc_state) &&
> +						(mtd->oobsize != 64))) {
>  			pr_warn("hardware ECC not possible\n");
>  			return -ENOTSUPP;
>  		}
>  
>  		nand_chip->ecc.mode = NAND_ECC_HW;
> -		nand_chip->ecc.calculate = pl353_nand_calculate_hwecc;
> -		nand_chip->ecc.correct = pl353_nand_correct_data;
> -		nand_chip->ecc.hwctl = NULL;
> -		nand_chip->ecc.read_page = pl353_nand_read_page_hwecc;
> -		nand_chip->ecc.size = PL353_NAND_ECC_SIZE;
> -		nand_chip->ecc.write_page = pl353_nand_write_page_hwecc;
> -		pl353_smc_set_ecc_pg_size(mtd->dev.parent, mtd->writesize);
> -		pl353_smc_set_ecc_mode(mtd->dev.parent, PL353_SMC_ECCMODE_APB);
> -		/* Hardware ECC generates 3 bytes ECC code for each 512 bytes */
> -		nand_chip->ecc.bytes = 3;
> -
> -		if (mtd->oobsize == 16)
> -			nand_chip->ecc.layout = &nand_oob_16;
> -		else
> -			nand_chip->ecc.layout = &nand_oob_64;
> +		if (ondie_ecc_state) {
> +			/* Bypass the controller ECC block */
> +			pl353_smc_set_ecc_mode(mtd->dev.parent,
> +						PL353_SMC_ECCMODE_BYPASS);
> +			nand_chip->ecc.bytes = 0;
> +			nand_chip->ecc.layout = &ondie_nand_oob_64;
> +			nand_chip->ecc.read_page = pl353_nand_read_page_raw;
> +			nand_chip->ecc.write_page = pl353_nand_write_page_raw;
> +			nand_chip->ecc.size = mtd->writesize;
> +			/*
> +			 * On-Die ECC spare bytes offset 8 is used for ECC codes
> +			 * Use the BBT pattern descriptors
> +			 */
> +			nand_chip->bbt_td = &bbt_main_descr;
> +			nand_chip->bbt_md = &bbt_mirror_descr;
> +		} else {
> +			nand_chip->ecc.calculate = pl353_nand_calculate_hwecc;
> +			nand_chip->ecc.correct = pl353_nand_correct_data;
> +			nand_chip->ecc.hwctl = NULL;
> +			nand_chip->ecc.read_page = pl353_nand_read_page_hwecc;
> +			nand_chip->ecc.size = PL353_NAND_ECC_SIZE;
> +			nand_chip->ecc.write_page = pl353_nand_write_page_hwecc;
> +			pl353_smc_set_ecc_pg_size(mtd->dev.parent,
> +							mtd->writesize);
> +			pl353_smc_set_ecc_mode(mtd->dev.parent,
> +							PL353_SMC_ECCMODE_APB);
> +			/*
> +			 * Hardware ECC generates 3 bytes ECC code for each
> +			 * 512 bytes
> +			 */
> +			nand_chip->ecc.bytes = 3;
> +
> +			if (mtd->oobsize == 16)
> +				nand_chip->ecc.layout = &nand_oob_16;
> +			else
> +				nand_chip->ecc.layout = &nand_oob_64;
> +		}
>  
>  		break;
>  	case NAND_ECC_SOFT:
> @@ -901,6 +1025,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  	struct nand_chip *nand_chip;
>  	struct resource *res;
>  	struct mtd_part_parser_data ppdata;
> +	int ondie_ecc_state;
>  
>  	xnand = devm_kzalloc(&pdev->dev, sizeof(*xnand), GFP_KERNEL);
>  	if (!xnand)
> @@ -944,6 +1069,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  
>  	platform_set_drvdata(pdev, xnand);
>  
> +	ondie_ecc_state = pl353_nand_detect_ondie_ecc(mtd);
>  	/* first scan to find the device and get the page size */
>  	if (nand_scan_ident(mtd, 1, NULL)) {
>  		dev_err(&pdev->dev, "nand_scan_ident for NAND failed\n");
> @@ -954,7 +1080,7 @@ static int pl353_nand_probe(struct platform_device *pdev)
>  	if (xnand->ecc_mode < 0)
>  		xnand->ecc_mode = NAND_ECC_HW;
>  
> -	if (pl353_nand_ecc_init(mtd))
> +	if (pl353_nand_ecc_init(mtd, ondie_ecc_state))
>  		return -ENOTSUPP;
>  
>  	if (nand_chip->options & NAND_BUSWIDTH_16)

Brian

  reply	other threads:[~2014-07-31  7:07 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1406561500-18264-1-git-send-email-punnaia@xilinx.com>
2014-07-28 15:31 ` [PATCH RFC v4 1/4] nand: pl353: Add basic driver for arm pl353 smc nand interface Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31 ` [PATCH RFC v4 2/4] nand: pl353: Add software ecc support Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31 ` [PATCH RFC v4 3/4] nand: pl353: Add ONDIE ECC support Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-31  7:06   ` Brian Norris [this message]
2014-07-31  7:06     ` Brian Norris
2014-07-31  7:23     ` Brian Norris
2014-07-31  7:23       ` Brian Norris
2014-07-31 16:01     ` Punnaiah Choudary Kalluri
2014-07-31 16:01       ` Punnaiah Choudary Kalluri
2014-07-28 15:31 ` [PATCH RFC v4 4/4] Documentation: nand: pl353: Add documentation for controller and driver Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-28 15:31   ` Punnaiah Choudary Kalluri
2014-07-29  0:31   ` Randy Dunlap
2014-07-29  0:31     ` Randy Dunlap
2014-07-29  2:42     ` Punnaiah Choudary
2014-07-29  2:44     ` Punnaiah Choudary
2014-07-29  2:44       ` Punnaiah Choudary
2014-07-29  2:44       ` Punnaiah Choudary

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20140731070643.GG11952@brian-ubuntu \
    --to=computersforpeace@gmail.com \
    --cc=acourbot@nvidia.com \
    --cc=anirudh@xilinx.com \
    --cc=arnd@arndb.de \
    --cc=artem.bityutskiy@linux.intel.com \
    --cc=devicetree@vger.kernel.org \
    --cc=dwmw2@infradead.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=galak@codeaurora.org \
    --cc=grant.likely@linaro.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=ivan.khoronzhuk@ti.com \
    --cc=jason@lakedaemon.net \
    --cc=joern@logfs.org \
    --cc=jussi.kivilinna@iki.fi \
    --cc=kalluripunnaiahchoudary@gmail.com \
    --cc=kpc528@gmail.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=mark.rutland@arm.com \
    --cc=michal.simek@xilinx.com \
    --cc=pawel.moll@arm.com \
    --cc=pekon@ti.com \
    --cc=punnaia@xilinx.com \
    --cc=punnaiah.choudary.kalluri@xilinx.com \
    --cc=rob@landley.net \
    --cc=robh+dt@kernel.org \
    --cc=svemula@xilinx.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.