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 <absahu@xxxxxxxxxxxxxx>
---
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,