Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-17 Thread Abhishek Sahu

On 2017-07-10 19:48, Sricharan R wrote:

On 6/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
   will be used only by BAM DMA and it will form the DMA descriptors
   containing command elements.

2. Add the data descriptor preparation function which will be used
   only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
   descriptor formation function.

5. Enable the BAM in NAND_CTRL.



Should this patch be patch #8 and then add other support ?



 The original plan was to add other these function and
 finally enable the operation but it was generating the
 unused functions warnings that's why I need to club all
 these together in the last patch. anyway, I will check
 once again and will reorder if possible.


Regards,
 Sricharan



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

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

index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
 #defineFETCH_ID0xb
 #defineRESET_DEVICE0xd

+/* NAND_CTRL bits */
+#defineBAM_MODE_EN BIT(0)
 /*
  * the NAND controller performs reads/writes with ECC in 516 byte 
chunks.

  * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
  */
 #define NAND_ERASED_CW_SET (0x0008)

+/* Returns the dma address for reg read buffer */
+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
 #define QPIC_PER_CW_MAX_CMD_ELEMENTS   (32)
 #define QPIC_PER_CW_MAX_CMD_SGL(32)
 #define QPIC_PER_CW_MAX_DATA_SGL   (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
  * controller
  * @dev:   parent device
  * @base:  MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
  * @core_clk:  controller clock
  * @aon_clk:   another controller clock
  *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;

void __iomem *base;
+   phys_addr_t base_phys;
dma_addr_t base_dma;

struct clk *core_clk;
@@ -467,6 +479,29 @@ static void free_bam_transaction(struct
qcom_nand_controller *nandc)
return bam_txn;
 }

+/* Clears the BAM transaction indexes */
+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
 static inline struct qcom_nand_host *to_qcom_nand_host(struct 
nand_chip

*chip)
 {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct
qcom_nand_controller *nandc,
return 0;
 }

+/*
+ * Prepares the command descriptor for BAM DMA which will be used for
NAND
+ * register reads and writes. The command descriptor requires the 
command
+ * to be formed in command element type so this function uses the 
command
+ * element from bam transaction ce array and fills the same with 
required

+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, 
bool

read,
+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-17 Thread Abhishek Sahu

On 2017-07-10 19:48, Sricharan R wrote:

On 6/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
   will be used only by BAM DMA and it will form the DMA descriptors
   containing command elements.

2. Add the data descriptor preparation function which will be used
   only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
   descriptor formation function.

5. Enable the BAM in NAND_CTRL.



Should this patch be patch #8 and then add other support ?



 The original plan was to add other these function and
 finally enable the operation but it was generating the
 unused functions warnings that's why I need to club all
 these together in the last patch. anyway, I will check
 once again and will reorder if possible.


Regards,
 Sricharan



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

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

index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
 #defineFETCH_ID0xb
 #defineRESET_DEVICE0xd

+/* NAND_CTRL bits */
+#defineBAM_MODE_EN BIT(0)
 /*
  * the NAND controller performs reads/writes with ECC in 516 byte 
chunks.

  * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
  */
 #define NAND_ERASED_CW_SET (0x0008)

+/* Returns the dma address for reg read buffer */
+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
 #define QPIC_PER_CW_MAX_CMD_ELEMENTS   (32)
 #define QPIC_PER_CW_MAX_CMD_SGL(32)
 #define QPIC_PER_CW_MAX_DATA_SGL   (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
  * controller
  * @dev:   parent device
  * @base:  MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
  * @core_clk:  controller clock
  * @aon_clk:   another controller clock
  *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;

void __iomem *base;
+   phys_addr_t base_phys;
dma_addr_t base_dma;

struct clk *core_clk;
@@ -467,6 +479,29 @@ static void free_bam_transaction(struct
qcom_nand_controller *nandc)
return bam_txn;
 }

+/* Clears the BAM transaction indexes */
+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
 static inline struct qcom_nand_host *to_qcom_nand_host(struct 
nand_chip

*chip)
 {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct
qcom_nand_controller *nandc,
return 0;
 }

