All of lore.kernel.org
 help / color / mirror / Atom feed
From: Roger Quadros <rogerq@ti.com>
To: "Gupta, Pekon" <pekon@ti.com>,
	"tony@atomide.com" <tony@atomide.com>,
	"computersforpeace@gmail.com" <computersforpeace@gmail.com>
Cc: "jg1.han@samsung.com" <jg1.han@samsung.com>,
	"Nori, Sekhar" <nsekhar@ti.com>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	"linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>,
	"ezequiel.garcia@free-electrons.com"
	<ezequiel.garcia@free-electrons.com>,
	"javier@dowhile0.org" <javier@dowhile0.org>,
	"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
	"dwmw2@infradead.org" <dwmw2@infradead.org>
Subject: Re: [RFC PATCH 02/10] mtd: nand: omap: Always use chip->ecc.steps for BCH sector count
Date: Fri, 11 Jul 2014 13:35:38 +0300	[thread overview]
Message-ID: <53BFBDFA.8040901@ti.com> (raw)
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EB01DF7@DBDE04.ent.ti.com>

On 07/11/2014 10:43 AM, Gupta, Pekon wrote:
>> From: Quadros, Roger
>>
>> Instead of hardcoding use the pre-calculated chip->ecc.steps for
>> configuring number of sectors to process with the BCH algorithm.
>>
>> This also avoids unnecessary access to the ECC_CONFIG register in
>> omap_calculate_ecc_bch().
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>> drivers/mtd/nand/omap2.c | 9 +++------
>> 1 file changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>> index 5b8739c..6f3d7cd 100644
>> --- a/drivers/mtd/nand/omap2.c
>> +++ b/drivers/mtd/nand/omap2.c
>> @@ -1066,10 +1066,10 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 	unsigned int ecc_size1, ecc_size0;
>>
>> 	/* GPMC configurations for calculating ECC */
>> +	nsectors = chip->ecc.steps;
>> 	switch (ecc_opt) {
>> 	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
>> 		bch_type = 0;
>> -		nsectors = 1;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_6;
>> 			ecc_size0 = BCH_ECC_SIZE0;
>> @@ -1082,7 +1082,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH4_CODE_HW:
>> 		bch_type = 0;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_1;
>> 			ecc_size0 = BCH4R_ECC_SIZE0;
>> @@ -1095,7 +1094,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
>> 		bch_type = 1;
>> -		nsectors = 1;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_6;
>> 			ecc_size0 = BCH_ECC_SIZE0;
>> @@ -1108,7 +1106,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH8_CODE_HW:
>> 		bch_type = 1;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_1;
>> 			ecc_size0 = BCH8R_ECC_SIZE0;
>> @@ -1121,7 +1118,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH16_CODE_HW:
>> 		bch_type = 0x2;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = 0x01;
>> 			ecc_size0 = 52; /* ECC bits in nibbles per sector */
>> @@ -1176,6 +1172,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
>> {
>> 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>> 						   mtd);
>> +	struct nand_chip *chip = mtd->priv;
>> 	int eccbytes	= info->nand.ecc.bytes;
>> 	struct gpmc_nand_regs	*gpmc_regs = &info->reg;
>> 	u8 *ecc_code;
>> @@ -1183,7 +1180,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
>> 	u32 val;
>> 	int i, j;
>>
>> -	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
>> +	nsectors = chip->ecc.steps;
> 
> Sorry NAK.. I'm sure you are breaking something here :-)
> 
> NAND driver supports multiple ECC schemes like;
> OMAP_ECC_CODE_HAM1_HW (support for legacy reasons)
> OMAP_ECC_CODE_BCH4_HW_DETECTION_SW (needed for OMAP3 and AM35xx)
> OMAP_ECC_CODE_BCH4_HW
> OMAP_ECC_CODE_BCH8_HW
> OMAP_ECC_CODE_BCH8_HW_DETECTION_SW  (needed for OMAP3 and AM35xx)
> OMAP_ECC_CODE_BCH16_HW
> 
> IIRC ..
> - software based ecc-schemes OMAP_ECC_CODE_BCHx_HW_DETECTION_SW
>   Reads/Write in per-sector granularity. (here nsector != chip->ecc.steps)

OK. I still don't have a full understanding about the ECC schemes so to ensure we
don't break anything I can just leave nsectors as it is and probably just store a
copy of it in omap_nand_info to avoid reading it back from gpmc_ecc_config.

I still have a few questions to clarify my understanding.

The only difference between OMAP_ECC_CODE_BCHx_HW_DETECTION_SW and
OMAP_ECC_CODE_BCHx_HW is that in the former the _correction_ is done by software
and in the latter the _correction_ is done by hardware (i.e. ELM module).
In both cases the _detection_ is done by the same hardware IP via ecc.calculate(),
i.e. omap_calculate_ecc_bch().

so why should nsector be different for both in the _detection_ stage?

An I right that ecc_steps is nothing but number of sub-blocks ECC calculation and correction
needs to be done for larger pages. This is a function of ECC hw capability (chip->ecc.size)
and NAND flash capability (mtd->writesize). i.e. ecc_steps = mtd->writesize / chip->ecc.size

We hardcode chip->ecc.size to 512 for all the ECC schemes in omap_nand_probe() so
calculate and correct will always be called for 512 byte sized blocks. So when does
the usecase for nsector > 1 come in?

cheers,
-roger

WARNING: multiple messages have this Message-ID (diff)
From: Roger Quadros <rogerq@ti.com>
To: "Gupta, Pekon" <pekon@ti.com>,
	"tony@atomide.com" <tony@atomide.com>,
	"computersforpeace@gmail.com" <computersforpeace@gmail.com>
Cc: "javier@dowhile0.org" <javier@dowhile0.org>,
	"ezequiel.garcia@free-electrons.com"
	<ezequiel.garcia@free-electrons.com>,
	"dwmw2@infradead.org" <dwmw2@infradead.org>,
	"jg1.han@samsung.com" <jg1.han@samsung.com>,
	"Nori, Sekhar" <nsekhar@ti.com>,
	"linux-mtd@lists.infradead.org" <linux-mtd@lists.infradead.org>,
	"linux-omap@vger.kernel.org" <linux-omap@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [RFC PATCH 02/10] mtd: nand: omap: Always use chip->ecc.steps for BCH sector count
Date: Fri, 11 Jul 2014 13:35:38 +0300	[thread overview]
Message-ID: <53BFBDFA.8040901@ti.com> (raw)
In-Reply-To: <20980858CB6D3A4BAE95CA194937D5E73EB01DF7@DBDE04.ent.ti.com>

On 07/11/2014 10:43 AM, Gupta, Pekon wrote:
>> From: Quadros, Roger
>>
>> Instead of hardcoding use the pre-calculated chip->ecc.steps for
>> configuring number of sectors to process with the BCH algorithm.
>>
>> This also avoids unnecessary access to the ECC_CONFIG register in
>> omap_calculate_ecc_bch().
>>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>> drivers/mtd/nand/omap2.c | 9 +++------
>> 1 file changed, 3 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c
>> index 5b8739c..6f3d7cd 100644
>> --- a/drivers/mtd/nand/omap2.c
>> +++ b/drivers/mtd/nand/omap2.c
>> @@ -1066,10 +1066,10 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 	unsigned int ecc_size1, ecc_size0;
>>
>> 	/* GPMC configurations for calculating ECC */
>> +	nsectors = chip->ecc.steps;
>> 	switch (ecc_opt) {
>> 	case OMAP_ECC_BCH4_CODE_HW_DETECTION_SW:
>> 		bch_type = 0;
>> -		nsectors = 1;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_6;
>> 			ecc_size0 = BCH_ECC_SIZE0;
>> @@ -1082,7 +1082,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH4_CODE_HW:
>> 		bch_type = 0;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_1;
>> 			ecc_size0 = BCH4R_ECC_SIZE0;
>> @@ -1095,7 +1094,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH8_CODE_HW_DETECTION_SW:
>> 		bch_type = 1;
>> -		nsectors = 1;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_6;
>> 			ecc_size0 = BCH_ECC_SIZE0;
>> @@ -1108,7 +1106,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH8_CODE_HW:
>> 		bch_type = 1;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = BCH_WRAPMODE_1;
>> 			ecc_size0 = BCH8R_ECC_SIZE0;
>> @@ -1121,7 +1118,6 @@ static void __maybe_unused omap_enable_hwecc_bch(struct mtd_info
>> *mtd, int mode)
>> 		break;
>> 	case OMAP_ECC_BCH16_CODE_HW:
>> 		bch_type = 0x2;
>> -		nsectors = chip->ecc.steps;
>> 		if (mode == NAND_ECC_READ) {
>> 			wr_mode	  = 0x01;
>> 			ecc_size0 = 52; /* ECC bits in nibbles per sector */
>> @@ -1176,6 +1172,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
>> {
>> 	struct omap_nand_info *info = container_of(mtd, struct omap_nand_info,
>> 						   mtd);
>> +	struct nand_chip *chip = mtd->priv;
>> 	int eccbytes	= info->nand.ecc.bytes;
>> 	struct gpmc_nand_regs	*gpmc_regs = &info->reg;
>> 	u8 *ecc_code;
>> @@ -1183,7 +1180,7 @@ static int __maybe_unused omap_calculate_ecc_bch(struct mtd_info *mtd,
>> 	u32 val;
>> 	int i, j;
>>
>> -	nsectors = ((readl(info->reg.gpmc_ecc_config) >> 4) & 0x7) + 1;
>> +	nsectors = chip->ecc.steps;
> 
> Sorry NAK.. I'm sure you are breaking something here :-)
> 
> NAND driver supports multiple ECC schemes like;
> OMAP_ECC_CODE_HAM1_HW (support for legacy reasons)
> OMAP_ECC_CODE_BCH4_HW_DETECTION_SW (needed for OMAP3 and AM35xx)
> OMAP_ECC_CODE_BCH4_HW
> OMAP_ECC_CODE_BCH8_HW
> OMAP_ECC_CODE_BCH8_HW_DETECTION_SW  (needed for OMAP3 and AM35xx)
> OMAP_ECC_CODE_BCH16_HW
> 
> IIRC ..
> - software based ecc-schemes OMAP_ECC_CODE_BCHx_HW_DETECTION_SW
>   Reads/Write in per-sector granularity. (here nsector != chip->ecc.steps)

OK. I still don't have a full understanding about the ECC schemes so to ensure we
don't break anything I can just leave nsectors as it is and probably just store a
copy of it in omap_nand_info to avoid reading it back from gpmc_ecc_config.

I still have a few questions to clarify my understanding.

The only difference between OMAP_ECC_CODE_BCHx_HW_DETECTION_SW and
OMAP_ECC_CODE_BCHx_HW is that in the former the _correction_ is done by software
and in the latter the _correction_ is done by hardware (i.e. ELM module).
In both cases the _detection_ is done by the same hardware IP via ecc.calculate(),
i.e. omap_calculate_ecc_bch().

so why should nsector be different for both in the _detection_ stage?

An I right that ecc_steps is nothing but number of sub-blocks ECC calculation and correction
needs to be done for larger pages. This is a function of ECC hw capability (chip->ecc.size)
and NAND flash capability (mtd->writesize). i.e. ecc_steps = mtd->writesize / chip->ecc.size

We hardcode chip->ecc.size to 512 for all the ECC schemes in omap_nand_probe() so
calculate and correct will always be called for 512 byte sized blocks. So when does
the usecase for nsector > 1 come in?

cheers,
-roger

  reply	other threads:[~2014-07-11 10:35 UTC|newest]

Thread overview: 57+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-07-09 12:37 [RFC PATCH 00/10] OMAP: GPMC: NAND: Introduce GPMC APIs for OMAP NAND Roger Quadros
2014-07-09 12:37 ` Roger Quadros
2014-07-09 12:37 ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 01/10] mtd: nand: omap: Use a single hardware controller instance Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 02/10] mtd: nand: omap: Always use chip->ecc.steps for BCH sector count Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-11  7:43   ` Gupta, Pekon
2014-07-11  7:43     ` Gupta, Pekon
2014-07-11 10:35     ` Roger Quadros [this message]
2014-07-11 10:35       ` Roger Quadros
2014-07-11 11:27       ` Gupta, Pekon
2014-07-11 11:27         ` Gupta, Pekon
2014-07-11 11:51         ` Roger Quadros
2014-07-11 11:51           ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 03/10] OMAP: GPMC: Introduce APIs to access NAND control registers Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 04/10] mtd: nand: omap: Use GPMC APIs for NAND control Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 05/10] OMAP: GPMC: Introduce APIs for accessing Prefetch/Write-post engine Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 06/10] mtd: nand: omap: Use GPMC APIs for accessing Prefetch engine Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 07/10] OMAP: GPMC: Introduce APIs for Configuring ECC Engine Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-11  7:54   ` Gupta, Pekon
2014-07-11  7:54     ` Gupta, Pekon
2014-07-09 12:37 ` [RFC PATCH 08/10] OMAP: GPMC: Introduce APIs to get ECC/BCH results Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37 ` [RFC PATCH 09/10] mtd: nand: omap: Use GPMC APIs for accessing ECC/BCH engine Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-11  7:56   ` Gupta, Pekon
2014-07-11  7:56     ` Gupta, Pekon
2014-07-09 12:37 ` [RFC PATCH 10/10] OMAP: GPMC: NAND: Don't pass NAND/ECC/BCH register adresses to NAND driver Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-09 12:37   ` Roger Quadros
2014-07-11  6:52 ` [RFC PATCH 00/10] OMAP: GPMC: NAND: Introduce GPMC APIs for OMAP NAND Tony Lindgren
2014-07-11  6:52   ` Tony Lindgren
2014-07-11  7:27   ` Gupta, Pekon
2014-07-11  7:27     ` Gupta, Pekon
2014-07-11  8:28     ` Roger Quadros
2014-07-11  8:28       ` Roger Quadros
2014-07-11  9:42       ` Gupta, Pekon
2014-07-11  9:42         ` Gupta, Pekon
2014-07-11 10:23         ` Roger Quadros
2014-07-11 10:23           ` Roger Quadros
2014-07-29 10:39           ` Tony Lindgren
2014-07-29 10:39             ` Tony Lindgren

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=53BFBDFA.8040901@ti.com \
    --to=rogerq@ti.com \
    --cc=computersforpeace@gmail.com \
    --cc=dwmw2@infradead.org \
    --cc=ezequiel.garcia@free-electrons.com \
    --cc=javier@dowhile0.org \
    --cc=jg1.han@samsung.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-mtd@lists.infradead.org \
    --cc=linux-omap@vger.kernel.org \
    --cc=nsekhar@ti.com \
    --cc=pekon@ti.com \
    --cc=tony@atomide.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.