1. The BAM mode requires few registers configuration before each
   NAND page read and codeword read which is different from ADM
   so add the helper functions which will be called in BAM mode
   only.

2. The NAND page read handling of BAM is different from ADM so
   call the appropriate helper functions

Signed-off-by: Abhishek Sahu <abs...@codeaurora.org>
---
 drivers/mtd/nand/qcom_nandc.c | 63 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 62 insertions(+), 1 deletion(-)

diff --git a/drivers/mtd/nand/qcom_nandc.c b/drivers/mtd/nand/qcom_nandc.c
index 8e7dc9e..17766af 100644
--- a/drivers/mtd/nand/qcom_nandc.c
+++ b/drivers/mtd/nand/qcom_nandc.c
@@ -870,6 +870,35 @@ static void config_cw_read(struct qcom_nand_controller 
*nandc)
 }
 
 /*
+ * Helpers to prepare DMA descriptors for configuring registers
+ * before reading a NAND page with BAM.
+ */
+static void config_bam_page_read(struct qcom_nand_controller *nandc)
+{
+       write_reg_dma(nandc, NAND_FLASH_CMD, 3, 0);
+       write_reg_dma(nandc, NAND_DEV0_CFG0, 3, 0);
+       write_reg_dma(nandc, NAND_EBI2_ECC_BUF_CFG, 1, 0);
+       write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1, 0);
+       write_reg_dma(nandc, NAND_ERASED_CW_DETECT_CFG, 1,
+                     NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL);
+}
+
+/*
+ * Helpers to prepare DMA descriptors for configuring registers
+ * before reading each codeword in NAND page with BAM.
+ */
+static void config_bam_cw_read(struct qcom_nand_controller *nandc)
+{
+       write_reg_dma(nandc, NAND_READ_LOCATION_0, 2, 0);
+       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, 0);
+       read_reg_dma(nandc, NAND_ERASED_CW_DETECT_STATUS, 1,
+                    NAND_BAM_NEXT_SGL);
+}
+
+/*
  * helpers to prepare dma descriptors used to configure registers needed for
  * writing a codeword/step in a page
  */
@@ -1398,6 +1427,9 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 
*data_buf,
        struct nand_ecc_ctrl *ecc = &chip->ecc;
        int i, ret;
 
+       if (nandc->dma_bam_enabled)
+               config_bam_page_read(nandc);
+
        /* queue cmd descs for each codeword */
        for (i = 0; i < ecc->steps; i++) {
                int data_size, oob_size;
@@ -1411,7 +1443,36 @@ static int read_page_ecc(struct qcom_nand_host *host, u8 
*data_buf,
                        oob_size = host->ecc_bytes_hw + host->spare_bytes;
                }
 
-               config_cw_read(nandc);
+               if (nandc->dma_bam_enabled) {
+                       if (data_buf && oob_buf) {
+                               nandc_set_reg(nandc, NAND_READ_LOCATION_0,
+                                             (0 << READ_LOCATION_OFFSET) |
+                                             (data_size <<
+                                             READ_LOCATION_SIZE) |
+                                             (0 << READ_LOCATION_LAST));
+                               nandc_set_reg(nandc, NAND_READ_LOCATION_1,
+                                             (data_size <<
+                                             READ_LOCATION_OFFSET) |
+                                             (oob_size << READ_LOCATION_SIZE) |
+                                             (1 << READ_LOCATION_LAST));
+                       } else if (data_buf) {
+                               nandc_set_reg(nandc, NAND_READ_LOCATION_0,
+                                             (0 << READ_LOCATION_OFFSET) |
+                                             (data_size <<
+                                             READ_LOCATION_SIZE) |
+                                             (1 << READ_LOCATION_LAST));
+                       } else {
+                               nandc_set_reg(nandc, NAND_READ_LOCATION_0,
+                                             (data_size <<
+                                             READ_LOCATION_OFFSET) |
+                                             (oob_size << READ_LOCATION_SIZE) |
+                                             (1 << READ_LOCATION_LAST));
+                       }
+
+                       config_bam_cw_read(nandc);
+               } else {
+                       config_cw_read(nandc);
+               }
 
                if (data_buf)
                        read_data_dma(nandc, FLASH_BUF_ACC, data_buf,
-- 
QUALCOMM INDIA, on behalf of Qualcomm Innovation Center, Inc. is a member of 
Code Aurora Forum, hosted by The Linux Foundation

Reply via email to