+/*
+ * Prepares the command descriptor for BAM DMA which will be used for
NAND
+ * register reads and writes. The command descriptor requires the 
command
+ * to be formed in command element type so this function uses the 
command
+ * element from bam transaction ce array and fills the same with 
required

+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, 
bool

read,
+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   if (read)
+

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-17 Thread Abhishek Sahu

On 2017-07-04 15:14, Archit Taneja wrote:

On 06/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
will be used only by BAM DMA and it will form the DMA descriptors
containing command elements.

2. Add the data descriptor preparation function which will be used
only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
descriptor formation function.

5. Enable the BAM in NAND_CTRL.

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

  1 file changed, 180 insertions(+), 10 deletions(-)

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

index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
  #define   FETCH_ID0xb
  #define   RESET_DEVICE0xd

+/* NAND_CTRL bits */
+#defineBAM_MODE_EN BIT(0)
  /*
   * the NAND controller performs reads/writes with ECC in 516 byte 
chunks.

   * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
   */
  #define NAND_ERASED_CW_SET(0x0008)

+/* Returns the dma address for reg read buffer */
+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
  #define QPIC_PER_CW_MAX_CMD_ELEMENTS  (32)
  #define QPIC_PER_CW_MAX_CMD_SGL   (32)
  #define QPIC_PER_CW_MAX_DATA_SGL  (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
   *controller
   * @dev:  parent device
   * @base: MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
   * @core_clk: controller clock
   * @aon_clk:  another controller clock
   *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;

void __iomem *base;
+   phys_addr_t base_phys;
dma_addr_t base_dma;

struct clk *core_clk;
@@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
qcom_nand_controller *nandc)

return bam_txn;
  }

+/* Clears the BAM transaction indexes */
+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
  static inline struct qcom_nand_host *to_qcom_nand_host(struct 
nand_chip *chip)

  {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
qcom_nand_controller *nandc,

return 0;
  }

+/*
+ * Prepares the command descriptor for BAM DMA which will be used for 
NAND
+ * register reads and writes. The command descriptor requires the 
command
+ * to be formed in command element type so this function uses the 
command
+ * element from bam transaction ce array and fills the same with 
required

+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, 
bool read,

+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   if (read)
+   bam_prep_ce(_ce_buffer[i],
+   NAND_REG_PHYS(nandc, reg_off + 4 * i),
+   BAM_READ_COMMAND,
+   REG_BUF_DMA_ADDR(nandc,
+(__le32 *)vaddr + i));
+   

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-17 Thread Abhishek Sahu

On 2017-07-04 15:14, Archit Taneja wrote:

On 06/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
will be used only by BAM DMA and it will form the DMA descriptors
containing command elements.

2. Add the data descriptor preparation function which will be used
only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
descriptor formation function.

5. Enable the BAM in NAND_CTRL.

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

  1 file changed, 180 insertions(+), 10 deletions(-)

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

index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
  #define   FETCH_ID0xb
  #define   RESET_DEVICE0xd

+/* NAND_CTRL bits */
+#defineBAM_MODE_EN BIT(0)
  /*
   * the NAND controller performs reads/writes with ECC in 516 byte 
chunks.

   * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
   */
  #define NAND_ERASED_CW_SET(0x0008)

+/* Returns the dma address for reg read buffer */
+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
  #define QPIC_PER_CW_MAX_CMD_ELEMENTS  (32)
  #define QPIC_PER_CW_MAX_CMD_SGL   (32)
  #define QPIC_PER_CW_MAX_DATA_SGL  (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
   *controller
   * @dev:  parent device
   * @base: MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
   * @core_clk: controller clock
   * @aon_clk:  another controller clock
   *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;

void __iomem *base;
+   phys_addr_t base_phys;
dma_addr_t base_dma;

struct clk *core_clk;
@@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
qcom_nand_controller *nandc)

return bam_txn;
  }

+/* Clears the BAM transaction indexes */
+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
  static inline struct qcom_nand_host *to_qcom_nand_host(struct 
nand_chip *chip)

  {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
qcom_nand_controller *nandc,

return 0;
  }

