linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH V3] mtd: rawnand: qcom: update last code word register
@ 2021-01-10  4:01 Md Sadre Alam
  2021-01-14 15:53 ` Miquel Raynal
  2021-01-28  7:52 ` Manivannan Sadhasivam
  0 siblings, 2 replies; 10+ messages in thread
From: Md Sadre Alam @ 2021-01-10  4:01 UTC (permalink / raw)
  To: miquel.raynal, manivannan.sadhasivam, richard, vigneshr,
	boris.brezillon, linux-mtd, linux-kernel
  Cc: mdalam, sricharan

From QPIC version 2.0 onwards new register got added to
read last codeword. This change will update the same.

For first three code word READ_LOCATION_n register will be
use.For last code word READ_LOCATION_LAST_CW_n register will be
use.

Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>
---
[V3]
 * Added else condition for last code word in update_rw_regs().
 drivers/mtd/nand/raw/qcom_nandc.c | 84 ++++++++++++++++++++++++++++++++-------
 1 file changed, 70 insertions(+), 14 deletions(-)

diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
index 667e4bf..50ff6e3 100644
--- a/drivers/mtd/nand/raw/qcom_nandc.c
+++ b/drivers/mtd/nand/raw/qcom_nandc.c
@@ -48,6 +48,10 @@
 #define	NAND_READ_LOCATION_1		0xf24
 #define	NAND_READ_LOCATION_2		0xf28
 #define	NAND_READ_LOCATION_3		0xf2c
+#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
+#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
+#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
+#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
 
 /* dummy register offsets, used by write_reg_dma */
 #define	NAND_DEV_CMD1_RESTORE		0xdead
@@ -187,6 +191,12 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_##reg,			\
 	      ((size) << READ_LOCATION_SIZE) |			\
 	      ((is_last) << READ_LOCATION_LAST))
 
