Re: [PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-16 Thread Abhishek Sahu

On 2017-08-16 09:48, Archit Taneja wrote:

On 08/11/2017 05:09 PM, Abhishek Sahu wrote:

The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
All write request will modify the data in internal buffer and
this buffer will be flushed to NAND device once EOT flag is set.
So for all the write requests in single codeword, the EOT should
be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
  drivers/mtd/nand/qcom_nandc.c | 122 
--

  1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c 
b/drivers/mtd/nand/qcom_nandc.c

index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
  #define QPIC_PER_CW_CMD_SGL   32
  #define QPIC_PER_CW_DATA_SGL  8
  +/* Flags used for BAM DMA desc preparation*/


 We can remove BAM from here since later on
 we will pass flag for erase code word and it will
 be used by ADM also.


+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl 
*/

+#define NAND_BAM_NEXT_SGL  BIT(2)
+
  /*
   * This data type corresponds to the BAM transaction which will be 
used for all

   * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct 
qcom_nand_controller *nandc, bool read,

   * @num_regs: number of registers to read


Minor comment: the read_reg_dma/write_reg/read_data/write_data_dma
funcs add a new arg, so it
would be nice to update the comment describing the function and its
arguments. It would also


 Thanks. I will update the comment to include this new arg.


be nice to mention that the flags are presently used only for
controllers using BAM.



 We can use this flag for ADM also so I will make the
 comment generic.


With that,

Reviewed-by: Archit Taneja 

Thanks,
Archit


   */
  static int read_reg_dma(struct qcom_nand_controller *nandc, int 
first,

-   int num_regs)
+   int num_regs, unsigned int flags)
  {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct 
qcom_nand_controller *nandc, int first,

   * @num_regs: number of registers to write
   */
  static int write_reg_dma(struct qcom_nand_controller *nandc, int 
first,

-int num_regs)
+int num_regs, unsigned int flags)
  {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct 
qcom_nand_controller *nandc, int first,

if (first == NAND_FLASH_CMD)
flow_control = true;
  + if (first == NAND_EXEC_CMD)
+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
  @@ -788,7 +799,7 @@ static int write_reg_dma(struct 
qcom_nand_controller *nandc, int first,

   * @size: DMA transaction size in bytes
   */
  static int read_data_dma(struct qcom_nand_controller *nandc, int 
reg_off,

-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
  }
@@ -802,7 +813,7 @@ static int read_data_dma(struct 
qcom_nand_controller *nandc, int reg_off,

   * @size: DMA transaction size in bytes
   */
  static int write_data_dma(struct qcom_nand_controller *nandc, int 
reg_off,

- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
  {
  	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, 
false);

  }
@@ -813,9 +824,9 @@ static int write_data_dma(struct 
qcom_nand_controller *nandc, int reg_off,

   */
  static void config_nand_page_read(struct qcom_nand_controller 
*nandc)

  {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
  }
/*
@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)

   */
  static void 

Re: [PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-16 Thread Abhishek Sahu

On 2017-08-16 09:48, Archit Taneja wrote:

On 08/11/2017 05:09 PM, Abhishek Sahu wrote:

The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
All write request will modify the data in internal buffer and
this buffer will be flushed to NAND device once EOT flag is set.
So for all the write requests in single codeword, the EOT should
be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
  drivers/mtd/nand/qcom_nandc.c | 122 
--

  1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c 
b/drivers/mtd/nand/qcom_nandc.c

index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
  #define QPIC_PER_CW_CMD_SGL   32
  #define QPIC_PER_CW_DATA_SGL  8
  +/* Flags used for BAM DMA desc preparation*/


 We can remove BAM from here since later on
 we will pass flag for erase code word and it will
 be used by ADM also.


+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl 
*/

+#define NAND_BAM_NEXT_SGL  BIT(2)
+
  /*
   * This data type corresponds to the BAM transaction which will be 
used for all

   * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct 
qcom_nand_controller *nandc, bool read,

   * @num_regs: number of registers to read


Minor comment: the read_reg_dma/write_reg/read_data/write_data_dma
funcs add a new arg, so it
would be nice to update the comment describing the function and its
arguments. It would also


 Thanks. I will update the comment to include this new arg.


be nice to mention that the flags are presently used only for
controllers using BAM.



 We can use this flag for ADM also so I will make the
 comment generic.


With that,

Reviewed-by: Archit Taneja 

Thanks,
Archit


   */
  static int read_reg_dma(struct qcom_nand_controller *nandc, int 
first,

-   int num_regs)
+   int num_regs, unsigned int flags)
  {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct 
qcom_nand_controller *nandc, int first,

   * @num_regs: number of registers to write
   */
  static int write_reg_dma(struct qcom_nand_controller *nandc, int 
first,

-int num_regs)
+int num_regs, unsigned int flags)
  {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct 
qcom_nand_controller *nandc, int first,

if (first == NAND_FLASH_CMD)
flow_control = true;
  + if (first == NAND_EXEC_CMD)
+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
  @@ -788,7 +799,7 @@ static int write_reg_dma(struct 
qcom_nand_controller *nandc, int first,

   * @size: DMA transaction size in bytes
   */
  static int read_data_dma(struct qcom_nand_controller *nandc, int 
reg_off,

-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
  }
@@ -802,7 +813,7 @@ static int read_data_dma(struct 
qcom_nand_controller *nandc, int reg_off,

   * @size: DMA transaction size in bytes
   */
  static int write_data_dma(struct qcom_nand_controller *nandc, int 
reg_off,

- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
  {
  	return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, 
false);

  }
@@ -813,9 +824,9 @@ static int write_data_dma(struct 
qcom_nand_controller *nandc, int reg_off,

   */
  static void config_nand_page_read(struct qcom_nand_controller 
*nandc)

  {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
  }
/*
@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)

   */
  static void config_nand_cw_read(struct qcom_nand_controller 

Re: [PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-15 Thread Archit Taneja



On 08/11/2017 05:09 PM, Abhishek Sahu wrote:

The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
All write request will modify the data in internal buffer and
this buffer will be flushed to NAND device once EOT flag is set.
So for all the write requests in single codeword, the EOT should
be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
  drivers/mtd/nand/qcom_nandc.c | 122 --
  1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
  #define QPIC_PER_CW_CMD_SGL   32
  #define QPIC_PER_CW_DATA_SGL  8
  
+/* Flags used for BAM DMA desc preparation*/

+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl */
+#define NAND_BAM_NEXT_SGL  BIT(2)
+
  /*
   * This data type corresponds to the BAM transaction which will be used for 
all
   * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller 
*nandc, bool read,
   * @num_regs: number of registers to read


Minor comment: the read_reg_dma/write_reg/read_data/write_data_dma funcs add a 
new arg, so it
would be nice to update the comment describing the function and its arguments. 
It would also
be nice to mention that the flags are presently used only for controllers using 
BAM.

With that,

Reviewed-by: Archit Taneja 

Thanks,
Archit


   */
  static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-   int num_regs)
+   int num_regs, unsigned int flags)
  {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, 
int first,
   * @num_regs: number of registers to write
   */
  static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-int num_regs)
+int num_regs, unsigned int flags)
  {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
if (first == NAND_FLASH_CMD)
flow_control = true;
  
+	if (first == NAND_EXEC_CMD)

+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
  
@@ -788,7 +799,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,

   * @size: DMA transaction size in bytes
   */
  static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
  }
@@ -802,7 +813,7 @@ static int read_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
   * @size: DMA transaction size in bytes
   */
  static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
  }
@@ -813,9 +824,9 @@ static int write_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
   */
  static void config_nand_page_read(struct qcom_nand_controller *nandc)
  {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
  }
  
  /*

@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)
   */
  static void config_nand_cw_read(struct qcom_nand_controller *nandc)
  {
-   write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-   write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+   write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+   write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
  
-	read_reg_dma(nandc, 

Re: [PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-15 Thread Archit Taneja



On 08/11/2017 05:09 PM, Abhishek Sahu wrote:

The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
All write request will modify the data in internal buffer and
this buffer will be flushed to NAND device once EOT flag is set.
So for all the write requests in single codeword, the EOT should
be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
  drivers/mtd/nand/qcom_nandc.c | 122 --
  1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
  #define QPIC_PER_CW_CMD_SGL   32
  #define QPIC_PER_CW_DATA_SGL  8
  
+/* Flags used for BAM DMA desc preparation*/

+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl */
+#define NAND_BAM_NEXT_SGL  BIT(2)
+
  /*
   * This data type corresponds to the BAM transaction which will be used for 
all
   * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller 
*nandc, bool read,
   * @num_regs: number of registers to read


Minor comment: the read_reg_dma/write_reg/read_data/write_data_dma funcs add a 
new arg, so it
would be nice to update the comment describing the function and its arguments. 
It would also
be nice to mention that the flags are presently used only for controllers using 
BAM.

With that,

Reviewed-by: Archit Taneja 

Thanks,
Archit


   */
  static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-   int num_regs)
+   int num_regs, unsigned int flags)
  {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, 
int first,
   * @num_regs: number of registers to write
   */
  static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-int num_regs)
+int num_regs, unsigned int flags)
  {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
if (first == NAND_FLASH_CMD)
flow_control = true;
  
+	if (first == NAND_EXEC_CMD)

+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
  
@@ -788,7 +799,7 @@ static int write_reg_dma(struct qcom_nand_controller *nandc, int first,

   * @size: DMA transaction size in bytes
   */
  static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
  }
@@ -802,7 +813,7 @@ static int read_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
   * @size: DMA transaction size in bytes
   */
  static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
  {
return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
  }
@@ -813,9 +824,9 @@ static int write_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
   */
  static void config_nand_page_read(struct qcom_nand_controller *nandc)
  {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
  }
  
  /*

@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)
   */
  static void config_nand_cw_read(struct qcom_nand_controller *nandc)
  {
-   write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-   write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+   write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+   write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
  
-	read_reg_dma(nandc, NAND_FLASH_STATUS, 2);

-   read_reg_dma(nandc, 

[PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-11 Thread Abhishek Sahu
The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
   separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
   DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
   All write request will modify the data in internal buffer and
   this buffer will be flushed to NAND device once EOT flag is set.
   So for all the write requests in single codeword, the EOT should
   be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
 drivers/mtd/nand/qcom_nandc.c | 122 --
 1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
 #define QPIC_PER_CW_CMD_SGL32
 #define QPIC_PER_CW_DATA_SGL   8
 
+/* Flags used for BAM DMA desc preparation*/
+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl */
+#define NAND_BAM_NEXT_SGL  BIT(2)
+
 /*
  * This data type corresponds to the BAM transaction which will be used for all
  * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller 
*nandc, bool read,
  * @num_regs:  number of registers to read
  */
 static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-   int num_regs)
+   int num_regs, unsigned int flags)
 {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, 
int first,
  * @num_regs:  number of registers to write
  */
 static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-int num_regs)
+int num_regs, unsigned int flags)
 {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
if (first == NAND_FLASH_CMD)
flow_control = true;
 
+   if (first == NAND_EXEC_CMD)
+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
 
@@ -788,7 +799,7 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
  * @size:  DMA transaction size in bytes
  */
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
 {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
@@ -802,7 +813,7 @@ static int read_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
  * @size:  DMA transaction size in bytes
  */
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
 {
return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
@@ -813,9 +824,9 @@ static int write_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
  */
 static void config_nand_page_read(struct qcom_nand_controller *nandc)
 {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
 }
 
 /*
@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)
  */
 static void config_nand_cw_read(struct qcom_nand_controller *nandc)
 {
-   write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-   write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+   write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+   write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-   read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
-   read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
+   read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
+   read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -847,9 +859,10 @@ static void config_nand_single_cw_page_read(struct 
qcom_nand_controller *nandc)
  */
 static void config_nand_page_write(struct qcom_nand_controller *nandc)
 {
-   

[PATCH v4 08/20] mtd: nand: qcom: support for passing flags in transfer functions

2017-08-11 Thread Abhishek Sahu
The BAM has multiple flags to control the transfer. This patch
adds flags parameter in register and data transfer functions and
modifies all these functions call with appropriate flags using
following rule

1. Read and write can’t go in single command descriptor so
   separate SGL should be used.
2. For some of the requests, NWD flag should be set in BAM
   DMA descriptor.
3. For Data write, the BAM has internal buffer for each codeword.
   All write request will modify the data in internal buffer and
   this buffer will be flushed to NAND device once EOT flag is set.
   So for all the write requests in single codeword, the EOT should
   be cleared for all tx data descriptors except the last one.

Signed-off-by: Abhishek Sahu 
---
 drivers/mtd/nand/qcom_nandc.c | 122 --
 1 file changed, 70 insertions(+), 52 deletions(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index f52a692..d9c8a6b 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -180,6 +180,14 @@
 #define QPIC_PER_CW_CMD_SGL32
 #define QPIC_PER_CW_DATA_SGL   8
 
+/* Flags used for BAM DMA desc preparation*/
+/* Don't set the EOT in current tx sgl */
+#define NAND_BAM_NO_EOTBIT(0)
+/* Set the NWD flag in current sgl */
+#define NAND_BAM_NWD   BIT(1)
+/* Finish writing in the current sgl and start writing in another sgl */
+#define NAND_BAM_NEXT_SGL  BIT(2)
+
 /*
  * This data type corresponds to the BAM transaction which will be used for all
  * NAND transfers.
@@ -731,7 +739,7 @@ static int prep_adm_dma_desc(struct qcom_nand_controller 
*nandc, bool read,
  * @num_regs:  number of registers to read
  */
 static int read_reg_dma(struct qcom_nand_controller *nandc, int first,
-   int num_regs)
+   int num_regs, unsigned int flags)
 {
bool flow_control = false;
void *vaddr;
@@ -755,7 +763,7 @@ static int read_reg_dma(struct qcom_nand_controller *nandc, 
int first,
  * @num_regs:  number of registers to write
  */
 static int write_reg_dma(struct qcom_nand_controller *nandc, int first,
-int num_regs)
+int num_regs, unsigned int flags)
 {
bool flow_control = false;
struct nandc_regs *regs = nandc->regs;
@@ -767,6 +775,9 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
if (first == NAND_FLASH_CMD)
flow_control = true;
 
+   if (first == NAND_EXEC_CMD)
+   flags |= NAND_BAM_NWD;
+
if (first == NAND_DEV_CMD1_RESTORE)
first = NAND_DEV_CMD1;
 
@@ -788,7 +799,7 @@ static int write_reg_dma(struct qcom_nand_controller 
*nandc, int first,
  * @size:  DMA transaction size in bytes
  */
 static int read_data_dma(struct qcom_nand_controller *nandc, int reg_off,
-const u8 *vaddr, int size)
+const u8 *vaddr, int size, unsigned int flags)
 {
return prep_adm_dma_desc(nandc, true, reg_off, vaddr, size, false);
 }
@@ -802,7 +813,7 @@ static int read_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
  * @size:  DMA transaction size in bytes
  */
 static int write_data_dma(struct qcom_nand_controller *nandc, int reg_off,
- const u8 *vaddr, int size)
+ const u8 *vaddr, int size, unsigned int flags)
 {
return prep_adm_dma_desc(nandc, false, reg_off, vaddr, size, false);
 }
@@ -813,9 +824,9 @@ static int write_data_dma(struct qcom_nand_controller 
*nandc, int reg_off,
  */
 static void config_nand_page_read(struct qcom_nand_controller *nandc)
 {
-   write_reg_dma(nandc, NAND_ADDR0, 2);
-   write_reg_dma(nandc, NAND_DEV0_CFG0, 3);
-   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1);
+   write_reg_dma(nandc, NAND_ADDR0, 2, 0);
+   write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+   write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
 }
 
 /*
@@ -824,11 +835,12 @@ static void config_nand_page_read(struct 
qcom_nand_controller *nandc)
  */
 static void config_nand_cw_read(struct qcom_nand_controller *nandc)
 {
-   write_reg_dma(nandc, NAND_FLASH_CMD, 1);
-   write_reg_dma(nandc, NAND_EXEC_CMD, 1);
+   write_reg_dma(nandc, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL);
+   write_reg_dma(nandc, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL);
 
-   read_reg_dma(nandc, NAND_FLASH_STATUS, 2);
-   read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1);
+   read_reg_dma(nandc, NAND_FLASH_STATUS, 2, 0);
+   read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+NAND_BAM_NEXT_SGL);
 }
 
 /*
@@ -847,9 +859,10 @@ static void config_nand_single_cw_page_read(struct 
qcom_nand_controller *nandc)
  */
 static void config_nand_page_write(struct qcom_nand_controller *nandc)
 {
-   write_reg_dma(nandc,