+/*
+ * Prepares the command descriptor for BAM DMA which will be used for 
NAND
+ * register reads and writes. The command descriptor requires the 
command
+ * to be formed in command element type so this function uses the 
command
+ * element from bam transaction ce array and fills the same with 
required

+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, 
bool read,

+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   if (read)
+   bam_prep_ce(_ce_buffer[i],
+   NAND_REG_PHYS(nandc, reg_off + 4 * i),
+   BAM_READ_COMMAND,
+   REG_BUF_DMA_ADDR(nandc,
+(__le32 *)vaddr + i));
+   else
+ 

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-10 Thread Sricharan R


On 6/29/2017 12:46 PM, Abhishek Sahu wrote:
> 1. Add the function for command descriptor preparation which
>will be used only by BAM DMA and it will form the DMA descriptors
>containing command elements.
> 
> 2. Add the data descriptor preparation function which will be used
>only by BAM DMA for forming the data SGL’s.
> 
> 3. Add clear BAM transaction and call it before every new request
> 
> 4. Check DMA mode for ADM or BAM and call the appropriate
>descriptor formation function.
> 
> 5. Enable the BAM in NAND_CTRL.
> 

Should this patch be patch #8 and then add other support ?

Regards,
 Sricharan


> Signed-off-by: Abhishek Sahu 
> ---
>  drivers/mtd/nand/qcom_nandc.c | 190 
> +++---
>  1 file changed, 180 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
> index 17766af..4c6e594 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -156,6 +156,8 @@
>  #define  FETCH_ID0xb
>  #define  RESET_DEVICE0xd
>  
> +/* NAND_CTRL bits */
> +#define  BAM_MODE_EN BIT(0)
>  /*
>   * the NAND controller performs reads/writes with ECC in 516 byte chunks.
>   * the driver calls the chunks 'step' or 'codeword' interchangeably
> @@ -190,6 +192,14 @@
>   */
>  #define NAND_ERASED_CW_SET   (0x0008)
>  
> +/* Returns the dma address for reg read buffer */
> +#define REG_BUF_DMA_ADDR(chip, vaddr) \
> + ((chip)->reg_read_buf_phys + \
> + ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
> +
> +/* Returns the NAND register physical address */
> +#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
> +
>  #define QPIC_PER_CW_MAX_CMD_ELEMENTS (32)
>  #define QPIC_PER_CW_MAX_CMD_SGL  (32)
>  #define QPIC_PER_CW_MAX_DATA_SGL (8)
> @@ -287,7 +297,8 @@ struct nandc_regs {
>   *   controller
>   * @dev: parent device
>   * @base:MMIO base
> - * @base_dma:physical base address of controller 
> registers
> + * @base_phys:   physical base address of controller 
> registers
> + * @base_dma:dma base address of controller registers
>   * @core_clk:controller clock
>   * @aon_clk: another controller clock
>   *
> @@ -323,6 +334,7 @@ struct qcom_nand_controller {
>   struct device *dev;
>  
>   void __iomem *base;
> + phys_addr_t base_phys;
>   dma_addr_t base_dma;
>  
>   struct clk *core_clk;
> @@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
> qcom_nand_controller *nandc)
>   return bam_txn;
>  }
>  
> +/* Clears the BAM transaction indexes */
> +static void clear_bam_transaction(struct qcom_nand_controller *nandc)
> +{
> + struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> + if (!nandc->dma_bam_enabled)
> + return;
> +
> + bam_txn->bam_ce_pos = 0;
> + bam_txn->bam_ce_start = 0;
> + bam_txn->cmd_sgl_pos = 0;
> + bam_txn->cmd_sgl_start = 0;
> + bam_txn->tx_sgl_pos = 0;
> + bam_txn->tx_sgl_start = 0;
> + bam_txn->rx_sgl_pos = 0;
> + bam_txn->rx_sgl_start = 0;
> +
> + sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
> +   QPIC_PER_CW_MAX_CMD_SGL);
> + sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
> +   QPIC_PER_CW_MAX_DATA_SGL);
> +}
> +
>  static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip 
> *chip)
>  {
>   return container_of(chip, struct qcom_nand_host, chip);
> @@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
> qcom_nand_controller *nandc,
>   return 0;
>  }
>  
> +/*
> + * Prepares the command descriptor for BAM DMA which will be used for NAND
> + * register reads and writes. The command descriptor requires the command
> + * to be formed in command element type so this function uses the command
> + * element from bam transaction ce array and fills the same with required
> + * data. A single SGL can contain multiple command elements so
> + * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
> + * after the current command element.
> + */
> +static int prep_dma_desc_command(struct qcom_nand_controller *nandc, bool 
> read,
> +  int reg_off, const void *vaddr,
> +  int size, unsigned int flags)
> +{
> + int bam_ce_size;
> + int i, ret;
> + struct bam_cmd_element *bam_ce_buffer;
> + struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> + bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
> +
> + /* fill the command desc */
> + for (i = 0; i < size; i++) {
> + if (read)
> + bam_prep_ce(_ce_buffer[i],
> + NAND_REG_PHYS(nandc, 

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-10 Thread Sricharan R


On 6/29/2017 12:46 PM, Abhishek Sahu wrote:
> 1. Add the function for command descriptor preparation which
>will be used only by BAM DMA and it will form the DMA descriptors
>containing command elements.
> 
> 2. Add the data descriptor preparation function which will be used
>only by BAM DMA for forming the data SGL’s.
> 
> 3. Add clear BAM transaction and call it before every new request
> 
> 4. Check DMA mode for ADM or BAM and call the appropriate
>descriptor formation function.
> 
> 5. Enable the BAM in NAND_CTRL.
> 

Should this patch be patch #8 and then add other support ?

Regards,
 Sricharan


> Signed-off-by: Abhishek Sahu 
> ---
>  drivers/mtd/nand/qcom_nandc.c | 190 
> +++---
>  1 file changed, 180 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
> index 17766af..4c6e594 100644
> --- a/drivers/mtd/nand/qcom_nandc.c
> +++ b/drivers/mtd/nand/qcom_nandc.c
> @@ -156,6 +156,8 @@
>  #define  FETCH_ID0xb
>  #define  RESET_DEVICE0xd
>  
> +/* NAND_CTRL bits */
> +#define  BAM_MODE_EN BIT(0)
>  /*
>   * the NAND controller performs reads/writes with ECC in 516 byte chunks.
>   * the driver calls the chunks 'step' or 'codeword' interchangeably
> @@ -190,6 +192,14 @@
>   */
>  #define NAND_ERASED_CW_SET   (0x0008)
>  
> +/* Returns the dma address for reg read buffer */
> +#define REG_BUF_DMA_ADDR(chip, vaddr) \
> + ((chip)->reg_read_buf_phys + \
> + ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
> +
> +/* Returns the NAND register physical address */
> +#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
> +
>  #define QPIC_PER_CW_MAX_CMD_ELEMENTS (32)
>  #define QPIC_PER_CW_MAX_CMD_SGL  (32)
>  #define QPIC_PER_CW_MAX_DATA_SGL (8)
> @@ -287,7 +297,8 @@ struct nandc_regs {
>   *   controller
>   * @dev: parent device
>   * @base:MMIO base
> - * @base_dma:physical base address of controller 
> registers
> + * @base_phys:   physical base address of controller 
> registers
> + * @base_dma:dma base address of controller registers
>   * @core_clk:controller clock
>   * @aon_clk: another controller clock
>   *
> @@ -323,6 +334,7 @@ struct qcom_nand_controller {
>   struct device *dev;
>  
>   void __iomem *base;
> + phys_addr_t base_phys;
>   dma_addr_t base_dma;
>  
>   struct clk *core_clk;
> @@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
> qcom_nand_controller *nandc)
>   return bam_txn;
>  }
>  
> +/* Clears the BAM transaction indexes */
> +static void clear_bam_transaction(struct qcom_nand_controller *nandc)
> +{
> + struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> + if (!nandc->dma_bam_enabled)
> + return;
> +
> + bam_txn->bam_ce_pos = 0;
> + bam_txn->bam_ce_start = 0;
> + bam_txn->cmd_sgl_pos = 0;
> + bam_txn->cmd_sgl_start = 0;
> + bam_txn->tx_sgl_pos = 0;
> + bam_txn->tx_sgl_start = 0;
> + bam_txn->rx_sgl_pos = 0;
> + bam_txn->rx_sgl_start = 0;
> +
> + sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
> +   QPIC_PER_CW_MAX_CMD_SGL);
> + sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
> +   QPIC_PER_CW_MAX_DATA_SGL);
> +}
> +
>  static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip 
> *chip)
>  {
>   return container_of(chip, struct qcom_nand_host, chip);
> @@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
> qcom_nand_controller *nandc,
>   return 0;
>  }
>  
> +/*
> + * Prepares the command descriptor for BAM DMA which will be used for NAND
> + * register reads and writes. The command descriptor requires the command
> + * to be formed in command element type so this function uses the command
> + * element from bam transaction ce array and fills the same with required
> + * data. A single SGL can contain multiple command elements so
> + * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
> + * after the current command element.
> + */
> +static int prep_dma_desc_command(struct qcom_nand_controller *nandc, bool 
> read,
> +  int reg_off, const void *vaddr,
> +  int size, unsigned int flags)
> +{
> + int bam_ce_size;
> + int i, ret;
> + struct bam_cmd_element *bam_ce_buffer;
> + struct bam_transaction *bam_txn = nandc->bam_txn;
> +
> + bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
> +
> + /* fill the command desc */
> + for (i = 0; i < size; i++) {
> + if (read)
> + bam_prep_ce(_ce_buffer[i],
> + NAND_REG_PHYS(nandc, reg_off + 4 * i),
> +  

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-04 Thread Archit Taneja



On 06/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
will be used only by BAM DMA and it will form the DMA descriptors
containing command elements.

2. Add the data descriptor preparation function which will be used
only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
descriptor formation function.

5. Enable the BAM in NAND_CTRL.

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

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
  #define   FETCH_ID0xb
  #define   RESET_DEVICE0xd
  
+/* NAND_CTRL bits */

+#defineBAM_MODE_EN BIT(0)
  /*
   * the NAND controller performs reads/writes with ECC in 516 byte chunks.
   * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
   */
  #define NAND_ERASED_CW_SET(0x0008)
  
+/* Returns the dma address for reg read buffer */

+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
  #define QPIC_PER_CW_MAX_CMD_ELEMENTS  (32)
  #define QPIC_PER_CW_MAX_CMD_SGL   (32)
  #define QPIC_PER_CW_MAX_DATA_SGL  (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
   *controller
   * @dev:  parent device
   * @base: MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
   * @core_clk: controller clock
   * @aon_clk:  another controller clock
   *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;
  
  	void __iomem *base;

+   phys_addr_t base_phys;
dma_addr_t base_dma;
  
  	struct clk *core_clk;

@@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
qcom_nand_controller *nandc)
return bam_txn;
  }
  
+/* Clears the BAM transaction indexes */

+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
  static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
  {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
qcom_nand_controller *nandc,
return 0;
  }
  
+/*

+ * Prepares the command descriptor for BAM DMA which will be used for NAND
+ * register reads and writes. The command descriptor requires the command
+ * to be formed in command element type so this function uses the command
+ * element from bam transaction ce array and fills the same with required
+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, bool read,
+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   if (read)
+   bam_prep_ce(_ce_buffer[i],
+   NAND_REG_PHYS(nandc, reg_off + 4 * i),
+   BAM_READ_COMMAND,
+   REG_BUF_DMA_ADDR(nandc,
+(__le32 *)vaddr + i));
+   else
+   

Re: [PATCH 10/14] qcom: mtd: nand: support for QPIC Page read/write

2017-07-04 Thread Archit Taneja



On 06/29/2017 12:46 PM, Abhishek Sahu wrote:

1. Add the function for command descriptor preparation which
will be used only by BAM DMA and it will form the DMA descriptors
containing command elements.

2. Add the data descriptor preparation function which will be used
only by BAM DMA for forming the data SGL’s.

3. Add clear BAM transaction and call it before every new request

4. Check DMA mode for ADM or BAM and call the appropriate
descriptor formation function.

5. Enable the BAM in NAND_CTRL.

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

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 17766af..4c6e594 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -156,6 +156,8 @@
  #define   FETCH_ID0xb
  #define   RESET_DEVICE0xd
  
+/* NAND_CTRL bits */

+#defineBAM_MODE_EN BIT(0)
  /*
   * the NAND controller performs reads/writes with ECC in 516 byte chunks.
   * the driver calls the chunks 'step' or 'codeword' interchangeably
@@ -190,6 +192,14 @@
   */
  #define NAND_ERASED_CW_SET(0x0008)
  
+/* Returns the dma address for reg read buffer */

+#define REG_BUF_DMA_ADDR(chip, vaddr) \
+   ((chip)->reg_read_buf_phys + \
+   ((uint8_t *)(vaddr) - (uint8_t *)(chip)->reg_read_buf))
+
+/* Returns the NAND register physical address */
+#define NAND_REG_PHYS(chip, offset) ((chip)->base_phys + (offset))
+
  #define QPIC_PER_CW_MAX_CMD_ELEMENTS  (32)
  #define QPIC_PER_CW_MAX_CMD_SGL   (32)
  #define QPIC_PER_CW_MAX_DATA_SGL  (8)
@@ -287,7 +297,8 @@ struct nandc_regs {
   *controller
   * @dev:  parent device
   * @base: MMIO base
- * @base_dma:  physical base address of controller registers
+ * @base_phys: physical base address of controller registers
+ * @base_dma:  dma base address of controller registers
   * @core_clk: controller clock
   * @aon_clk:  another controller clock
   *
@@ -323,6 +334,7 @@ struct qcom_nand_controller {
struct device *dev;
  
  	void __iomem *base;

+   phys_addr_t base_phys;
dma_addr_t base_dma;
  
  	struct clk *core_clk;

@@ -467,6 +479,29 @@ static void free_bam_transaction(struct 
qcom_nand_controller *nandc)
return bam_txn;
  }
  
+/* Clears the BAM transaction indexes */

+static void clear_bam_transaction(struct qcom_nand_controller *nandc)
+{
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   if (!nandc->dma_bam_enabled)
+   return;
+
+   bam_txn->bam_ce_pos = 0;
+   bam_txn->bam_ce_start = 0;
+   bam_txn->cmd_sgl_pos = 0;
+   bam_txn->cmd_sgl_start = 0;
+   bam_txn->tx_sgl_pos = 0;
+   bam_txn->tx_sgl_start = 0;
+   bam_txn->rx_sgl_pos = 0;
+   bam_txn->rx_sgl_start = 0;
+
+   sg_init_table(bam_txn->cmd_sgl, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_CMD_SGL);
+   sg_init_table(bam_txn->data_sg, nandc->max_cwperpage *
+ QPIC_PER_CW_MAX_DATA_SGL);
+}
+
  static inline struct qcom_nand_host *to_qcom_nand_host(struct nand_chip *chip)
  {
return container_of(chip, struct qcom_nand_host, chip);
@@ -682,6 +717,102 @@ static int prepare_bam_async_desc(struct 
qcom_nand_controller *nandc,
return 0;
  }
  
+/*

+ * Prepares the command descriptor for BAM DMA which will be used for NAND
+ * register reads and writes. The command descriptor requires the command
+ * to be formed in command element type so this function uses the command
+ * element from bam transaction ce array and fills the same with required
+ * data. A single SGL can contain multiple command elements so
+ * NAND_BAM_NEXT_SGL will be used for starting the separate SGL
+ * after the current command element.
+ */
+static int prep_dma_desc_command(struct qcom_nand_controller *nandc, bool read,
+int reg_off, const void *vaddr,
+int size, unsigned int flags)
+{
+   int bam_ce_size;
+   int i, ret;
+   struct bam_cmd_element *bam_ce_buffer;
+   struct bam_transaction *bam_txn = nandc->bam_txn;
+
+   bam_ce_buffer = _txn->bam_ce[bam_txn->bam_ce_pos];
+
+   /* fill the command desc */
+   for (i = 0; i < size; i++) {
+   if (read)
+   bam_prep_ce(_ce_buffer[i],
+   NAND_REG_PHYS(nandc, reg_off + 4 * i),
+   BAM_READ_COMMAND,
+   REG_BUF_DMA_ADDR(nandc,
+(__le32 *)vaddr + i));
+   else
+   bam_prep_ce_le32(_ce_buffer[i],