+#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
+nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
+	      ((offset) << READ_LOCATION_OFFSET) |		\
+	      ((size) << READ_LOCATION_SIZE) |			\
+	      ((is_last) << READ_LOCATION_LAST))
+
 /*
  * Returns the actual register address for all NAND_DEV_ registers
  * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
@@ -316,6 +326,10 @@ struct nandc_regs {
 	__le32 read_location1;
 	__le32 read_location2;
 	__le32 read_location3;
+	__le32 read_location_last0;
+	__le32 read_location_last1;
+	__le32 read_location_last2;
+	__le32 read_location_last3;
 
 	__le32 erased_cw_detect_cfg_clr;
 	__le32 erased_cw_detect_cfg_set;
@@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
 		return &regs->read_location2;
 	case NAND_READ_LOCATION_3:
 		return &regs->read_location3;
+	case NAND_READ_LOCATION_LAST_CW_0:
+		return &regs->read_location_last0;
+	case NAND_READ_LOCATION_LAST_CW_1:
+		return &regs->read_location_last1;
+	case NAND_READ_LOCATION_LAST_CW_2:
+		return &regs->read_location_last2;
+	case NAND_READ_LOCATION_LAST_CW_3:
+		return &regs->read_location_last3;
 	default:
 		return NULL;
 	}
@@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
 	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
 	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
 
-	if (read)
-		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
-				   host->cw_data : host->cw_size, 1);
+	if (read) {
+		if (nandc->props->qpic_v2)
+			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
+					host->cw_data : host->cw_size, 1);
+		else
+			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
+					host->cw_data : host->cw_size, 1);
+	}
 }
 
 /*
@@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
 static void
 config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
 {
-	if (nandc->props->is_bam)
+	if (nandc->props->is_bam) {
+		if (nandc->props->qpic_v2)
+			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
+				      1, NAND_BAM_NEXT_SGL);
 		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
 			      NAND_BAM_NEXT_SGL);
+	}
 
 	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
 	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
@@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
 	}
 
 	if (nandc->props->is_bam) {
-		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
+		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
+			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
+		else
+			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
 		read_loc += data_size1;
 
-		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
+		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
+			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
+		else
+			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
 		read_loc += oob_size1;
 
-		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
+		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
+			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
+		else
+			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
 		read_loc += data_size2;
 
-		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
+		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
+			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
+		else
+			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
 	}
 
 	config_nand_cw_read(nandc, false);
@@ -1873,14 +1916,27 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
 
 		if (nandc->props->is_bam) {
 			if (data_buf && oob_buf) {
-				nandc_set_read_loc(nandc, 0, 0, data_size, 0);
-				nandc_set_read_loc(nandc, 1, data_size,
-						   oob_size, 1);
+				if (nandc->props->qpic_v2 && i == (ecc->steps - 1)) {
+					nandc_set_read_loc_last(nandc, 0, 0, data_size, 0);
+					nandc_set_read_loc_last(nandc, 1, data_size,
+								oob_size, 1);
+				} else {
+					nandc_set_read_loc(nandc, 0, 0, data_size, 0);
+					nandc_set_read_loc(nandc, 1, data_size,
+							   oob_size, 1);
+				}
 			} else if (data_buf) {
-				nandc_set_read_loc(nandc, 0, 0, data_size, 1);
+				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
+					nandc_set_read_loc_last(nandc, 0, 0, data_size, 1);
+				else
+					nandc_set_read_loc(nandc, 0, 0, data_size, 1);
 			} else {
-				nandc_set_read_loc(nandc, 0, data_size,
-						   oob_size, 1);
+				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
+					nandc_set_read_loc_last(nandc, 0, data_size,
+								oob_size, 1);
+				else
+					nandc_set_read_loc(nandc, 0, data_size,
+							   oob_size, 1);
 			}
 		}
 
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-10  4:01 [PATCH V3] mtd: rawnand: qcom: update last code word register Md Sadre Alam
@ 2021-01-14 15:53 ` Miquel Raynal
  2021-01-14 16:31   ` Manivannan Sadhasivam
  2021-01-28 21:48   ` mdalam
  2021-01-28  7:52 ` Manivannan Sadhasivam
  1 sibling, 2 replies; 10+ messages in thread
From: Miquel Raynal @ 2021-01-14 15:53 UTC (permalink / raw)
  To: Md Sadre Alam
  Cc: manivannan.sadhasivam, richard, vigneshr, boris.brezillon,
	linux-mtd, linux-kernel, sricharan

Hello,

Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
09:31:45 +0530:

> From QPIC version 2.0 onwards new register got added to

                                a

> read last codeword. This change will update the same.

       the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                      Please reword this sentence.

> For first three code word READ_LOCATION_n register will be
> use.For last code word READ_LOCATION_LAST_CW_n register will be
> use.

"For the first three codewords, READ_LOCATION_n registers will be used.
The last codeword register will be accessed through
READ_LOCATION_LAST_CW_n."

Also, please specify what these registers store.

> Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>

Could someone please test this patch?

> ---
> [V3]
>  * Added else condition for last code word in update_rw_regs().
>  drivers/mtd/nand/raw/qcom_nandc.c | 84 ++++++++++++++++++++++++++++++++-------
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index 667e4bf..50ff6e3 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -48,6 +48,10 @@
>  #define	NAND_READ_LOCATION_1		0xf24
>  #define	NAND_READ_LOCATION_2		0xf28
>  #define	NAND_READ_LOCATION_3		0xf2c
> +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
> +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
> +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
> +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
>  
>  /* dummy register offsets, used by write_reg_dma */
>  #define	NAND_DEV_CMD1_RESTORE		0xdead
> @@ -187,6 +191,12 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_##reg,			\
>  	      ((size) << READ_LOCATION_SIZE) |			\
>  	      ((is_last) << READ_LOCATION_LAST))
>  
> +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
> +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
> +	      ((offset) << READ_LOCATION_OFFSET) |		\
> +	      ((size) << READ_LOCATION_SIZE) |			\
> +	      ((is_last) << READ_LOCATION_LAST))
> +
>  /*
>   * Returns the actual register address for all NAND_DEV_ registers
>   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
> @@ -316,6 +326,10 @@ struct nandc_regs {
>  	__le32 read_location1;
>  	__le32 read_location2;
>  	__le32 read_location3;
> +	__le32 read_location_last0;
> +	__le32 read_location_last1;
> +	__le32 read_location_last2;
> +	__le32 read_location_last3;
>  
>  	__le32 erased_cw_detect_cfg_clr;
>  	__le32 erased_cw_detect_cfg_set;
> @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
>  		return &regs->read_location2;
>  	case NAND_READ_LOCATION_3:
>  		return &regs->read_location3;
> +	case NAND_READ_LOCATION_LAST_CW_0:
> +		return &regs->read_location_last0;
> +	case NAND_READ_LOCATION_LAST_CW_1:
> +		return &regs->read_location_last1;
> +	case NAND_READ_LOCATION_LAST_CW_2:
> +		return &regs->read_location_last2;
> +	case NAND_READ_LOCATION_LAST_CW_3:
> +		return &regs->read_location_last3;
>  	default:
>  		return NULL;
>  	}
> @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
>  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>  
> -	if (read)
> -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> -				   host->cw_data : host->cw_size, 1);
> +	if (read) {
> +		if (nandc->props->qpic_v2)
> +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
> +					host->cw_data : host->cw_size, 1);
> +		else
> +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> +					host->cw_data : host->cw_size, 1);
> +	}
>  }
>  
>  /*
> @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
>  static void
>  config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
>  {
> -	if (nandc->props->is_bam)
> +	if (nandc->props->is_bam) {
> +		if (nandc->props->qpic_v2)
> +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
> +				      1, NAND_BAM_NEXT_SGL);
>  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
>  			      NAND_BAM_NEXT_SGL);
> +	}
>  
>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  	}
>  
>  	if (nandc->props->is_bam) {
> -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
> +		else
> +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);

You repeat many times this logic, a helper to avoid this extra
indentation level with the if/else block is needed.

>  		read_loc += data_size1;
>  
> -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
> +		else
> +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>  		read_loc += oob_size1;
>  
> -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
> +		else
> +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>  		read_loc += data_size2;
>  
> -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
> +		else
> +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>  	}

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-14 15:53 ` Miquel Raynal
@ 2021-01-14 16:31   ` Manivannan Sadhasivam
  2021-01-14 16:42     ` Miquel Raynal
  2021-01-28 21:48   ` mdalam
  1 sibling, 1 reply; 10+ messages in thread
From: Manivannan Sadhasivam @ 2021-01-14 16:31 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: Md Sadre Alam, richard, vigneshr, boris.brezillon, linux-mtd,
	linux-kernel, sricharan

On Thu, Jan 14, 2021 at 04:53:25PM +0100, Miquel Raynal wrote:
> Hello,
> 
> Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
> 09:31:45 +0530:
> 
> > From QPIC version 2.0 onwards new register got added to
> 
>                                 a
> 
> > read last codeword. This change will update the same.
> 
>        the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>                       Please reword this sentence.
> 
> > For first three code word READ_LOCATION_n register will be
> > use.For last code word READ_LOCATION_LAST_CW_n register will be
> > use.
> 
> "For the first three codewords, READ_LOCATION_n registers will be used.
> The last codeword register will be accessed through
> READ_LOCATION_LAST_CW_n."
> 
> Also, please specify what these registers store.
> 
> > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>
> 
> Could someone please test this patch?
> 

This is on my TODO list. Will get back to it once I'm back from holidays
or sooner if I find some time in the middle.

Thanks,
Mani

> > ---
> > [V3]
> >  * Added else condition for last code word in update_rw_regs().
> >  drivers/mtd/nand/raw/qcom_nandc.c | 84 ++++++++++++++++++++++++++++++++-------
> >  1 file changed, 70 insertions(+), 14 deletions(-)
> > 
> > diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> > index 667e4bf..50ff6e3 100644
> > --- a/drivers/mtd/nand/raw/qcom_nandc.c
> > +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> > @@ -48,6 +48,10 @@
> >  #define	NAND_READ_LOCATION_1		0xf24
> >  #define	NAND_READ_LOCATION_2		0xf28
> >  #define	NAND_READ_LOCATION_3		0xf2c
> > +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
> > +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
> > +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
> > +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
> >  
> >  /* dummy register offsets, used by write_reg_dma */
> >  #define	NAND_DEV_CMD1_RESTORE		0xdead
> > @@ -187,6 +191,12 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_##reg,			\
> >  	      ((size) << READ_LOCATION_SIZE) |			\
> >  	      ((is_last) << READ_LOCATION_LAST))
> >  
> > +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
> > +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
> > +	      ((offset) << READ_LOCATION_OFFSET) |		\
> > +	      ((size) << READ_LOCATION_SIZE) |			\
> > +	      ((is_last) << READ_LOCATION_LAST))
> > +
> >  /*
> >   * Returns the actual register address for all NAND_DEV_ registers
> >   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
> > @@ -316,6 +326,10 @@ struct nandc_regs {
> >  	__le32 read_location1;
> >  	__le32 read_location2;
> >  	__le32 read_location3;
> > +	__le32 read_location_last0;
> > +	__le32 read_location_last1;
> > +	__le32 read_location_last2;
> > +	__le32 read_location_last3;
> >  
> >  	__le32 erased_cw_detect_cfg_clr;
> >  	__le32 erased_cw_detect_cfg_set;
> > @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
> >  		return &regs->read_location2;
> >  	case NAND_READ_LOCATION_3:
> >  		return &regs->read_location3;
> > +	case NAND_READ_LOCATION_LAST_CW_0:
> > +		return &regs->read_location_last0;
> > +	case NAND_READ_LOCATION_LAST_CW_1:
> > +		return &regs->read_location_last1;
> > +	case NAND_READ_LOCATION_LAST_CW_2:
> > +		return &regs->read_location_last2;
> > +	case NAND_READ_LOCATION_LAST_CW_3:
> > +		return &regs->read_location_last3;
> >  	default:
> >  		return NULL;
> >  	}
> > @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
> >  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
> >  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
> >  
> > -	if (read)
> > -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> > -				   host->cw_data : host->cw_size, 1);
> > +	if (read) {
> > +		if (nandc->props->qpic_v2)
> > +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
> > +					host->cw_data : host->cw_size, 1);
> > +		else
> > +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> > +					host->cw_data : host->cw_size, 1);
> > +	}
> >  }
> >  
> >  /*
> > @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
> >  static void
> >  config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
> >  {
> > -	if (nandc->props->is_bam)
> > +	if (nandc->props->is_bam) {
> > +		if (nandc->props->qpic_v2)
> > +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
> > +				      1, NAND_BAM_NEXT_SGL);
> >  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
> >  			      NAND_BAM_NEXT_SGL);
> > +	}
> >  
> >  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
> >  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> > @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
> >  	}
> >  
> >  	if (nandc->props->is_bam) {
> > -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
> > +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> > +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
> > +		else
> > +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
> 
> You repeat many times this logic, a helper to avoid this extra
> indentation level with the if/else block is needed.
> 
> >  		read_loc += data_size1;
> >  
> > -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
> > +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> > +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
> > +		else
> > +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
> >  		read_loc += oob_size1;
> >  
> > -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
> > +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> > +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
> > +		else
> > +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
> >  		read_loc += data_size2;
> >  
> > -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
> > +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> > +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
> > +		else
> > +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
> >  	}
> 
> Thanks,
> Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-14 16:31   ` Manivannan Sadhasivam
@ 2021-01-14 16:42     ` Miquel Raynal
  0 siblings, 0 replies; 10+ messages in thread
From: Miquel Raynal @ 2021-01-14 16:42 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: Md Sadre Alam, richard, vigneshr, boris.brezillon, linux-mtd,
	linux-kernel, sricharan

Hi Manivannan,

Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> wrote on Thu,
14 Jan 2021 22:01:54 +0530:

> On Thu, Jan 14, 2021 at 04:53:25PM +0100, Miquel Raynal wrote:
> > Hello,
> > 
> > Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
> > 09:31:45 +0530:
> >   
> > > From QPIC version 2.0 onwards new register got added to  
> > 
> >                                 a
> >   
> > > read last codeword. This change will update the same.  
> > 
> >        the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >                       Please reword this sentence.
> >   
> > > For first three code word READ_LOCATION_n register will be
> > > use.For last code word READ_LOCATION_LAST_CW_n register will be
> > > use.  
> > 
> > "For the first three codewords, READ_LOCATION_n registers will be used.
> > The last codeword register will be accessed through
> > READ_LOCATION_LAST_CW_n."
> > 
> > Also, please specify what these registers store.
> >   
> > > Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>  
> > 
> > Could someone please test this patch?
> >   
> 
> This is on my TODO list. Will get back to it once I'm back from holidays
> or sooner if I find some time in the middle.

No hurry, I believe this patch still needs a little bit of effort before
being ready for upstreaming.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-10  4:01 [PATCH V3] mtd: rawnand: qcom: update last code word register Md Sadre Alam
  2021-01-14 15:53 ` Miquel Raynal
@ 2021-01-28  7:52 ` Manivannan Sadhasivam
  2021-01-29  5:11   ` mdalam
  1 sibling, 1 reply; 10+ messages in thread
From: Manivannan Sadhasivam @ 2021-01-28  7:52 UTC (permalink / raw)
  To: Md Sadre Alam
  Cc: miquel.raynal, richard, vigneshr, boris.brezillon, linux-mtd,
	linux-kernel, sricharan

On Sun, Jan 10, 2021 at 09:31:45AM +0530, Md Sadre Alam wrote:
> From QPIC version 2.0 onwards new register got added to
> read last codeword. This change will update the same.
> 
> For first three code word READ_LOCATION_n register will be
> use.For last code word READ_LOCATION_LAST_CW_n register will be
> use.
> 
> Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>

I gave this patch a try on SDX55 board but not able to resolve an issue and
I think it is related to reading the last code word which this patch is trying
to address. For my patch on supporting QPIC v2 IP, I tested with SDX55-MTP board
and I never hit any issue. But on my new dev board (Telit FN980), there seems to
be an issue while populating the partitions and tracing down that bug lands me
in copy_last_cw() function.

The issue only happens while creating the 3rd partition on Telit board whose
size differs when compared with MTP. The board just reboots into QDL mode
whenever it tries to read the last code word.

Below is the snippet of partition layout:

Telit partitions:

[    1.082015] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
[    1.082702] 1: mibib offs=0x0000000a size=0x0000000a attr:0x000000ff
[    1.083488] 2: ico offs=0x00000014 size=0x00000014 attr:0x000000ff
[    1.084572] 3: efs2 offs=0x00000028 size=0x0000002c attr:0x000000ff
[    1.085316] 4: tz offs=0x00000054 size=0x00000007 attr:0x000000ff
[    1.086089] 5: tz_devcfg offs=0x0000005b size=0x00000004 attr:0x000000ff
....

MTP partitions:

[    1.573871] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
[    1.581139] 1: mibib offs=0x0000000a size=0x0000000a attr:0x000000ff
[    1.587362] 2: efs2 offs=0x00000014 size=0x0000002c attr:0x000000ff
[    1.593853] 3: tz offs=0x00000040 size=0x00000007 attr:0x000000ff
[    1.599860] 4: tz_devcfg offs=0x00000047 size=0x00000004 attr:0x000000ff
...

So until I figure this out, please keep this patch on hold!

Thanks,
Mani

> ---
> [V3]
>  * Added else condition for last code word in update_rw_regs().
>  drivers/mtd/nand/raw/qcom_nandc.c | 84 ++++++++++++++++++++++++++++++++-------
>  1 file changed, 70 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c b/drivers/mtd/nand/raw/qcom_nandc.c
> index 667e4bf..50ff6e3 100644
> --- a/drivers/mtd/nand/raw/qcom_nandc.c
> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
> @@ -48,6 +48,10 @@
>  #define	NAND_READ_LOCATION_1		0xf24
>  #define	NAND_READ_LOCATION_2		0xf28
>  #define	NAND_READ_LOCATION_3		0xf2c
> +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
> +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
> +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
> +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
>  
>  /* dummy register offsets, used by write_reg_dma */
>  #define	NAND_DEV_CMD1_RESTORE		0xdead
> @@ -187,6 +191,12 @@ nandc_set_reg(nandc, NAND_READ_LOCATION_##reg,			\
>  	      ((size) << READ_LOCATION_SIZE) |			\
>  	      ((is_last) << READ_LOCATION_LAST))
>  
> +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
> +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
> +	      ((offset) << READ_LOCATION_OFFSET) |		\
> +	      ((size) << READ_LOCATION_SIZE) |			\
> +	      ((is_last) << READ_LOCATION_LAST))
> +
>  /*
>   * Returns the actual register address for all NAND_DEV_ registers
>   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and NAND_DEV_CMD_VLD)
> @@ -316,6 +326,10 @@ struct nandc_regs {
>  	__le32 read_location1;
>  	__le32 read_location2;
>  	__le32 read_location3;
> +	__le32 read_location_last0;
> +	__le32 read_location_last1;
> +	__le32 read_location_last2;
> +	__le32 read_location_last3;
>  
>  	__le32 erased_cw_detect_cfg_clr;
>  	__le32 erased_cw_detect_cfg_set;
> @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct nandc_regs *regs, int offset)
>  		return &regs->read_location2;
>  	case NAND_READ_LOCATION_3:
>  		return &regs->read_location3;
> +	case NAND_READ_LOCATION_LAST_CW_0:
> +		return &regs->read_location_last0;
> +	case NAND_READ_LOCATION_LAST_CW_1:
> +		return &regs->read_location_last1;
> +	case NAND_READ_LOCATION_LAST_CW_2:
> +		return &regs->read_location_last2;
> +	case NAND_READ_LOCATION_LAST_CW_3:
> +		return &regs->read_location_last3;
>  	default:
>  		return NULL;
>  	}
> @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host *host, int num_cw, bool read)
>  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>  
> -	if (read)
> -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> -				   host->cw_data : host->cw_size, 1);
> +	if (read) {
> +		if (nandc->props->qpic_v2)
> +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
> +					host->cw_data : host->cw_size, 1);
> +		else
> +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
> +					host->cw_data : host->cw_size, 1);
> +	}
>  }
>  
>  /*
> @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct qcom_nand_controller *nandc)
>  static void
>  config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
>  {
> -	if (nandc->props->is_bam)
> +	if (nandc->props->is_bam) {
> +		if (nandc->props->qpic_v2)
> +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
> +				      1, NAND_BAM_NEXT_SGL);
>  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
>  			      NAND_BAM_NEXT_SGL);
> +	}
>  
>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
> @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, struct nand_chip *chip,
>  	}
>  
>  	if (nandc->props->is_bam) {
> -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
> +		else
> +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>  		read_loc += data_size1;
>  
> -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
> +		else
> +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>  		read_loc += oob_size1;
>  
> -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
> +		else
> +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>  		read_loc += data_size2;
>  
> -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
> +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
> +		else
> +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>  	}
>  
>  	config_nand_cw_read(nandc, false);
> @@ -1873,14 +1916,27 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 *data_buf,
>  
>  		if (nandc->props->is_bam) {
>  			if (data_buf && oob_buf) {
> -				nandc_set_read_loc(nandc, 0, 0, data_size, 0);
> -				nandc_set_read_loc(nandc, 1, data_size,
> -						   oob_size, 1);
> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1)) {
> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 0);
> +					nandc_set_read_loc_last(nandc, 1, data_size,
> +								oob_size, 1);
> +				} else {
> +					nandc_set_read_loc(nandc, 0, 0, data_size, 0);
> +					nandc_set_read_loc(nandc, 1, data_size,
> +							   oob_size, 1);
> +				}
>  			} else if (data_buf) {
> -				nandc_set_read_loc(nandc, 0, 0, data_size, 1);
> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 1);
> +				else
> +					nandc_set_read_loc(nandc, 0, 0, data_size, 1);
>  			} else {
> -				nandc_set_read_loc(nandc, 0, data_size,
> -						   oob_size, 1);
> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
> +					nandc_set_read_loc_last(nandc, 0, data_size,
> +								oob_size, 1);
> +				else
> +					nandc_set_read_loc(nandc, 0, data_size,
> +							   oob_size, 1);
>  			}
>  		}
>  
> -- 
> 2.7.4
> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-14 15:53 ` Miquel Raynal
  2021-01-14 16:31   ` Manivannan Sadhasivam
@ 2021-01-28 21:48   ` mdalam
  2021-01-28 22:11     ` Miquel Raynal
  1 sibling, 1 reply; 10+ messages in thread
From: mdalam @ 2021-01-28 21:48 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: manivannan.sadhasivam, richard, vigneshr, boris.brezillon,
	linux-mtd, linux-kernel, sricharan

On 2021-01-14 21:23, Miquel Raynal wrote:
> Hello,
> 
> Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
> 09:31:45 +0530:
> 
>> From QPIC version 2.0 onwards new register got added to
> 
>                                 a
> 
>> read last codeword. This change will update the same.
> 
>        the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>                       Please reword this sentence.

   Fixed this in V4 patch.
> 
>> For first three code word READ_LOCATION_n register will be
>> use.For last code word READ_LOCATION_LAST_CW_n register will be
>> use.
> 
> "For the first three codewords, READ_LOCATION_n registers will be used.
> The last codeword register will be accessed through
> READ_LOCATION_LAST_CW_n."
> 
> Also, please specify what these registers store.

   The location register is mainly use for reading controller
   buffer via BAM mode. The bits of the register 
"NAND_READ_LOCATION_LAST_CW_n, n=0..4"
   as follow:
   [9:0]-bits : (OFFSET) This bit defines the offset from the buffer base 
address to be picked up for DMA.
   [25:16]-bits: (SIZE) This bit of every register will define the size 
of the chunk for DMA.
   31-bit :      (LAST) If this bit is set, the controller takes the 
particular register to specify the last chunk
                       of data made available for DMA. This chunk is part 
of the internal buffer of the controller.

> 
>> Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>
> 
> Could someone please test this patch?

   I have tested this patch on IPQ5018 platform and its working fine.
> 
>> ---
>> [V3]
>>  * Added else condition for last code word in update_rw_regs().
>>  drivers/mtd/nand/raw/qcom_nandc.c | 84 
>> ++++++++++++++++++++++++++++++++-------
>>  1 file changed, 70 insertions(+), 14 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index 667e4bf..50ff6e3 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -48,6 +48,10 @@
>>  #define	NAND_READ_LOCATION_1		0xf24
>>  #define	NAND_READ_LOCATION_2		0xf28
>>  #define	NAND_READ_LOCATION_3		0xf2c
>> +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
>> +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
>> +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
>> +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
>> 
>>  /* dummy register offsets, used by write_reg_dma */
>>  #define	NAND_DEV_CMD1_RESTORE		0xdead
>> @@ -187,6 +191,12 @@ nandc_set_reg(nandc, 
>> NAND_READ_LOCATION_##reg,			\
>>  	      ((size) << READ_LOCATION_SIZE) |			\
>>  	      ((is_last) << READ_LOCATION_LAST))
>> 
>> +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
>> +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
>> +	      ((offset) << READ_LOCATION_OFFSET) |		\
>> +	      ((size) << READ_LOCATION_SIZE) |			\
>> +	      ((is_last) << READ_LOCATION_LAST))
>> +
>>  /*
>>   * Returns the actual register address for all NAND_DEV_ registers
>>   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and 
>> NAND_DEV_CMD_VLD)
>> @@ -316,6 +326,10 @@ struct nandc_regs {
>>  	__le32 read_location1;
>>  	__le32 read_location2;
>>  	__le32 read_location3;
>> +	__le32 read_location_last0;
>> +	__le32 read_location_last1;
>> +	__le32 read_location_last2;
>> +	__le32 read_location_last3;
>> 
>>  	__le32 erased_cw_detect_cfg_clr;
>>  	__le32 erased_cw_detect_cfg_set;
>> @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct 
>> nandc_regs *regs, int offset)
>>  		return &regs->read_location2;
>>  	case NAND_READ_LOCATION_3:
>>  		return &regs->read_location3;
>> +	case NAND_READ_LOCATION_LAST_CW_0:
>> +		return &regs->read_location_last0;
>> +	case NAND_READ_LOCATION_LAST_CW_1:
>> +		return &regs->read_location_last1;
>> +	case NAND_READ_LOCATION_LAST_CW_2:
>> +		return &regs->read_location_last2;
>> +	case NAND_READ_LOCATION_LAST_CW_3:
>> +		return &regs->read_location_last3;
>>  	default:
>>  		return NULL;
>>  	}
>> @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host 
>> *host, int num_cw, bool read)
>>  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>>  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>> 
>> -	if (read)
>> -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>> -				   host->cw_data : host->cw_size, 1);
>> +	if (read) {
>> +		if (nandc->props->qpic_v2)
>> +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
>> +					host->cw_data : host->cw_size, 1);
>> +		else
>> +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>> +					host->cw_data : host->cw_size, 1);
>> +	}
>>  }
>> 
>>  /*
>> @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct 
>> qcom_nand_controller *nandc)
>>  static void
>>  config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
>>  {
>> -	if (nandc->props->is_bam)
>> +	if (nandc->props->is_bam) {
>> +		if (nandc->props->qpic_v2)
>> +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
>> +				      1, NAND_BAM_NEXT_SGL);
>>  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
>>  			      NAND_BAM_NEXT_SGL);
>> +	}
>> 
>>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>>  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>> @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	}
>> 
>>  	if (nandc->props->is_bam) {
>> -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
> 
> You repeat many times this logic, a helper to avoid this extra
> indentation level with the if/else block is needed.

   Fixed this V4 patch.
> 
>>  		read_loc += data_size1;
>> 
>> -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>>  		read_loc += oob_size1;
>> 
>> -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>>  		read_loc += data_size2;
>> 
>> -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>>  	}
> 
> Thanks,
> Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-28 21:48   ` mdalam
@ 2021-01-28 22:11     ` Miquel Raynal
  2021-01-29  5:05       ` mdalam
  0 siblings, 1 reply; 10+ messages in thread
From: Miquel Raynal @ 2021-01-28 22:11 UTC (permalink / raw)
  To: mdalam
  Cc: manivannan.sadhasivam, richard, vigneshr, boris.brezillon,
	linux-mtd, linux-kernel, sricharan

Hello,

mdalam@codeaurora.org wrote on Fri, 29 Jan 2021 03:18:46 +0530:

> On 2021-01-14 21:23, Miquel Raynal wrote:
> > Hello,
> > 
> > Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
> > 09:31:45 +0530:
> >   
> >> From QPIC version 2.0 onwards new register got added to  
> > 
> >                                 a
> >   
> >> read last codeword. This change will update the same.  
> > 
> >        the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> >                       Please reword this sentence.  
> 
>    Fixed this in V4 patch.
> >   
> >> For first three code word READ_LOCATION_n register will be
> >> use.For last code word READ_LOCATION_LAST_CW_n register will be
> >> use.  
> > 
> > "For the first three codewords, READ_LOCATION_n registers will be used.
> > The last codeword register will be accessed through
> > READ_LOCATION_LAST_CW_n."
> > 
> > Also, please specify what these registers store.  
> 
>    The location register is mainly use for reading controller
>    buffer via BAM mode. The bits of the register "NAND_READ_LOCATION_LAST_CW_n, n=0..4"
>    as follow:

Perhaps what I do not understand is: when is this "last_cw" register
more useful than the previous set?

>    [9:0]-bits : (OFFSET) This bit defines the offset from the buffer base address to be picked up for DMA.
>    [25:16]-bits: (SIZE) This bit of every register will define the size of the chunk for DMA.
>    31-bit :      (LAST) If this bit is set, the controller takes the particular register to specify the last chunk
>                        of data made available for DMA. This chunk is part of the internal buffer of the controller.
> 
> >   

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-28 22:11     ` Miquel Raynal
@ 2021-01-29  5:05       ` mdalam
  0 siblings, 0 replies; 10+ messages in thread
From: mdalam @ 2021-01-29  5:05 UTC (permalink / raw)
  To: Miquel Raynal
  Cc: manivannan.sadhasivam, richard, vigneshr, boris.brezillon,
	linux-mtd, linux-kernel, sricharan

On 2021-01-29 03:41, Miquel Raynal wrote:
> Hello,
> 
> mdalam@codeaurora.org wrote on Fri, 29 Jan 2021 03:18:46 +0530:
> 
>> On 2021-01-14 21:23, Miquel Raynal wrote:
>> > Hello,
>> >
>> > Md Sadre Alam <mdalam@codeaurora.org> wrote on Sun, 10 Jan 2021
>> > 09:31:45 +0530:
>> >
>> >> From QPIC version 2.0 onwards new register got added to
>> >
>> >                                 a
>> >
>> >> read last codeword. This change will update the same.
>> >
>> >        the?           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>> >                       Please reword this sentence.
>> 
>>    Fixed this in V4 patch.
>> >
>> >> For first three code word READ_LOCATION_n register will be
>> >> use.For last code word READ_LOCATION_LAST_CW_n register will be
>> >> use.
>> >
>> > "For the first three codewords, READ_LOCATION_n registers will be used.
>> > The last codeword register will be accessed through
>> > READ_LOCATION_LAST_CW_n."
>> >
>> > Also, please specify what these registers store.
>> 
>>    The location register is mainly use for reading controller
>>    buffer via BAM mode. The bits of the register 
>> "NAND_READ_LOCATION_LAST_CW_n, n=0..4"
>>    as follow:
> 
> Perhaps what I do not understand is: when is this "last_cw" register
> more useful than the previous set?

   From QPIC Version 2.0 onwards it is mandatory to use 
"NAND_READ_LOCATION_LAST_CW_n, n=0..4"
   register to extract last code word data from controller buffer. Using 
register "NAND_READ_LOCATION_n, n=0..4"
   we can extract all code words except last code word.
> 
>>    [9:0]-bits : (OFFSET) This bit defines the offset from the buffer 
>> base address to be picked up for DMA.
>>    [25:16]-bits: (SIZE) This bit of every register will define the 
>> size of the chunk for DMA.
>>    31-bit :      (LAST) If this bit is set, the controller takes the 
>> particular register to specify the last chunk
>>                        of data made available for DMA. This chunk is 
>> part of the internal buffer of the controller.
>> 
>> >
> 
> Thanks,
> Miquèl

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-28  7:52 ` Manivannan Sadhasivam
@ 2021-01-29  5:11   ` mdalam
  2021-02-05 17:53     ` mdalam
  0 siblings, 1 reply; 10+ messages in thread
From: mdalam @ 2021-01-29  5:11 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: miquel.raynal, richard, vigneshr, boris.brezillon, linux-mtd,
	linux-kernel, sricharan

On 2021-01-28 13:22, Manivannan Sadhasivam wrote:
> On Sun, Jan 10, 2021 at 09:31:45AM +0530, Md Sadre Alam wrote:
>> From QPIC version 2.0 onwards new register got added to
>> read last codeword. This change will update the same.
>> 
>> For first three code word READ_LOCATION_n register will be
>> use.For last code word READ_LOCATION_LAST_CW_n register will be
>> use.
>> 
>> Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>
> 
> I gave this patch a try on SDX55 board but not able to resolve an issue 
> and
> I think it is related to reading the last code word which this patch is 
> trying
> to address. For my patch on supporting QPIC v2 IP, I tested with 
> SDX55-MTP board
> and I never hit any issue. But on my new dev board (Telit FN980), there 
> seems to
> be an issue while populating the partitions and tracing down that bug 
> lands me
> in copy_last_cw() function.
> 
> The issue only happens while creating the 3rd partition on Telit board 
> whose
> size differs when compared with MTP. The board just reboots into QDL 
> mode
> whenever it tries to read the last code word.
> 
> Below is the snippet of partition layout:
> 
> Telit partitions:
> 
> [    1.082015] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
> [    1.082702] 1: mibib offs=0x0000000a size=0x0000000a attr:0x000000ff
> [    1.083488] 2: ico offs=0x00000014 size=0x00000014 attr:0x000000ff
> [    1.084572] 3: efs2 offs=0x00000028 size=0x0000002c attr:0x000000ff
> [    1.085316] 4: tz offs=0x00000054 size=0x00000007 attr:0x000000ff
> [    1.086089] 5: tz_devcfg offs=0x0000005b size=0x00000004 
> attr:0x000000ff
> ....
> 
> MTP partitions:
> 
> [    1.573871] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
> [    1.581139] 1: mibib offs=0x0000000a size=0x0000000a attr:0x000000ff
> [    1.587362] 2: efs2 offs=0x00000014 size=0x0000002c attr:0x000000ff
> [    1.593853] 3: tz offs=0x00000040 size=0x00000007 attr:0x000000ff
> [    1.599860] 4: tz_devcfg offs=0x00000047 size=0x00000004 
> attr:0x000000ff
> ...
> 
> So until I figure this out, please keep this patch on hold!

   There was some corner case I missed in V3 patch. I have fixed this in 
V4 patch.
   I have done some tress testing as well with V4 patch on IPQ5018 
platform using "nand-utils"
   and "mtd_test.ko" , Now its working fine. Can you test with V4 patch 
once.
> 
> Thanks,
> Mani
> 
>> ---
>> [V3]
>>  * Added else condition for last code word in update_rw_regs().
>>  drivers/mtd/nand/raw/qcom_nandc.c | 84 
>> ++++++++++++++++++++++++++++++++-------
>>  1 file changed, 70 insertions(+), 14 deletions(-)
>> 
>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>> b/drivers/mtd/nand/raw/qcom_nandc.c
>> index 667e4bf..50ff6e3 100644
>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>> @@ -48,6 +48,10 @@
>>  #define	NAND_READ_LOCATION_1		0xf24
>>  #define	NAND_READ_LOCATION_2		0xf28
>>  #define	NAND_READ_LOCATION_3		0xf2c
>> +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
>> +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
>> +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
>> +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
>> 
>>  /* dummy register offsets, used by write_reg_dma */
>>  #define	NAND_DEV_CMD1_RESTORE		0xdead
>> @@ -187,6 +191,12 @@ nandc_set_reg(nandc, 
>> NAND_READ_LOCATION_##reg,			\
>>  	      ((size) << READ_LOCATION_SIZE) |			\
>>  	      ((is_last) << READ_LOCATION_LAST))
>> 
>> +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
>> +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
>> +	      ((offset) << READ_LOCATION_OFFSET) |		\
>> +	      ((size) << READ_LOCATION_SIZE) |			\
>> +	      ((is_last) << READ_LOCATION_LAST))
>> +
>>  /*
>>   * Returns the actual register address for all NAND_DEV_ registers
>>   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and 
>> NAND_DEV_CMD_VLD)
>> @@ -316,6 +326,10 @@ struct nandc_regs {
>>  	__le32 read_location1;
>>  	__le32 read_location2;
>>  	__le32 read_location3;
>> +	__le32 read_location_last0;
>> +	__le32 read_location_last1;
>> +	__le32 read_location_last2;
>> +	__le32 read_location_last3;
>> 
>>  	__le32 erased_cw_detect_cfg_clr;
>>  	__le32 erased_cw_detect_cfg_set;
>> @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct 
>> nandc_regs *regs, int offset)
>>  		return &regs->read_location2;
>>  	case NAND_READ_LOCATION_3:
>>  		return &regs->read_location3;
>> +	case NAND_READ_LOCATION_LAST_CW_0:
>> +		return &regs->read_location_last0;
>> +	case NAND_READ_LOCATION_LAST_CW_1:
>> +		return &regs->read_location_last1;
>> +	case NAND_READ_LOCATION_LAST_CW_2:
>> +		return &regs->read_location_last2;
>> +	case NAND_READ_LOCATION_LAST_CW_3:
>> +		return &regs->read_location_last3;
>>  	default:
>>  		return NULL;
>>  	}
>> @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host 
>> *host, int num_cw, bool read)
>>  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>>  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>> 
>> -	if (read)
>> -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>> -				   host->cw_data : host->cw_size, 1);
>> +	if (read) {
>> +		if (nandc->props->qpic_v2)
>> +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
>> +					host->cw_data : host->cw_size, 1);
>> +		else
>> +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>> +					host->cw_data : host->cw_size, 1);
>> +	}
>>  }
>> 
>>  /*
>> @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct 
>> qcom_nand_controller *nandc)
>>  static void
>>  config_nand_cw_read(struct qcom_nand_controller *nandc, bool use_ecc)
>>  {
>> -	if (nandc->props->is_bam)
>> +	if (nandc->props->is_bam) {
>> +		if (nandc->props->qpic_v2)
>> +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
>> +				      1, NAND_BAM_NEXT_SGL);
>>  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
>>  			      NAND_BAM_NEXT_SGL);
>> +	}
>> 
>>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>>  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>> @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>> struct nand_chip *chip,
>>  	}
>> 
>>  	if (nandc->props->is_bam) {
>> -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>>  		read_loc += data_size1;
>> 
>> -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>>  		read_loc += oob_size1;
>> 
>> -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>>  		read_loc += data_size2;
>> 
>> -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>> +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
>> +		else
>> +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>>  	}
>> 
>>  	config_nand_cw_read(nandc, false);
>> @@ -1873,14 +1916,27 @@ static int read_page_ecc(struct qcom_nand_host 
>> *host, u8 *data_buf,
>> 
>>  		if (nandc->props->is_bam) {
>>  			if (data_buf && oob_buf) {
>> -				nandc_set_read_loc(nandc, 0, 0, data_size, 0);
>> -				nandc_set_read_loc(nandc, 1, data_size,
>> -						   oob_size, 1);
>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1)) {
>> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 0);
>> +					nandc_set_read_loc_last(nandc, 1, data_size,
>> +								oob_size, 1);
>> +				} else {
>> +					nandc_set_read_loc(nandc, 0, 0, data_size, 0);
>> +					nandc_set_read_loc(nandc, 1, data_size,
>> +							   oob_size, 1);
>> +				}
>>  			} else if (data_buf) {
>> -				nandc_set_read_loc(nandc, 0, 0, data_size, 1);
>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
>> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 1);
>> +				else
>> +					nandc_set_read_loc(nandc, 0, 0, data_size, 1);
>>  			} else {
>> -				nandc_set_read_loc(nandc, 0, data_size,
>> -						   oob_size, 1);
>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
>> +					nandc_set_read_loc_last(nandc, 0, data_size,
>> +								oob_size, 1);
>> +				else
>> +					nandc_set_read_loc(nandc, 0, data_size,
>> +							   oob_size, 1);
>>  			}
>>  		}
>> 
>> --
>> 2.7.4
>> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH V3] mtd: rawnand: qcom: update last code word register
  2021-01-29  5:11   ` mdalam
@ 2021-02-05 17:53     ` mdalam
  0 siblings, 0 replies; 10+ messages in thread
From: mdalam @ 2021-02-05 17:53 UTC (permalink / raw)
  To: Manivannan Sadhasivam
  Cc: miquel.raynal, richard, vigneshr, boris.brezillon, linux-mtd,
	linux-kernel, sricharan, mdalam=codeaurora.org

On 2021-01-29 10:41, mdalam@codeaurora.org wrote:
> On 2021-01-28 13:22, Manivannan Sadhasivam wrote:
>> On Sun, Jan 10, 2021 at 09:31:45AM +0530, Md Sadre Alam wrote:
>>> From QPIC version 2.0 onwards new register got added to
>>> read last codeword. This change will update the same.
>>> 
>>> For first three code word READ_LOCATION_n register will be
>>> use.For last code word READ_LOCATION_LAST_CW_n register will be
>>> use.
>>> 
>>> Signed-off-by: Md Sadre Alam <mdalam@codeaurora.org>
>> 
>> I gave this patch a try on SDX55 board but not able to resolve an 
>> issue and
>> I think it is related to reading the last code word which this patch 
>> is trying
>> to address. For my patch on supporting QPIC v2 IP, I tested with 
>> SDX55-MTP board
>> and I never hit any issue. But on my new dev board (Telit FN980), 
>> there seems to
>> be an issue while populating the partitions and tracing down that bug 
>> lands me
>> in copy_last_cw() function.
>> 
>> The issue only happens while creating the 3rd partition on Telit board 
>> whose
>> size differs when compared with MTP. The board just reboots into QDL 
>> mode
>> whenever it tries to read the last code word.
>> 
>> Below is the snippet of partition layout:
>> 
>> Telit partitions:
>> 
>> [    1.082015] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
>> [    1.082702] 1: mibib offs=0x0000000a size=0x0000000a 
>> attr:0x000000ff
>> [    1.083488] 2: ico offs=0x00000014 size=0x00000014 attr:0x000000ff
>> [    1.084572] 3: efs2 offs=0x00000028 size=0x0000002c attr:0x000000ff
>> [    1.085316] 4: tz offs=0x00000054 size=0x00000007 attr:0x000000ff
>> [    1.086089] 5: tz_devcfg offs=0x0000005b size=0x00000004 
>> attr:0x000000ff
>> ....
>> 
>> MTP partitions:
>> 
>> [    1.573871] 0: sbl offs=0x00000000 size=0x0000000a attr:0x000000ff
>> [    1.581139] 1: mibib offs=0x0000000a size=0x0000000a 
>> attr:0x000000ff
>> [    1.587362] 2: efs2 offs=0x00000014 size=0x0000002c attr:0x000000ff
>> [    1.593853] 3: tz offs=0x00000040 size=0x00000007 attr:0x000000ff
>> [    1.599860] 4: tz_devcfg offs=0x00000047 size=0x00000004 
>> attr:0x000000ff
>> ...
>> 
>> So until I figure this out, please keep this patch on hold!
> 
>   There was some corner case I missed in V3 patch. I have fixed this
> in V4 patch.
>   I have done some tress testing as well with V4 patch on IPQ5018
> platform using "nand-utils"
>   and "mtd_test.ko" , Now its working fine. Can you test with V4 patch 
> once.

    ping! Do you need some more info for the V4 patch ?
>> 
>> Thanks,
>> Mani
>> 
>>> ---
>>> [V3]
>>>  * Added else condition for last code word in update_rw_regs().
>>>  drivers/mtd/nand/raw/qcom_nandc.c | 84 
>>> ++++++++++++++++++++++++++++++++-------
>>>  1 file changed, 70 insertions(+), 14 deletions(-)
>>> 
>>> diff --git a/drivers/mtd/nand/raw/qcom_nandc.c 
>>> b/drivers/mtd/nand/raw/qcom_nandc.c
>>> index 667e4bf..50ff6e3 100644
>>> --- a/drivers/mtd/nand/raw/qcom_nandc.c
>>> +++ b/drivers/mtd/nand/raw/qcom_nandc.c
>>> @@ -48,6 +48,10 @@
>>>  #define	NAND_READ_LOCATION_1		0xf24
>>>  #define	NAND_READ_LOCATION_2		0xf28
>>>  #define	NAND_READ_LOCATION_3		0xf2c
>>> +#define	NAND_READ_LOCATION_LAST_CW_0	0xf40
>>> +#define	NAND_READ_LOCATION_LAST_CW_1	0xf44
>>> +#define	NAND_READ_LOCATION_LAST_CW_2	0xf48
>>> +#define	NAND_READ_LOCATION_LAST_CW_3	0xf4c
>>> 
>>>  /* dummy register offsets, used by write_reg_dma */
>>>  #define	NAND_DEV_CMD1_RESTORE		0xdead
>>> @@ -187,6 +191,12 @@ nandc_set_reg(nandc, 
>>> NAND_READ_LOCATION_##reg,			\
>>>  	      ((size) << READ_LOCATION_SIZE) |			\
>>>  	      ((is_last) << READ_LOCATION_LAST))
>>> 
>>> +#define nandc_set_read_loc_last(nandc, reg, offset, size, is_last)	\
>>> +nandc_set_reg(nandc, NAND_READ_LOCATION_LAST_CW_##reg,			\
>>> +	      ((offset) << READ_LOCATION_OFFSET) |		\
>>> +	      ((size) << READ_LOCATION_SIZE) |			\
>>> +	      ((is_last) << READ_LOCATION_LAST))
>>> +
>>>  /*
>>>   * Returns the actual register address for all NAND_DEV_ registers
>>>   * (i.e. NAND_DEV_CMD0, NAND_DEV_CMD1, NAND_DEV_CMD2 and 
>>> NAND_DEV_CMD_VLD)
>>> @@ -316,6 +326,10 @@ struct nandc_regs {
>>>  	__le32 read_location1;
>>>  	__le32 read_location2;
>>>  	__le32 read_location3;
>>> +	__le32 read_location_last0;
>>> +	__le32 read_location_last1;
>>> +	__le32 read_location_last2;
>>> +	__le32 read_location_last3;
>>> 
>>>  	__le32 erased_cw_detect_cfg_clr;
>>>  	__le32 erased_cw_detect_cfg_set;
>>> @@ -644,6 +658,14 @@ static __le32 *offset_to_nandc_reg(struct 
>>> nandc_regs *regs, int offset)
>>>  		return &regs->read_location2;
>>>  	case NAND_READ_LOCATION_3:
>>>  		return &regs->read_location3;
>>> +	case NAND_READ_LOCATION_LAST_CW_0:
>>> +		return &regs->read_location_last0;
>>> +	case NAND_READ_LOCATION_LAST_CW_1:
>>> +		return &regs->read_location_last1;
>>> +	case NAND_READ_LOCATION_LAST_CW_2:
>>> +		return &regs->read_location_last2;
>>> +	case NAND_READ_LOCATION_LAST_CW_3:
>>> +		return &regs->read_location_last3;
>>>  	default:
>>>  		return NULL;
>>>  	}
>>> @@ -719,9 +741,14 @@ static void update_rw_regs(struct qcom_nand_host 
>>> *host, int num_cw, bool read)
>>>  	nandc_set_reg(nandc, NAND_READ_STATUS, host->clrreadstatus);
>>>  	nandc_set_reg(nandc, NAND_EXEC_CMD, 1);
>>> 
>>> -	if (read)
>>> -		nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>>> -				   host->cw_data : host->cw_size, 1);
>>> +	if (read) {
>>> +		if (nandc->props->qpic_v2)
>>> +			nandc_set_read_loc_last(nandc, 0, 0, host->use_ecc ?
>>> +					host->cw_data : host->cw_size, 1);
>>> +		else
>>> +			nandc_set_read_loc(nandc, 0, 0, host->use_ecc ?
>>> +					host->cw_data : host->cw_size, 1);
>>> +	}
>>>  }
>>> 
>>>  /*
>>> @@ -1096,9 +1123,13 @@ static void config_nand_page_read(struct 
>>> qcom_nand_controller *nandc)
>>>  static void
>>>  config_nand_cw_read(struct qcom_nand_controller *nandc, bool 
>>> use_ecc)
>>>  {
>>> -	if (nandc->props->is_bam)
>>> +	if (nandc->props->is_bam) {
>>> +		if (nandc->props->qpic_v2)
>>> +			write_reg_dma(nandc, NAND_READ_LOCATION_LAST_CW_0,
>>> +				      1, NAND_BAM_NEXT_SGL);
>>>  		write_reg_dma(nandc, NAND_READ_LOCATION_0, 4,
>>>  			      NAND_BAM_NEXT_SGL);
>>> +	}
>>> 
>>>  	write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
>>>  	write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
>>> @@ -1633,16 +1664,28 @@ qcom_nandc_read_cw_raw(struct mtd_info *mtd, 
>>> struct nand_chip *chip,
>>>  	}
>>> 
>>>  	if (nandc->props->is_bam) {
>>> -		nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>>> +			nandc_set_read_loc_last(nandc, 0, read_loc, data_size1, 0);
>>> +		else
>>> +			nandc_set_read_loc(nandc, 0, read_loc, data_size1, 0);
>>>  		read_loc += data_size1;
>>> 
>>> -		nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>>> +			nandc_set_read_loc_last(nandc, 1, read_loc, oob_size1, 0);
>>> +		else
>>> +			nandc_set_read_loc(nandc, 1, read_loc, oob_size1, 0);
>>>  		read_loc += oob_size1;
>>> 
>>> -		nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>>> +			nandc_set_read_loc_last(nandc, 2, read_loc, data_size2, 0);
>>> +		else
>>> +			nandc_set_read_loc(nandc, 2, read_loc, data_size2, 0);
>>>  		read_loc += data_size2;
>>> 
>>> -		nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>>> +		if (nandc->props->qpic_v2 && cw == (ecc->steps - 1))
>>> +			nandc_set_read_loc_last(nandc, 3, read_loc, oob_size2, 0);
>>> +		else
>>> +			nandc_set_read_loc(nandc, 3, read_loc, oob_size2, 1);
>>>  	}
>>> 
>>>  	config_nand_cw_read(nandc, false);
>>> @@ -1873,14 +1916,27 @@ static int read_page_ecc(struct 
>>> qcom_nand_host *host, u8 *data_buf,
>>> 
>>>  		if (nandc->props->is_bam) {
>>>  			if (data_buf && oob_buf) {
>>> -				nandc_set_read_loc(nandc, 0, 0, data_size, 0);
>>> -				nandc_set_read_loc(nandc, 1, data_size,
>>> -						   oob_size, 1);
>>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1)) {
>>> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 0);
>>> +					nandc_set_read_loc_last(nandc, 1, data_size,
>>> +								oob_size, 1);
>>> +				} else {
>>> +					nandc_set_read_loc(nandc, 0, 0, data_size, 0);
>>> +					nandc_set_read_loc(nandc, 1, data_size,
>>> +							   oob_size, 1);
>>> +				}
>>>  			} else if (data_buf) {
>>> -				nandc_set_read_loc(nandc, 0, 0, data_size, 1);
>>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
>>> +					nandc_set_read_loc_last(nandc, 0, 0, data_size, 1);
>>> +				else
>>> +					nandc_set_read_loc(nandc, 0, 0, data_size, 1);
>>>  			} else {
>>> -				nandc_set_read_loc(nandc, 0, data_size,
>>> -						   oob_size, 1);
>>> +				if (nandc->props->qpic_v2 && i == (ecc->steps - 1))
>>> +					nandc_set_read_loc_last(nandc, 0, data_size,
>>> +								oob_size, 1);
>>> +				else
>>> +					nandc_set_read_loc(nandc, 0, data_size,
>>> +							   oob_size, 1);
>>>  			}
>>>  		}
>>> 
>>> --
>>> 2.7.4
>>> 

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2021-02-05 18:54 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-01-10  4:01 [PATCH V3] mtd: rawnand: qcom: update last code word register Md Sadre Alam
2021-01-14 15:53 ` Miquel Raynal
2021-01-14 16:31   ` Manivannan Sadhasivam
2021-01-14 16:42     ` Miquel Raynal
2021-01-28 21:48   ` mdalam
2021-01-28 22:11     ` Miquel Raynal
2021-01-29  5:05       ` mdalam
2021-01-28  7:52 ` Manivannan Sadhasivam
2021-01-29  5:11   ` mdalam
2021-02-05 17:53     ` mdalam

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).